Skip to content

Commit 0acab01

Browse files
aemersontstellar
authored andcommitted
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 ------------------------------------------------------------------------
1 parent 4e858e4 commit 0acab01

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -588,8 +588,8 @@ void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
588588
Register CondRHS = getOrCreateVReg(*CB.CmpRHS);
589589
Cond = MIB.buildICmp(CB.PredInfo.Pred, i1Ty, CondLHS, CondRHS).getReg(0);
590590
} else {
591-
assert(CB.PredInfo.Pred == CmpInst::ICMP_ULE &&
592-
"Can only handle ULE ranges");
591+
assert(CB.PredInfo.Pred == CmpInst::ICMP_SLE &&
592+
"Can only handle SLE ranges");
593593

594594
const APInt& Low = cast<ConstantInt>(CB.CmpLHS)->getValue();
595595
const APInt& High = cast<ConstantInt>(CB.CmpRHS)->getValue();
@@ -598,7 +598,7 @@ void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
598598
if (cast<ConstantInt>(CB.CmpLHS)->isMinValue(true)) {
599599
Register CondRHS = getOrCreateVReg(*CB.CmpRHS);
600600
Cond =
601-
MIB.buildICmp(CmpInst::ICMP_ULE, i1Ty, CmpOpReg, CondRHS).getReg(0);
601+
MIB.buildICmp(CmpInst::ICMP_SLE, i1Ty, CmpOpReg, CondRHS).getReg(0);
602602
} else {
603603
const LLT &CmpTy = MRI->getType(CmpOpReg);
604604
auto Sub = MIB.buildSub({CmpTy}, CmpOpReg, CondLHS);
@@ -728,7 +728,7 @@ bool IRTranslator::lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I,
728728
MHS = nullptr;
729729
} else {
730730
// Check I->Low <= Cond <= I->High.
731-
Pred = CmpInst::ICMP_ULE;
731+
Pred = CmpInst::ICMP_SLE;
732732
LHS = I->Low;
733733
MHS = Cond;
734734
RHS = I->High;

llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-switch.ll

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,3 +1412,45 @@ bb4: ; preds = %bb1
14121412

14131413
declare i64* @ham(i32)
14141414

1415+
define internal void @bar() unnamed_addr #1 {
1416+
; CHECK-LABEL: name: bar
1417+
; CHECK: bb.1 (%ir-block.0):
1418+
unreachable
1419+
}
1420+
1421+
define i1 @i1_value_cmp_is_signed(i1) {
1422+
; CHECK-LABEL: name: i1_value_cmp_is_signed
1423+
; CHECK: bb.1.Entry:
1424+
; CHECK: successors: %bb.3(0x40000000), %bb.2(0x40000000)
1425+
; CHECK: liveins: $w0
1426+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
1427+
; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[COPY]](s32)
1428+
; CHECK: [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1429+
; CHECK: [[C1:%[0-9]+]]:_(s1) = G_CONSTANT i1 false
1430+
; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(sle), [[TRUNC]](s1), [[C1]]
1431+
; CHECK: G_BRCOND [[ICMP]](s1), %bb.3
1432+
; CHECK: G_BR %bb.2
1433+
; CHECK: bb.2.BadValue:
1434+
; CHECK: successors:
1435+
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
1436+
; CHECK: BL @bar, csr_aarch64_aapcs, implicit-def $lr, implicit $sp
1437+
; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
1438+
; CHECK: bb.3.OkValue:
1439+
; CHECK: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[TRUNC]](s1)
1440+
; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
1441+
; CHECK: $w0 = COPY [[ANYEXT]](s32)
1442+
; CHECK: RET_ReallyLR implicit $w0
1443+
Entry:
1444+
switch i1 %0, label %BadValue [
1445+
i1 false, label %OkValue
1446+
i1 true, label %OkValue
1447+
]
1448+
1449+
BadValue:
1450+
call fastcc void @bar()
1451+
unreachable
1452+
1453+
OkValue:
1454+
ret i1 %0
1455+
}
1456+

0 commit comments

Comments
 (0)