summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmara Emerson <aemerson@apple.com>2019-09-24 00:09:23 +0000
committerAmara Emerson <aemerson@apple.com>2019-09-24 00:09:23 +0000
commitadec1209e627aecb6634edb46e99e741d95ba95f (patch)
treecc973e577126ad9eb5adbcef66a80c59dce1c151
parent837273711e0bbd778573e51171d00e6a4f1174a5 (diff)
downloadbcm5719-llvm-adec1209e627aecb6634edb46e99e741d95ba95f.tar.gz
bcm5719-llvm-adec1209e627aecb6634edb46e99e741d95ba95f.zip
[GlobalISel][IRTranslator] Fix switch table lowering to use signed LE not unsigned.
We were miscompiling switch value comparisons with the wrong signedness, which shows up when we have things like switch case values with i1 types, which end up being legalized incorrectly. Fixes PR43383 llvm-svn: 372675
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp8
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll42
2 files changed, 46 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 1e34739cb03..2ce05ec3968 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -589,8 +589,8 @@ void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
Register CondRHS = getOrCreateVReg(*CB.CmpRHS);
Cond = MIB.buildICmp(CB.PredInfo.Pred, i1Ty, CondLHS, CondRHS).getReg(0);
} else {
- assert(CB.PredInfo.Pred == CmpInst::ICMP_ULE &&
- "Can only handle ULE ranges");
+ assert(CB.PredInfo.Pred == CmpInst::ICMP_SLE &&
+ "Can only handle SLE ranges");
const APInt& Low = cast<ConstantInt>(CB.CmpLHS)->getValue();
const APInt& High = cast<ConstantInt>(CB.CmpRHS)->getValue();
@@ -599,7 +599,7 @@ void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
if (cast<ConstantInt>(CB.CmpLHS)->isMinValue(true)) {
Register CondRHS = getOrCreateVReg(*CB.CmpRHS);
Cond =
- MIB.buildICmp(CmpInst::ICMP_ULE, i1Ty, CmpOpReg, CondRHS).getReg(0);
+ MIB.buildICmp(CmpInst::ICMP_SLE, i1Ty, CmpOpReg, CondRHS).getReg(0);
} else {
const LLT &CmpTy = MRI->getType(CmpOpReg);
auto Sub = MIB.buildSub({CmpTy}, CmpOpReg, CondLHS);
@@ -729,7 +729,7 @@ bool IRTranslator::lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I,
MHS = nullptr;
} else {
// Check I->Low <= Cond <= I->High.
- Pred = CmpInst::ICMP_ULE;
+ Pred = CmpInst::ICMP_SLE;
LHS = I->Low;
MHS = Cond;
RHS = I->High;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll
index f5075216352..969cacb89d1 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll
@@ -1412,3 +1412,45 @@ bb4: ; preds = %bb1
declare i64* @ham(i32)
+define internal void @bar() unnamed_addr #1 {
+ ; CHECK-LABEL: name: bar
+ ; CHECK: bb.1 (%ir-block.0):
+ unreachable
+}
+
+define i1 @i1_value_cmp_is_signed(i1) {
+ ; CHECK-LABEL: name: i1_value_cmp_is_signed
+ ; CHECK: bb.1.Entry:
+ ; CHECK: successors: %bb.3(0x40000000), %bb.2(0x40000000)
+ ; CHECK: liveins: $w0
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[COPY]](s32)
+ ; CHECK: [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; CHECK: [[C1:%[0-9]+]]:_(s1) = G_CONSTANT i1 false
+ ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(sle), [[TRUNC]](s1), [[C1]]
+ ; CHECK: G_BRCOND [[ICMP]](s1), %bb.3
+ ; CHECK: G_BR %bb.2
+ ; CHECK: bb.2.BadValue:
+ ; CHECK: successors:
+ ; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK: BL @bar, csr_aarch64_aapcs, implicit-def $lr, implicit $sp
+ ; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK: bb.3.OkValue:
+ ; CHECK: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[TRUNC]](s1)
+ ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
+ ; CHECK: $w0 = COPY [[ANYEXT]](s32)
+ ; CHECK: RET_ReallyLR implicit $w0
+Entry:
+ switch i1 %0, label %BadValue [
+ i1 false, label %OkValue
+ i1 true, label %OkValue
+ ]
+
+BadValue:
+ call fastcc void @bar()
+ unreachable
+
+OkValue:
+ ret i1 %0
+}
+
OpenPOWER on IntegriCloud