[llvm] r345780 - revert rL345717 : [InstSimplify] fold icmp based on range of abs/nabs

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 31 14:37:40 PDT 2018


Author: spatel
Date: Wed Oct 31 14:37:40 2018
New Revision: 345780

URL: http://llvm.org/viewvc/llvm-project?rev=345780&view=rev
Log:
revert rL345717 : [InstSimplify] fold icmp based on range of abs/nabs

This can miscompile as shown in PR39510:
https://bugs.llvm.org/show_bug.cgi?id=39510

Modified:
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
    llvm/trunk/test/Transforms/InstSimplify/icmp-abs-nabs.ll

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=345780&r1=345779&r2=345780&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Wed Oct 31 14:37:40 2018
@@ -2996,45 +2996,6 @@ static Value *simplifyICmpWithBinOp(CmpI
   return nullptr;
 }
 
-static Value *simplifyICmpWithAbsNabs(CmpInst::Predicate Pred, Value *Op0,
-                                      Value *Op1) {
-  // We need a comparison with a constant.
-  const APInt *C;
-  if (!match(Op1, m_APInt(C)))
-    return nullptr;
-
-  // matchSelectPattern returns the negation part of an abs pattern in SP1.
-  // If the negate has an NSW flag, abs(INT_MIN) is undefined. Without that
-  // constraint, we can't make a contiguous range for the result of abs.
-  ICmpInst::Predicate AbsPred = ICmpInst::BAD_ICMP_PREDICATE;
-  Value *SP0, *SP1;
-  SelectPatternFlavor SPF = matchSelectPattern(Op0, SP0, SP1).Flavor;
-  if (SPF == SelectPatternFlavor::SPF_ABS &&
-      cast<Instruction>(SP1)->hasNoSignedWrap())
-    // The result of abs(X) is >= 0 (with nsw).
-    AbsPred = ICmpInst::ICMP_SGE;
-  if (SPF == SelectPatternFlavor::SPF_NABS)
-    // The result of -abs(X) is <= 0.
-    AbsPred = ICmpInst::ICMP_SLE;
-
-  if (AbsPred == ICmpInst::BAD_ICMP_PREDICATE)
-    return nullptr;
-
-  // Intersect the range of abs/nabs with the range of this icmp.
-  // If there is no intersection, the icmp must be false.
-  // If the intersection equals the range of abs/nabs, the icmp must be true.
-  APInt Zero = APInt::getNullValue(C->getBitWidth());
-  ConstantRange AbsRange = ConstantRange::makeExactICmpRegion(AbsPred, Zero);
-  ConstantRange CmpRange = ConstantRange::makeExactICmpRegion(Pred, *C);
-  ConstantRange Intersection = AbsRange.intersectWith(CmpRange);
-  if (Intersection.isEmptySet())
-    return getFalse(GetCompareTy(Op0));
-  if (Intersection == AbsRange)
-    return getTrue(GetCompareTy(Op0));
-
-  return nullptr;
-}
-
 /// Simplify integer comparisons where at least one operand of the compare
 /// matches an integer min/max idiom.
 static Value *simplifyICmpWithMinMax(CmpInst::Predicate Pred, Value *LHS,
@@ -3466,9 +3427,6 @@ static Value *SimplifyICmpInst(unsigned
   if (Value *V = simplifyICmpWithMinMax(Pred, LHS, RHS, Q, MaxRecurse))
     return V;
 
-  if (Value *V = simplifyICmpWithAbsNabs(Pred, LHS, RHS))
-    return V;
-
   // Simplify comparisons of related pointers using a powerful, recursive
   // GEP-walk when we have target data available..
   if (LHS->getType()->isPointerTy())

Modified: llvm/trunk/test/Transforms/InstSimplify/icmp-abs-nabs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/icmp-abs-nabs.ll?rev=345780&r1=345779&r2=345780&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/icmp-abs-nabs.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/icmp-abs-nabs.ll Wed Oct 31 14:37:40 2018
@@ -5,7 +5,11 @@
 
 define i1 @abs_nsw_is_positive(i32 %x) {
 ; CHECK-LABEL: @abs_nsw_is_positive(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
+; CHECK-NEXT:    [[NEGX:%.*]] = sub nsw i32 0, [[X]]
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sgt i32 [[ABS]], -1
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i32 %x, 0
   %negx = sub nsw i32 0, %x
@@ -31,7 +35,11 @@ define i1 @abs_nsw_is_positive_sge(i32 %
 
 define i1 @abs_nsw_is_positive_reduced_range(i32 %x) {
 ; CHECK-LABEL: @abs_nsw_is_positive_reduced_range(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
+; CHECK-NEXT:    [[NEGX:%.*]] = sub nsw i32 0, [[X]]
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sgt i32 [[ABS]], -42
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i32 %x, 0
   %negx = sub nsw i32 0, %x
@@ -91,7 +99,11 @@ define i1 @abs_nsw_is_not_negative(i32 %
 
 define i1 @abs_nsw_is_not_negative_sle(i32 %x) {
 ; CHECK-LABEL: @abs_nsw_is_not_negative_sle(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[NEGX:%.*]] = sub nsw i32 0, [[X]]
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sle i32 [[ABS]], -1
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i32 %x, 1
   %negx = sub nsw i32 0, %x
@@ -104,7 +116,11 @@ define i1 @abs_nsw_is_not_negative_sle(i
 
 define i1 @abs_nsw_is_not_negative_reduced_range(i32 %x) {
 ; CHECK-LABEL: @abs_nsw_is_not_negative_reduced_range(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
+; CHECK-NEXT:    [[NEGX:%.*]] = sub nsw i32 0, [[X]]
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
+; CHECK-NEXT:    [[R:%.*]] = icmp slt i32 [[ABS]], -24
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i32 %x, 0
   %negx = sub nsw i32 0, %x
@@ -151,7 +167,11 @@ define i1 @abs_nsw_is_not_negative_wrong
 
 define i1 @nabs_is_negative_or_0(i32 %x) {
 ; CHECK-LABEL: @nabs_is_negative_or_0(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
+; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, [[X]]
+; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
+; CHECK-NEXT:    [[R:%.*]] = icmp slt i32 [[NABS]], 1
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i32 %x, 0
   %negx = sub i32 0, %x
@@ -164,7 +184,11 @@ define i1 @nabs_is_negative_or_0(i32 %x)
 
 define i1 @nabs_is_negative_or_0_sle(i32 %x) {
 ; CHECK-LABEL: @nabs_is_negative_or_0_sle(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, [[X]]
+; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sle i32 [[NABS]], 0
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i32 %x, 1
   %negx = sub i32 0, %x
@@ -177,7 +201,11 @@ define i1 @nabs_is_negative_or_0_sle(i32
 
 define i1 @nabs_is_negative_or_0_reduced_range(i32 %x) {
 ; CHECK-LABEL: @nabs_is_negative_or_0_reduced_range(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, [[X]]
+; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
+; CHECK-NEXT:    [[R:%.*]] = icmp slt i32 [[NABS]], 421
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i32 %x, 1
   %negx = sub i32 0, %x
@@ -207,7 +235,11 @@ define i1 @nabs_is_negative_or_0_wrong_r
 
 define i1 @nabs_is_not_over_0(i32 %x) {
 ; CHECK-LABEL: @nabs_is_not_over_0(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
+; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, [[X]]
+; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sgt i32 [[NABS]], 0
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i32 %x, 0
   %negx = sub i32 0, %x
@@ -220,7 +252,11 @@ define i1 @nabs_is_not_over_0(i32 %x) {
 
 define i1 @nabs_is_not_over_0_sle(i32 %x) {
 ; CHECK-LABEL: @nabs_is_not_over_0_sle(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, [[X]]
+; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sge i32 [[NABS]], 1
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i32 %x, 1
   %negx = sub i32 0, %x
@@ -233,7 +269,11 @@ define i1 @nabs_is_not_over_0_sle(i32 %x
 
 define i1 @nabs_is_not_over_0_reduced_range(i32 %x) {
 ; CHECK-LABEL: @nabs_is_not_over_0_reduced_range(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, [[X]]
+; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sgt i32 [[NABS]], 4223
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i32 %x, 1
   %negx = sub i32 0, %x
@@ -278,7 +318,11 @@ define i1 @abs_nsw_is_positive_eq(i32 %x
 
 define i1 @abs_nsw_is_positive_ult(i8 %x) {
 ; CHECK-LABEL: @abs_nsw_is_positive_ult(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
+; CHECK-NEXT:    [[NEGX:%.*]] = sub nsw i8 0, [[X]]
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEGX]], i8 [[X]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[ABS]], -117
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i8 %x, 0
   %negx = sub nsw i8 0, %x
@@ -291,7 +335,11 @@ define i1 @abs_nsw_is_positive_ult(i8 %x
 
 define i1 @abs_nsw_is_not_negative_ugt(i8 %x) {
 ; CHECK-LABEL: @abs_nsw_is_not_negative_ugt(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
+; CHECK-NEXT:    [[NEGX:%.*]] = sub nsw i8 0, [[X]]
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEGX]], i8 [[X]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[ABS]], 127
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i8 %x, 0
   %negx = sub nsw i8 0, %x
@@ -304,7 +352,11 @@ define i1 @abs_nsw_is_not_negative_ugt(i
 
 define <2 x i1> @abs_nsw_is_not_negative_vec_splat(<2 x i32> %x) {
 ; CHECK-LABEL: @abs_nsw_is_not_negative_vec_splat(
-; CHECK-NEXT:    ret <2 x i1> zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    [[NEGX:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X]]
+; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[NEGX]], <2 x i32> [[X]]
+; CHECK-NEXT:    [[R:%.*]] = icmp slt <2 x i32> [[ABS]], <i32 -8, i32 -8>
+; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %cmp = icmp slt <2 x i32> %x, zeroinitializer
   %negx = sub nsw <2 x i32> zeroinitializer, %x
@@ -317,7 +369,11 @@ define <2 x i1> @abs_nsw_is_not_negative
 
 define i1 @nabs_is_negative_or_0_ne(i8 %x) {
 ; CHECK-LABEL: @nabs_is_negative_or_0_ne(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
+; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X]]
+; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEGX]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[NABS]], 12
+; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp = icmp slt i8 %x, 0
   %negx = sub i8 0, %x
@@ -330,7 +386,11 @@ define i1 @nabs_is_negative_or_0_ne(i8 %
 
 define <3 x i1> @nabs_is_not_over_0_sle_vec_splat(<3 x i33> %x) {
 ; CHECK-LABEL: @nabs_is_not_over_0_sle_vec_splat(
-; CHECK-NEXT:    ret <3 x i1> zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <3 x i33> [[X:%.*]], <i33 1, i33 1, i33 1>
+; CHECK-NEXT:    [[NEGX:%.*]] = sub <3 x i33> zeroinitializer, [[X]]
+; CHECK-NEXT:    [[NABS:%.*]] = select <3 x i1> [[CMP]], <3 x i33> [[X]], <3 x i33> [[NEGX]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sge <3 x i33> [[NABS]], <i33 1, i33 1, i33 1>
+; CHECK-NEXT:    ret <3 x i1> [[R]]
 ;
   %cmp = icmp slt <3 x i33> %x, <i33 1, i33 1, i33 1>
   %negx = sub <3 x i33> zeroinitializer, %x




More information about the llvm-commits mailing list