[PATCH] D25913: [InstCombine] Fold nuw left-shifts in `ugt`/`ule` comparisons.

bryant via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 25 14:10:14 PDT 2016


bryant updated this revision to Diff 75793.
bryant added a comment.

Merge uge/ule with ugt/ult, respectively.


Repository:
  rL LLVM

https://reviews.llvm.org/D25913

Files:
  lib/Transforms/InstCombine/InstCombineCompares.cpp
  test/Transforms/InstCombine/icmp-shl-zext-simplify.ll


Index: test/Transforms/InstCombine/icmp-shl-zext-simplify.ll
===================================================================
--- test/Transforms/InstCombine/icmp-shl-zext-simplify.ll
+++ test/Transforms/InstCombine/icmp-shl-zext-simplify.ll
@@ -3,8 +3,7 @@
 
 define i1 @icmp_ugt_32(i64) {
 ; CHECK-LABEL: @icmp_ugt_32(
-; CHECK-NEXT:    [[C:%.*]] = shl nuw i64 %0, 32
-; CHECK-NEXT:    [[D:%.*]] = icmp ugt i64 [[C]], 4294967295
+; CHECK-NEXT:    [[D:%.*]] = icmp ne i64 %0, 0
 ; CHECK-NEXT:    ret i1 [[D]]
 ;
   %c = shl nuw i64 %0, 32
@@ -14,8 +13,7 @@
 
 define i1 @icmp_ule_64(i128) {
 ; CHECK-LABEL: @icmp_ule_64(
-; CHECK-NEXT:    [[C:%.*]] = shl nuw i128 %0, 64
-; CHECK-NEXT:    [[D:%.*]] = icmp ult i128 [[C]], 18446744073709551616
+; CHECK-NEXT:    [[D:%.*]] = icmp eq i128 %0, 0
 ; CHECK-NEXT:    ret i1 [[D]]
 ;
   %c = shl nuw i128 %0, 64
@@ -25,8 +23,7 @@
 
 define i1 @icmp_ugt_16(i64) {
 ; CHECK-LABEL: @icmp_ugt_16(
-; CHECK-NEXT:    [[C:%.*]] = shl nuw i64 %0, 16
-; CHECK-NEXT:    [[D:%.*]] = icmp ugt i64 [[C]], 1048575
+; CHECK-NEXT:    [[D:%.*]] = icmp ugt i64 %0, 15
 ; CHECK-NEXT:    ret i1 [[D]]
 ;
   %c = shl nuw i64 %0, 16
@@ -36,8 +33,7 @@
 
 define <2 x i1> @icmp_ule_16x2(<2 x i64>) {
 ; CHECK-LABEL: @icmp_ule_16x2(
-; CHECK-NEXT:    [[C:%.*]] = shl nuw <2 x i64> %0, <i64 16, i64 16>
-; CHECK-NEXT:    [[D:%.*]] = icmp ult <2 x i64> [[C]], <i64 65536, i64 65536>
+; CHECK-NEXT:    [[D:%.*]] = icmp eq <2 x i64> %0, zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[D]]
 ;
   %c = shl nuw <2 x i64> %0, <i64 16, i64 16>
@@ -47,8 +43,7 @@
 
 define i1 @icmp_ult_8(i64) {
 ; CHECK-LABEL: @icmp_ult_8(
-; CHECK-NEXT:    [[C:%.*]] = shl nuw i64 %0, 8
-; CHECK-NEXT:    [[D:%.*]] = icmp ult i64 [[C]], 4095
+; CHECK-NEXT:    [[D:%.*]] = icmp ult i64 %0, 16
 ; CHECK-NEXT:    ret i1 [[D]]
 ;
   %c = shl nuw i64 %0, 8
@@ -58,8 +53,7 @@
 
 define <2 x i1> @icmp_uge_8x2(<2 x i16>) {
 ; CHECK-LABEL: @icmp_uge_8x2(
-; CHECK-NEXT:    [[C:%.*]] = shl nuw <2 x i16> %0, <i16 8, i16 8>
-; CHECK-NEXT:    [[D:%.*]] = icmp ugt <2 x i16> [[C]], <i16 4094, i16 4094>
+; CHECK-NEXT:    [[D:%.*]] = icmp ugt <2 x i16> %0, <i16 15, i16 15>
 ; CHECK-NEXT:    ret <2 x i1> [[D]]
 ;
   %c = shl nuw <2 x i16> %0, <i16 8, i16 8>
@@ -69,8 +63,7 @@
 
 define <2 x i1> @icmp_ugt_16x2(<2 x i32>) {
 ; CHECK-LABEL: @icmp_ugt_16x2(
-; CHECK-NEXT:    [[C:%.*]] = shl nuw <2 x i32> %0, <i32 16, i32 16>
-; CHECK-NEXT:    [[D:%.*]] = icmp ugt <2 x i32> [[C]], <i32 1048575, i32 1048575>
+; CHECK-NEXT:    [[D:%.*]] = icmp ugt <2 x i32> %0, <i32 15, i32 15>
 ; CHECK-NEXT:    ret <2 x i1> [[D]]
 ;
   %c = shl nuw <2 x i32> %0, <i32 16, i32 16>
Index: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1950,6 +1950,21 @@
                         And, Constant::getNullValue(And->getType()));
   }
 
+  // When the shift is nuw and pred is >u (for all C) or <u (for non-zero C),
+  // comparison only really happens in the pre-shifted bits. This also holds for
+  // <=u and >u, but the latter two are canonicalized into the former.
+  if (Shl->hasNoUnsignedWrap()) {
+    Type *CTy = IntegerType::get(Cmp.getContext(), C->getBitWidth());
+    if (X->getType()->isVectorTy())
+      CTy = VectorType::get(CTy, X->getType()->getVectorNumElements());
+
+    if (C->ugt(0) && Pred == ICmpInst::ICMP_ULT)
+      return new ICmpInst(ICmpInst::ICMP_ULE, X,
+                          ConstantInt::get(CTy, (*C - 1).lshr(*ShiftAmt)));
+    else if (Pred == ICmpInst::ICMP_UGT)
+      return new ICmpInst(Pred, X, ConstantInt::get(CTy, C->lshr(*ShiftAmt)));
+  }
+
   // Transform (icmp pred iM (shl iM %v, N), C)
   // -> (icmp pred i(M-N) (trunc %v iM to i(M-N)), (trunc (C>>N))
   // Transform the shl to a trunc if (trunc (C>>N)) has no loss and M-N.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25913.75793.patch
Type: text/x-patch
Size: 3933 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161025/31e9dc1a/attachment.bin>


More information about the llvm-commits mailing list