[llvm] r372675 - [GlobalISel][IRTranslator] Fix switch table lowering to use signed LE not unsigned.
Amara Emerson via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 23 17:09:23 PDT 2019
Author: aemerson
Date: Mon Sep 23 17:09:23 2019
New Revision: 372675
URL: http://llvm.org/viewvc/llvm-project?rev=372675&view=rev
Log:
[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
Modified:
llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll
Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=372675&r1=372674&r2=372675&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Mon Sep 23 17:09:23 2019
@@ -589,8 +589,8 @@ void IRTranslator::emitSwitchCase(Switch
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(Switch
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::lowerSwitchRangeWorkI
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;
Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll?rev=372675&r1=372674&r2=372675&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll Mon Sep 23 17:09:23 2019
@@ -1412,3 +1412,45 @@ bb4:
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
+}
+
More information about the llvm-commits
mailing list