[llvm] r333300 - Recommit r333226 "[ValueTracking] Teach computeKnownBits that the result of an absolute value pattern that uses nsw flag is always positive."

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri May 25 12:18:09 PDT 2018


Author: ctopper
Date: Fri May 25 12:18:09 2018
New Revision: 333300

URL: http://llvm.org/viewvc/llvm-project?rev=333300&view=rev
Log:
Recommit r333226 "[ValueTracking] Teach computeKnownBits that the result of an absolute value pattern that uses nsw flag is always positive."

Libfuzzer tests have been fixed to prevent being optimized.

Original commit message:

If the nsw flag is used in the absolute value then it is undefined for INT_MIN. For all other value it will produce a positive number. So we can assume the result is positive.

This breaks some InstCombine abs/nabs combining tests because we simplify the second compare from known bits rather than as the whole pattern. Looks like we can probably fix it by adding a neg+abs/nabs combine to just swap the select operands. N

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

Modified:
    llvm/trunk/lib/Analysis/ValueTracking.cpp
    llvm/trunk/test/Transforms/InstCombine/abs-1.ll
    llvm/trunk/test/Transforms/InstCombine/abs_abs.ll

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=333300&r1=333299&r2=333300&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Fri May 25 12:18:09 2018
@@ -1078,6 +1078,12 @@ static void computeKnownBitsFromOperator
       // leading zero bits.
       MaxHighZeros =
           std::max(Known.countMinLeadingZeros(), Known2.countMinLeadingZeros());
+    } else if (SPF == SPF_ABS) {
+      // RHS from matchSelectPattern returns the negation part of abs pattern.
+      // If the negate has an NSW flag we can assume the sign bit of the result
+      // will be 0 because that makes abs(INT_MIN) undefined.
+      if (cast<Instruction>(RHS)->hasNoSignedWrap())
+        MaxHighZeros = 1;
     }
 
     // Only known if known in both the LHS and RHS.

Modified: llvm/trunk/test/Transforms/InstCombine/abs-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/abs-1.ll?rev=333300&r1=333299&r2=333300&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/abs-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/abs-1.ll Fri May 25 12:18:09 2018
@@ -293,3 +293,14 @@ define <2 x i8> @negate_nabs(<2 x i8> %x
   %r = sub <2 x i8> zeroinitializer, %s
   ret <2 x i8> %r
 }
+
+define i1 @abs_must_be_positive(i32 %x) {
+; CHECK-LABEL: @abs_must_be_positive(
+; CHECK-NEXT:    ret i1 true
+;
+  %negx = sub nsw i32 0, %x
+  %c = icmp sge i32 %x, 0
+  %sel = select i1 %c, i32 %x, i32 %negx
+  %c2 = icmp sge i32 %sel, 0
+  ret i1 %c2
+}

Modified: llvm/trunk/test/Transforms/InstCombine/abs_abs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/abs_abs.ll?rev=333300&r1=333299&r2=333300&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/abs_abs.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/abs_abs.ll Fri May 25 12:18:09 2018
@@ -933,8 +933,8 @@ define i32 @nabs_abs_x09(i32 %x) {
 ; CHECK-LABEL: @nabs_abs_x09(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[X]]
-; CHECK-NEXT:    [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[COND1]]
+; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
+; CHECK-NEXT:    ret i32 [[COND]]
 ;
   %cmp = icmp sgt i32 %x, -1
   %sub = sub nsw i32 0, %x
@@ -949,8 +949,8 @@ define i32 @nabs_abs_x10(i32 %x) {
 ; CHECK-LABEL: @nabs_abs_x10(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[X]]
-; CHECK-NEXT:    [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[COND1]]
+; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
+; CHECK-NEXT:    ret i32 [[COND]]
 ;
   %cmp = icmp sgt i32 %x, 0
   %sub = sub nsw i32 0, %x
@@ -965,8 +965,8 @@ define i32 @nabs_abs_x11(i32 %x) {
 ; CHECK-LABEL: @nabs_abs_x11(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[X]]
-; CHECK-NEXT:    [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[COND1]]
+; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
+; CHECK-NEXT:    ret i32 [[COND]]
 ;
   %cmp = icmp slt i32 %x, 0
   %sub = sub nsw i32 0, %x
@@ -981,8 +981,8 @@ define i32 @nabs_abs_x12(i32 %x) {
 ; CHECK-LABEL: @nabs_abs_x12(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[X]]
-; CHECK-NEXT:    [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[COND1]]
+; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
+; CHECK-NEXT:    ret i32 [[COND]]
 ;
   %cmp = icmp slt i32 %x, 1
   %sub = sub nsw i32 0, %x




More information about the llvm-commits mailing list