summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-04-27 15:38:30 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-04-27 15:38:30 +0000
commitba8e6140c330f8304eef8bdb209f2fc4c6041475 (patch)
tree7e920f3c227df60dc0ec76b08b4396dd857a94df
parentf761e7d6ca9a6702068dd8889f13aaa6c8ae6af4 (diff)
downloadllvm-ba8e6140c330f8304eef8bdb209f2fc4c6041475.tar.gz
Merging r296645: (PR32253)
Included an updated testcase ------------------------------------------------------------------------ [Hexagon] Fix lowering of formal arguments of type i1 On Hexagon, values of type i1 are passed in registers of type i32, even though i1 is not a legal value for these registers. This is a special case and needs special handling to maintain consistency of the lowering information. This fixes PR32089. ------------------------------------------------------------------------ llvm-svn: 301550
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelLowering.cpp23
-rw-r--r--llvm/test/CodeGen/Hexagon/isel-i1arg-crash.ll6
-rw-r--r--llvm/test/MC/Hexagon/inst_select.ll4
3 files changed, 28 insertions, 5 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index e87e1e6a7e0f..be70e1464e55 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -256,7 +256,9 @@ static bool CC_Hexagon (unsigned ValNo, MVT ValVT, MVT LocVT,
return false;
}
- if (LocVT == MVT::i1 || LocVT == MVT::i8 || LocVT == MVT::i16) {
+ if (LocVT == MVT::i1) {
+ LocVT = MVT::i32;
+ } else if (LocVT == MVT::i8 || LocVT == MVT::i16) {
LocVT = MVT::i32;
ValVT = MVT::i32;
if (ArgFlags.isSExt())
@@ -1140,10 +1142,25 @@ SDValue HexagonTargetLowering::LowerFormalArguments(
EVT RegVT = VA.getLocVT();
if (RegVT == MVT::i8 || RegVT == MVT::i16 ||
RegVT == MVT::i32 || RegVT == MVT::f32) {
- unsigned VReg =
+ unsigned VReg =
RegInfo.createVirtualRegister(&Hexagon::IntRegsRegClass);
RegInfo.addLiveIn(VA.getLocReg(), VReg);
- InVals.push_back(DAG.getCopyFromReg(Chain, dl, VReg, RegVT));
+ SDValue Copy = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
+ // Treat values of type MVT::i1 specially: they are passed in
+ // registers of type i32, but they need to remain as values of
+ // type i1 for consistency of the argument lowering.
+ if (VA.getValVT() == MVT::i1) {
+ // Generate a copy into a predicate register and use the value
+ // of the register as the "InVal".
+ unsigned PReg =
+ RegInfo.createVirtualRegister(&Hexagon::PredRegsRegClass);
+ SDNode *T = DAG.getMachineNode(Hexagon::C2_tfrrp, dl, MVT::i1,
+ Copy.getValue(0));
+ Copy = DAG.getCopyToReg(Copy.getValue(1), dl, PReg, SDValue(T, 0));
+ Copy = DAG.getCopyFromReg(Copy, dl, PReg, MVT::i1);
+ }
+ InVals.push_back(Copy);
+ Chain = Copy.getValue(1);
} else if (RegVT == MVT::i64 || RegVT == MVT::f64) {
unsigned VReg =
RegInfo.createVirtualRegister(&Hexagon::DoubleRegsRegClass);
diff --git a/llvm/test/CodeGen/Hexagon/isel-i1arg-crash.ll b/llvm/test/CodeGen/Hexagon/isel-i1arg-crash.ll
new file mode 100644
index 000000000000..7e8bd9e93b27
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/isel-i1arg-crash.ll
@@ -0,0 +1,6 @@
+; RUN: llc -march=hexagon -debug-only=isel < %s
+; REQUIRES: asserts
+
+define void @g(i1 %cond) {
+ ret void
+}
diff --git a/llvm/test/MC/Hexagon/inst_select.ll b/llvm/test/MC/Hexagon/inst_select.ll
index 9d12c1de73fe..a730419c854a 100644
--- a/llvm/test/MC/Hexagon/inst_select.ll
+++ b/llvm/test/MC/Hexagon/inst_select.ll
@@ -7,7 +7,7 @@ define i32 @foo (i1 %a, i32 %b, i32 %c)
ret i32 %1
}
-; CHECK: 00 40 00 85 85004000
+; CHECK: 00 40 40 85 85404000
; CHECK: 00 40 9f 52 529f4000
; CHECK: 00 60 01 74 74016000
-; CHECK: 00 e0 82 74 7482e000 \ No newline at end of file
+; CHECK: 00 e0 82 74 7482e000