[llvm] r341353 - [InstCombine] Fold icmp ugt/ult (add nuw X, C2), C --> icmp ugt/ult X, (C - C2)

Nicola Zaghen via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 4 03:29:48 PDT 2018


Author: nzaghen
Date: Tue Sep  4 03:29:48 2018
New Revision: 341353

URL: http://llvm.org/viewvc/llvm-project?rev=341353&view=rev
Log:
[InstCombine] Fold icmp ugt/ult (add nuw X, C2), C --> icmp ugt/ult X, (C - C2)

Support for sgt/slt was added in rL294898, this adds the same cases also for unsigned compares.

This is the Alive proof: https://rise4fun.com/Alive/nyY

Differential Revision: https://reviews.llvm.org/D50972


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/trunk/test/Analysis/ValueTracking/non-negative-phi-bits.ll
    llvm/trunk/test/Transforms/InstCombine/icmp-add.ll
    llvm/trunk/test/Transforms/LoopVectorize/X86/masked_load_store.ll
    llvm/trunk/test/Transforms/LoopVectorize/if-conversion-nest.ll
    llvm/trunk/test/Transforms/LoopVectorize/runtime-check.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=341353&r1=341352&r2=341353&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Tue Sep  4 03:29:48 2018
@@ -2338,12 +2338,15 @@ Instruction *InstCombiner::foldICmpAddCo
   CmpInst::Predicate Pred = Cmp.getPredicate();
 
   // If the add does not wrap, we can always adjust the compare by subtracting
