InstCombine: Don't combine constants on unsigned icmps
authorReid Kleckner <reid@kleckner.net>
Thu, 27 Mar 2014 17:49:27 +0000 (17:49 +0000)
committerReid Kleckner <reid@kleckner.net>
Thu, 27 Mar 2014 17:49:27 +0000 (17:49 +0000)
Fixes a miscompile introduced in r204912.  It would miscompile code like
(unsigned)(a + -49) <= 5U.  The transform would turn this into
(unsigned)a < 55U, which would return true for values in [0, 49], when
it should not.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204948 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstCombine/icmp.ll

index 9bf3818954204713cd9794378de5a74c4b499a00..fea0d0245c817c1151e8f8ef5a1d03422eb3c540 100644 (file)
@@ -3010,7 +3010,8 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
       return FoldICmpAddOpCst(I, X, Cst, I.getSwappedPredicate());
 
     ConstantInt *Cst2;
-    if (match(Op1, m_ConstantInt(Cst)) &&
+    if (I.isSigned() &&
+        match(Op1, m_ConstantInt(Cst)) &&
         match(Op0, m_Add(m_Value(X), m_ConstantInt(Cst2))) &&
         cast<BinaryOperator>(Op0)->hasNoSignedWrap()) {
       // icmp X+Cst2, Cst --> icmp X, Cst-Cst2
index 2e3ff24f6ba2cfaf721f3ea6b0407af75f6ee2be..63fefc0877664cd8d6fd5cac0d8f0dbb6ebfd19f 100644 (file)
@@ -1409,3 +1409,13 @@ entry:
   %conv = zext i1 %cmp to i32
   ret i32 %conv
 }
+
+; CHECK-LABEL: icmp_add_const_ult
+; CHECK: %cmp = icmp ult i32 %add, 6
+define i32 @icmp_add_const_ult(i32 %a) #0 {
+entry:
+  %add = add nsw i32 %a, -49
+  %cmp = icmp ult i32 %add, 6
+  %conv = zext i1 %cmp to i32
+  ret i32 %conv
+}