[llvm] r366945 - [InstCombine] Teach foldOrOfICmps to allow icmp eq MIN_INT/MAX to be part of a range comparision. Similar for foldAndOfICmps

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 24 13:57:29 PDT 2019


Author: ctopper
Date: Wed Jul 24 13:57:29 2019
New Revision: 366945

URL: http://llvm.org/viewvc/llvm-project?rev=366945&view=rev
Log:
[InstCombine] Teach foldOrOfICmps to allow icmp eq MIN_INT/MAX to be part of a range comparision. Similar for foldAndOfICmps

We can treat icmp eq X, MIN_UINT as icmp ule X, MIN_UINT and allow
it to merge with icmp ugt X, C. Similar for the other constants.

We can do simliar for icmp ne X, (U)INT_MIN/MAX in foldAndOfICmps. And we already handled UINT_MIN there.

Fixes PR42691.

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

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/trunk/test/Transforms/InstCombine/and-or-icmps.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=366945&r1=366944&r2=366945&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Wed Jul 24 13:57:29 2019
@@ -1197,7 +1197,7 @@ Value *InstCombiner::foldAndOfICmps(ICmp
       // (X != 13 & X u< 14) -> X < 13
       if (LHSC->getValue() == (RHSC->getValue() - 1))
         return Builder.CreateICmpULT(LHS0, LHSC);
-      if (LHSC->isZero()) // (X != 0 & X u< 14) -> X-1 u< 13
+      if (LHSC->isZero()) // (X != 0 & X u< C) -> X-1 u< C-1
         return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(),
                                false, true);
       break; // (X != 13 & X u< 15) -> no change
@@ -1205,7 +1205,11 @@ Value *InstCombiner::foldAndOfICmps(ICmp
       // (X != 13 & X s< 14) -> X < 13
       if (LHSC->getValue() == (RHSC->getValue() - 1))
         return Builder.CreateICmpSLT(LHS0, LHSC);
-      break;                 // (X != 13 & X s< 15) -> no change
+      // (X != INT_MIN & X s< C) -> X-(INT_MIN+1) u< (C-(INT_MIN+1))
+      if (LHSC->isMinValue(true))
+        return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(),
+                               true, true);
+      break; // (X != 13 & X s< 15) -> no change
     case ICmpInst::ICMP_NE:
       // Potential folds for this case should already be handled.
       break;
@@ -1219,8 +1223,12 @@ Value *InstCombiner::foldAndOfICmps(ICmp
       // (X u> 13 & X != 14) -> X u> 14
       if (RHSC->getValue() == (LHSC->getValue() + 1))
         return Builder.CreateICmp(PredL, LHS0, RHSC);
+      // X u> C & X != UINT_MAX -> (X-(C+1)) u< UINT_MAX-(C+1)
+      if (RHSC->isMaxValue(false))
+        return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(),
+                               false, true);
       break;                 // (X u> 13 & X != 15) -> no change
-    case ICmpInst::ICMP_ULT: // (X u> 13 & X u< 15) -> (X-14) <u 1
+    case ICmpInst::ICMP_ULT: // (X u> 13 & X u< 15) -> (X-14) u< 1
       return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(),
                              false, true);
     }
@@ -1233,8 +1241,12 @@ Value *InstCombiner::foldAndOfICmps(ICmp
       // (X s> 13 & X != 14) -> X s> 14
       if (RHSC->getValue() == (LHSC->getValue() + 1))
         return Builder.CreateICmp(PredL, LHS0, RHSC);
+      // X s> C & X != INT_MAX -> (X-(C+1)) u< INT_MAX-(C+1)
+      if (RHSC->isMaxValue(true))
+        return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(),
+                               true, true);
       break;                 // (X s> 13 & X != 15) -> no change
-    case ICmpInst::ICMP_SLT: // (X s> 13 & X s< 15) -> (X-14) s< 1
+    case ICmpInst::ICMP_SLT: // (X s> 13 & X s< 15) -> (X-14) u< 1
       return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(), true,
                              true);
     }
@@ -2253,8 +2265,19 @@ Value *InstCombiner::foldOrOfICmps(ICmpI
     case ICmpInst::ICMP_EQ:
       // Potential folds for this case should already be handled.
       break;
-    case ICmpInst::ICMP_UGT: // (X == 13 | X u> 14) -> no change
-    case ICmpInst::ICMP_SGT: // (X == 13 | X s> 14) -> no change
+    case ICmpInst::ICMP_UGT:
+      // (X == 0 || X u> C) -> (X-1) u>= C
+      if (LHSC->isMinValue(false))
+        return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue() + 1,
+                               false, false);
+      // (X == 13 | X u> 14) -> no change
+      break;
+    case ICmpInst::ICMP_SGT:
+      // (X == INT_MIN || X s> C) -> (X-(INT_MIN+1)) u>= C-INT_MIN
+      if (LHSC->isMinValue(true))
+        return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue() + 1,
+                               true, false);
+      // (X == 13 | X s> 14) -> no change
       break;
     }
     break;