-  // the constants. Equality comparisons are handled elsewhere. SGE/SLE are
-  // canonicalized to SGT/SLT.
-  if (Add->hasNoSignedWrap() &&
-      (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLT)) {
+  // the constants. Equality comparisons are handled elsewhere. SGE/SLE/UGE/ULE
+  // are canonicalized to SGT/SLT/UGT/ULT.
+  if ((Add->hasNoSignedWrap() &&
+       (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLT)) ||
+      (Add->hasNoUnsignedWrap() &&
+       (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULT))) {
     bool Overflow;
-    APInt NewC = C.ssub_ov(*C2, Overflow);
+    APInt NewC =
+        Cmp.isSigned() ? C.ssub_ov(*C2, Overflow) : C.usub_ov(*C2, Overflow);
     // If there is overflow, the result must be true or false.
     // TODO: Can we assert there is no overflow because InstSimplify always
     // handles those cases?

Modified: llvm/trunk/test/Analysis/ValueTracking/non-negative-phi-bits.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ValueTracking/non-negative-phi-bits.ll?rev=341353&r1=341352&r2=341353&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ValueTracking/non-negative-phi-bits.ll (original)
+++ llvm/trunk/test/Analysis/ValueTracking/non-negative-phi-bits.ll Tue Sep  4 03:29:48 2018
@@ -8,7 +8,7 @@ define void @test() #0 {
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
-; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], 40
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ult i64 [[INDVARS_IV]], 39
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
 ; CHECK:       for.end:
 ; CHECK-NEXT:    ret void

Modified: llvm/trunk/test/Transforms/InstCombine/icmp-add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp-add.ll?rev=341353&r1=341352&r2=341353&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/icmp-add.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/icmp-add.ll Tue Sep  4 03:29:48 2018
@@ -283,8 +283,7 @@ define i1 @slt_zero_add_nuw_signbit(i8 %
 
 define i1 @reduce_add_ult(i32 %in) {
 ; CHECK-LABEL: @reduce_add_ult(
-; CHECK-NEXT:    [[A6:%.*]] = add nuw i32 [[IN:%.*]], 3
-; CHECK-NEXT:    [[A18:%.*]] = icmp ult i32 [[A6]], 12
+; CHECK-NEXT:    [[A18:%.*]] = icmp ult i32 [[IN:%.*]], 9
 ; CHECK-NEXT:    ret i1 [[A18]]
 ;
   %a6 = add nuw i32 %in, 3
@@ -294,8 +293,7 @@ define i1 @reduce_add_ult(i32 %in) {
 
 define i1 @reduce_add_ugt(i32 %in) {
 ; CHECK-LABEL: @reduce_add_ugt(
-; CHECK-NEXT:    [[A6:%.*]] = add nuw i32 [[IN:%.*]], 3
-; CHECK-NEXT:    [[A18:%.*]] = icmp ugt i32 [[A6]], 12
+; CHECK-NEXT:    [[A18:%.*]] = icmp ugt i32 [[IN:%.*]], 9
 ; CHECK-NEXT:    ret i1 [[A18]]
 ;
   %a6 = add nuw i32 %in, 3
@@ -305,8 +303,7 @@ define i1 @reduce_add_ugt(i32 %in) {
 
 define i1 @reduce_add_ule(i32 %in) {
 ; CHECK-LABEL: @reduce_add_ule(
-; CHECK-NEXT:    [[A6:%.*]] = add nuw i32 [[IN:%.*]], 3
-; CHECK-NEXT:    [[A18:%.*]] = icmp ult i32 [[A6]], 13
+; CHECK-NEXT:    [[A18:%.*]] = icmp ult i32 [[IN:%.*]], 10
 ; CHECK-NEXT:    ret i1 [[A18]]
 ;
   %a6 = add nuw i32 %in, 3
@@ -316,11 +313,41 @@ define i1 @reduce_add_ule(i32 %in) {
 
 define i1 @reduce_add_uge(i32 %in) {
 ; CHECK-LABEL: @reduce_add_uge(
-; CHECK-NEXT:    [[A6:%.*]] = add nuw i32 [[IN:%.*]], 3
-; CHECK-NEXT:    [[A18:%.*]] = icmp ugt i32 [[A6]], 11
+; CHECK-NEXT:    [[A18:%.*]] = icmp ugt i32 [[IN:%.*]], 8
 ; CHECK-NEXT:    ret i1 [[A18]]
 ;
   %a6 = add nuw i32 %in, 3
   %a18 = icmp uge i32 %a6, 12
   ret i1 %a18
 }
+
+define i1 @ult_add_ssubov(i32 %in) {
+; CHECK-LABEL: @ult_add_ssubov(
+; CHECK-NEXT:    ret i1 false
+;
+  %a6 = add nuw i32 %in, 71
+  %a18 = icmp ult i32 %a6, 3
+  ret i1 %a18
+}
+
+define i1 @ult_add_nonuw(i8 %in) {
+; CHECK-LABEL: @ult_add_nonuw(
+; CHECK-NEXT:    [[A6:%.*]] = add i8 [[IN:%.*]], 71
+; CHECK-NEXT:    [[A18:%.*]] = icmp ult i8 [[A6]], 12
+; CHECK-NEXT:    ret i1 [[A18]]
+;
+  %a6 = add i8 %in, 71
+  %a18 = icmp ult i8 %a6, 12
+  ret i1 %a18
+}
+
+define i1 @uge_add_nonuw(i32 %in) {
+; CHECK-LABEL: @uge_add_nonuw(
+; CHECK-NEXT:    [[A6:%.*]] = add i32 [[IN:%.*]], 3
+; CHECK-NEXT:    [[A18:%.*]] = icmp ugt i32 [[A6]], 11
+; CHECK-NEXT:    ret i1 [[A18]]
+;
+  %a6 = add i32 %in, 3
+  %a18 = icmp uge i32 %a6, 12
+  ret i1 %a18
+}

Modified: llvm/trunk/test/Transforms/LoopVectorize/X86/masked_load_store.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopVectorize/X86/masked_load_store.ll?rev=341353&r1=341352&r2=341353&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopVectorize/X86/masked_load_store.ll (original)
+++ llvm/trunk/test/Transforms/LoopVectorize/X86/masked_load_store.ll Tue Sep  4 03:29:48 2018
@@ -1878,7 +1878,7 @@ define void @foo4(double* %A, double* %B
 ; AVX1-NEXT:    br label [[FOR_INC]]
 ; AVX1:       for.inc:
 ; AVX1-NEXT:    [[INDVARS_IV_NEXT:%.*]] = or i64 [[INDVARS_IV]], 16
-; AVX1-NEXT:    [[CMP:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], 10000
+; AVX1-NEXT:    [[CMP:%.*]] = icmp ult i64 [[INDVARS_IV]], 9984
 ; AVX1-NEXT:    br i1 [[CMP]], label [[FOR_BODY_1:%.*]], label [[FOR_END:%.*]]
 ; AVX1:       for.end:
 ; AVX1-NEXT:    ret void
@@ -1920,7 +1920,7 @@ define void @foo4(double* %A, double* %B
 ; AVX2-NEXT:    br label [[FOR_INC]]
 ; AVX2:       for.inc:
 ; AVX2-NEXT:    [[INDVARS_IV_NEXT:%.*]] = or i64 [[INDVARS_IV]], 16
-; AVX2-NEXT:    [[CMP:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], 10000
+; AVX2-NEXT:    [[CMP:%.*]] = icmp ult i64 [[INDVARS_IV]], 9984
 ; AVX2-NEXT:    br i1 [[CMP]], label [[FOR_BODY_1:%.*]], label [[FOR_END:%.*]]
 ; AVX2:       for.end:
 ; AVX2-NEXT:    ret void
@@ -2119,7 +2119,7 @@ define void @foo4(double* %A, double* %B
 ; AVX512-NEXT:    br label [[FOR_INC_3]]
 ; AVX512:       for.inc.3:
 ; AVX512-NEXT:    [[INDVARS_IV_NEXT_3]] = add nsw i64 [[INDVARS_IV]], 64
-; AVX512-NEXT:    [[CMP_3:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT_3]], 10000
+; AVX512-NEXT:    [[CMP_3:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT_2]], 9984
 ; AVX512-NEXT:    br i1 [[CMP_3]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop !52
 ;
 entry:

Modified: llvm/trunk/test/Transforms/LoopVectorize/if-conversion-nest.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopVectorize/if-conversion-nest.ll?rev=341353&r1=341352&r2=341353&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopVectorize/if-conversion-nest.ll (original)
+++ llvm/trunk/test/Transforms/LoopVectorize/if-conversion-nest.ll Tue Sep  4 03:29:48 2018
@@ -12,7 +12,7 @@ define i32 @foo(i32* nocapture %A, i32*
 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N]], -1
 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
 ; CHECK-NEXT:    [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1
-; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 4
+; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP0]], 3
 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]]
 ; CHECK:       vector.memcheck:
 ; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[N]], -1

Modified: llvm/trunk/test/Transforms/LoopVectorize/runtime-check.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopVectorize/runtime-check.ll?rev=341353&r1=341352&r2=341353&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopVectorize/runtime-check.ll (original)
+++ llvm/trunk/test/Transforms/LoopVectorize/runtime-check.ll Tue Sep  4 03:29:48 2018
@@ -18,7 +18,7 @@ define i32 @foo(float* nocapture %a, flo
 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N]], -1, !dbg !9
 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !dbg !9
 ; CHECK-NEXT:    [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1, !dbg !9
-; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 4, !dbg !9
+; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP0]], 3, !dbg !9
 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]], !dbg !9
 ; CHECK:       vector.memcheck:
 ; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[N]], -1, !dbg !9




More information about the llvm-commits mailing list