aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmara Emerson <aemerson@apple.com>2019-09-24 00:09:23 +0000
committerTom Stellard <tstellar@redhat.com>2019-11-12 13:31:34 -0800
commit0acab01d54de35ea1fdf790215e9caf4e139ac80 (patch)
tree941955a48a29e62e5077e61bcc08b187b1282418
parent4e858e4ac00b59f064da4e1f7e276916e7d296aa (diff)
downloadllvm-0acab01d54de35ea1fdf790215e9caf4e139ac80.zip
llvm-0acab01d54de35ea1fdf790215e9caf4e139ac80.tar.gz
llvm-0acab01d54de35ea1fdf790215e9caf4e139ac80.tar.bz2
Merging r372675:
------------------------------------------------------------------------ r372675 | aemerson | 2019-09-23 17:09:23 -0700 (Mon, 23 Sep 2019) | 7 lines [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 ------------------------------------------------------------------------
-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 6e99bdb..16ac453 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -588,8 +588,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();
@@ -598,7 +598,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);
@@ -728,7 +728,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 f507521..969cacb 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
+}
+