InstCombine: Fold X-C1 <u 2 -> (X & -2) == C1
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 8 Jul 2013 11:53:08 +0000 (11:53 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 8 Jul 2013 11:53:08 +0000 (11:53 +0000)
Back in r179493 we determined that two transforms collided with each
other.  The fix back then was to reorder the transforms so that the
preferred transform would give it a try and then we would try the
secondary transform.  However, it was noted that the best approach would
canonicalize one transform into the other, removing the collision and
allowing us to optimize IR given to us in that form.

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

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

index 0f1576050ff3a7ce423d1282bcc586cd5582e565..f4734461a62dc4b78768afcac72cd85e7271c79f 100644 (file)
@@ -1539,6 +1539,14 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
                               Builder->getInt(CR.getLower()));
         }
       }
+
+      // X-C1 <u 2 -> (X & -2) == C1
+      //   iff C1 & 1 == 0
+      if (ICI.getPredicate() == ICmpInst::ICMP_ULT && LHSI->hasOneUse() &&
+          LHSV[0] == 0 && RHSV == 2)
+        return new ICmpInst(ICmpInst::ICMP_EQ,
+                            Builder->CreateAnd(LHSI->getOperand(0), -RHSV),
+                            ConstantExpr::getNeg(LHSC));
     }
     break;
   }
index 929688195fe5328cf9b2604be264f8696016018b..cf8305df2a9c8fadb7112e370cea61c73b5d2f51 100644 (file)
@@ -1113,3 +1113,13 @@ define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
   %3 = or i1 %1, %2
   ret i1 %3
 }
+
+; CHECK: @icmp_add_ult_2
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %X, -2
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp eq i32 [[AND]], 14
+; CHECK-NEXT: ret i1 [[CMP]]
+define i1 @icmp_add_ult_2(i32 %X) {
+  %add = add i32 %X, -14
+  %cmp = icmp ult i32 %add, 2
+  ret i1 %cmp
+}