@@ -2263,6 +2286,10 @@ Value *InstCombiner::foldOrOfICmps(ICmpI
     default:
       llvm_unreachable("Unknown integer condition code!");
     case ICmpInst::ICMP_EQ: // (X u< 13 | X == 14) -> no change
+      // (X u< C || X == UINT_MAX) => (X-C) u>= UINT_MAX-C
+      if (RHSC->isMaxValue(false))
+        return insertRangeTest(LHS0, LHSC->getValue(), RHSC->getValue(),
+                               false, false);
       break;
     case ICmpInst::ICMP_UGT: // (X u< 13 | X u> 15) -> (X-13) u> 2
       assert(!RHSC->isMaxValue(false) && "Missed icmp simplification");
@@ -2274,9 +2301,14 @@ Value *InstCombiner::foldOrOfICmps(ICmpI
     switch (PredR) {
     default:
       llvm_unreachable("Unknown integer condition code!");
-    case ICmpInst::ICMP_EQ: // (X s< 13 | X == 14) -> no change
+    case ICmpInst::ICMP_EQ:
+      // (X s< C || X == INT_MAX) => (X-C) u>= INT_MAX-C
+      if (RHSC->isMaxValue(true))
+        return insertRangeTest(LHS0, LHSC->getValue(), RHSC->getValue(),
+                               true, false);
+      // (X s< 13 | X == 14) -> no change
       break;
-    case ICmpInst::ICMP_SGT: // (X s< 13 | X s> 15) -> (X-13) s> 2
+    case ICmpInst::ICMP_SGT: // (X s< 13 | X s> 15) -> (X-13) u> 2
       assert(!RHSC->isMaxValue(true) && "Missed icmp simplification");
       return insertRangeTest(LHS0, LHSC->getValue(), RHSC->getValue() + 1, true,
                              false);

Modified: llvm/trunk/test/Transforms/InstCombine/and-or-icmps.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/and-or-icmps.ll?rev=366945&r1=366944&r2=366945&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/and-or-icmps.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/and-or-icmps.ll Wed Jul 24 13:57:29 2019
@@ -255,10 +255,8 @@ define void @simplify_before_foldAndOfIC
 
 define i1 @PR42691_1(i32 %x) {
 ; CHECK-LABEL: @PR42691_1(
-; CHECK-NEXT:    [[C1:%.*]] = icmp slt i32 %x, 0
-; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 %x, 2147483647
-; CHECK-NEXT:    [[C:%.*]] = or i1 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[C]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 %x, 2147483646
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %c1 = icmp slt i32 %x, 0
   %c2 = icmp eq i32 %x, 2147483647
@@ -279,10 +277,8 @@ define i1 @PR42691_2(i32 %x) {
 
 define i1 @PR42691_3(i32 %x) {
 ; CHECK-LABEL: @PR42691_3(
-; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 %x, -1
-; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 %x, -2147483648
-; CHECK-NEXT:    [[C:%.*]] = or i1 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[C]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 %x, -2147483647
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %c1 = icmp sge i32 %x, 0
   %c2 = icmp eq i32 %x, -2147483648
@@ -303,10 +299,9 @@ define i1 @PR42691_4(i32 %x) {
 
 define i1 @PR42691_5(i32 %x) {
 ; CHECK-LABEL: @PR42691_5(
-; CHECK-NEXT:    [[C1:%.*]] = icmp slt i32 %x, 1
-; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 %x, 2147483647
-; CHECK-NEXT:    [[C:%.*]] = or i1 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[C]]
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 %x, -1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %c1 = icmp slt i32 %x, 1
   %c2 = icmp eq i32 %x, 2147483647
@@ -316,10 +311,9 @@ define i1 @PR42691_5(i32 %x) {
 
 define i1 @PR42691_6(i32 %x) {
 ; CHECK-LABEL: @PR42691_6(
-; CHECK-NEXT:    [[C1:%.*]] = icmp ult i32 %x, -2147483647
-; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 %x, -1
-; CHECK-NEXT:    [[C:%.*]] = or i1 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[C]]
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 %x, 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %c1 = icmp ult i32 %x, 2147483649
   %c2 = icmp eq i32 %x, 4294967295
@@ -341,10 +335,9 @@ define i1 @PR42691_7(i32 %x) {
 
 define i1 @PR42691_8(i32 %x) {
 ; CHECK-LABEL: @PR42691_8(
-; CHECK-NEXT:    [[C1:%.*]] = icmp slt i32 %x, 14
-; CHECK-NEXT:    [[C2:%.*]] = icmp ne i32 %x, -2147483648
-; CHECK-NEXT:    [[C:%.*]] = and i1 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[C]]
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 %x, 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], -2147483635
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %c1 = icmp slt i32 %x, 14
   %c2 = icmp ne i32 %x, -2147483648
@@ -354,10 +347,9 @@ define i1 @PR42691_8(i32 %x) {
 
 define i1 @PR42691_9(i32 %x) {
 ; CHECK-LABEL: @PR42691_9(
-; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 %x, 13
-; CHECK-NEXT:    [[C2:%.*]] = icmp ne i32 %x, 2147483647
-; CHECK-NEXT:    [[C:%.*]] = and i1 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[C]]
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 %x, -14
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 2147483633
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %c1 = icmp sgt i32 %x, 13
   %c2 = icmp ne i32 %x, 2147483647
@@ -367,10 +359,9 @@ define i1 @PR42691_9(i32 %x) {
 
 define i1 @PR42691_10(i32 %x) {
 ; CHECK-LABEL: @PR42691_10(
-; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i32 %x, 13
-; CHECK-NEXT:    [[C2:%.*]] = icmp ne i32 %x, -1
-; CHECK-NEXT:    [[C:%.*]] = and i1 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[C]]
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 %x, -14
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], -15
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %c1 = icmp ugt i32 %x, 13
   %c2 = icmp ne i32 %x, 4294967295




More information about the llvm-commits mailing list