[llvm] 7a29496 - [InstCombine] propagate no-wrap flag through select-of-mul fold

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 12 09:57:47 PDT 2021


Author: Sanjay Patel
Date: 2021-10-12T12:57:20-04:00
New Revision: 7a2949647a3c6bbeebe439a078d66b986e12fce2

URL: https://github.com/llvm/llvm-project/commit/7a2949647a3c6bbeebe439a078d66b986e12fce2
DIFF: https://github.com/llvm/llvm-project/commit/7a2949647a3c6bbeebe439a078d66b986e12fce2.diff

LOG: [InstCombine] propagate no-wrap flag through select-of-mul fold

This may not be obvious, but Alive2 agrees:
https://alive2.llvm.org/ce/z/Ld9qNT

If the mul has "nsw", then -1 * INT_MIN is poison, so the
negate can also have "nsw" because 0 - INT_MIN is poison.

If the mul has "nuw", then that means the "OtherOp" can only
be 0 or 1 (anything else multiplied by 0xfff... would wrap).
So the replacement negate must be "nsw" because it is either
"0-0" or "0-1".

This is another regression noticed with a planned follow-up
to D111410.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/test/Transforms/InstCombine/mul-inseltpoison.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 0f96377f3629..779d298da7a4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -107,14 +107,19 @@ static Value *foldMulSelectToNegate(BinaryOperator &I,
   // mul (select Cond, 1, -1), OtherOp --> select Cond, OtherOp, -OtherOp
   // mul OtherOp, (select Cond, 1, -1) --> select Cond, OtherOp, -OtherOp
   if (match(&I, m_c_Mul(m_OneUse(m_Select(m_Value(Cond), m_One(), m_AllOnes())),
-                        m_Value(OtherOp))))
-    return Builder.CreateSelect(Cond, OtherOp, Builder.CreateNeg(OtherOp));
-
+                        m_Value(OtherOp)))) {
+    bool HasAnyNoWrap = I.hasNoSignedWrap() || I.hasNoUnsignedWrap();
+    Value *Neg = Builder.CreateNeg(OtherOp, "", false, HasAnyNoWrap);
+    return Builder.CreateSelect(Cond, OtherOp, Neg);
+  }
   // mul (select Cond, -1, 1), OtherOp --> select Cond, -OtherOp, OtherOp
   // mul OtherOp, (select Cond, -1, 1) --> select Cond, -OtherOp, OtherOp
   if (match(&I, m_c_Mul(m_OneUse(m_Select(m_Value(Cond), m_AllOnes(), m_One())),
-                        m_Value(OtherOp))))
-    return Builder.CreateSelect(Cond, Builder.CreateNeg(OtherOp), OtherOp);
+                        m_Value(OtherOp)))) {
+    bool HasAnyNoWrap = I.hasNoSignedWrap() || I.hasNoUnsignedWrap();
+    Value *Neg = Builder.CreateNeg(OtherOp, "", false, HasAnyNoWrap);
+    return Builder.CreateSelect(Cond, Neg, OtherOp);
+  }
 
   // fmul (select Cond, 1.0, -1.0), OtherOp --> select Cond, OtherOp, -OtherOp
   // fmul OtherOp, (select Cond, 1.0, -1.0) --> select Cond, OtherOp, -OtherOp

diff  --git a/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll b/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll
index 5c66ea072115..7d2038ece44d 100644
--- a/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll
+++ b/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll
@@ -720,7 +720,7 @@ define i32 @negate_if_false(i32 %x, i1 %cond) {
 
 define i32 @negate_if_true_nsw(i32 %x, i1 %cond) {
 ; CHECK-LABEL: @negate_if_true_nsw(
-; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[X:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i32 0, [[X:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[X]]
 ; CHECK-NEXT:    ret i32 [[TMP2]]
 ;
@@ -731,7 +731,7 @@ define i32 @negate_if_true_nsw(i32 %x, i1 %cond) {
 
 define i32 @negate_if_true_nuw(i32 %x, i1 %cond) {
 ; CHECK-LABEL: @negate_if_true_nuw(
-; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[X:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i32 0, [[X:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[X]]
 ; CHECK-NEXT:    ret i32 [[TMP2]]
 ;
@@ -742,7 +742,7 @@ define i32 @negate_if_true_nuw(i32 %x, i1 %cond) {
 
 define i32 @negate_if_false_nsw(i32 %x, i1 %cond) {
 ; CHECK-LABEL: @negate_if_false_nsw(
-; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[X:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i32 0, [[X:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[COND:%.*]], i32 [[X]], i32 [[TMP1]]
 ; CHECK-NEXT:    ret i32 [[TMP2]]
 ;
@@ -753,7 +753,7 @@ define i32 @negate_if_false_nsw(i32 %x, i1 %cond) {
 
 define i32 @negate_if_false_nuw(i32 %x, i1 %cond) {
 ; CHECK-LABEL: @negate_if_false_nuw(
-; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[X:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i32 0, [[X:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[COND:%.*]], i32 [[X]], i32 [[TMP1]]
 ; CHECK-NEXT:    ret i32 [[TMP2]]
 ;


        


More information about the llvm-commits mailing list