OSDN Git Service

InstCombine: variations on 0xffffffff - x >= 4
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 9 Jul 2013 09:20:58 +0000 (09:20 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 9 Jul 2013 09:20:58 +0000 (09:20 +0000)
The following transforms are valid if -C is a power of 2:
(icmp ugt (xor X, C), ~C) -> (icmp ult X, C)
(icmp ult (xor X, C), -C) -> (icmp uge X, C)

These are nice, they get rid of the xor.

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

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

index e9f3458..8ac0e3f 100644 (file)
@@ -1126,6 +1126,18 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
                               Builder->getInt(RHSV ^ NotSignBit));
         }
       }
+
+      // (icmp ugt (xor X, C), ~C) -> (icmp ult X, C)
+      //   iff -C is a power of 2
+      if (ICI.getPredicate() == ICmpInst::ICMP_UGT &&
+          XorCST->getValue() == ~RHSV && (RHSV + 1).isPowerOf2())
+        return new ICmpInst(ICmpInst::ICMP_ULT, LHSI->getOperand(0), XorCST);
+
+      // (icmp ult (xor X, C), -C) -> (icmp uge X, C)
+      //   iff -C is a power of 2
+      if (ICI.getPredicate() == ICmpInst::ICMP_ULT &&
+          XorCST->getValue() == -RHSV && RHSV.isPowerOf2())
+        return new ICmpInst(ICmpInst::ICMP_UGE, LHSI->getOperand(0), XorCST);
     }
     break;
   case Instruction::And:         // (icmp pred (and X, AndCST), RHS)
index 5dccde2..c541a69 100644 (file)
@@ -1181,3 +1181,21 @@ define i1 @icmp_and_X_-16_ne-16(i32 %X) {
   %cmp = icmp ne i32 %and, -16
   ret i1 %cmp
 }
+
+; CHECK: @icmp_sub_-1_X_ult_4
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ugt i32 %X, -5
+; CHECK-NEXT: ret i1 [[CMP]]
+define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
+  %sub = sub i32 -1, %X
+  %cmp = icmp ult i32 %sub, 4
+  ret i1 %cmp
+}
+
+; CHECK: @icmp_sub_-1_X_uge_4
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %X, -4
+; CHECK-NEXT: ret i1 [[CMP]]
+define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
+  %sub = sub i32 -1, %X
+  %cmp = icmp uge i32 %sub, 4
+  ret i1 %cmp
+}