[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