[llvm] a2cf44b - [InstCombine] Propagate NUW flags for `shl (lshr X, C1), C2 -> shl X, C2-C1` (#72525)

via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 20 07:29:48 PST 2023


Author: Yingwei Zheng
Date: 2023-11-20T23:29:44+08:00
New Revision: a2cf44b72cbf9361f37dd6f680502bb18070cba3

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

LOG: [InstCombine] Propagate NUW flags for `shl (lshr X, C1), C2 -> shl X, C2-C1` (#72525)

Alive2: https://alive2.llvm.org/ce/z/KNXNQA

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
    llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll
    llvm/test/Transforms/InstCombine/known-signbit-shift.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 4d1b05a9dd3c3c2..c72eb0f74de8e6d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1047,7 +1047,11 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
         // If C1 < C: (X >>?,exact C1) << C --> X << (C - C1)
         Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShrAmt);
         auto *NewShl = BinaryOperator::CreateShl(X, ShiftDiff);
-        NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
+        NewShl->setHasNoUnsignedWrap(
+            I.hasNoUnsignedWrap() ||
+            (ShrAmt &&
+             cast<Instruction>(Op0)->getOpcode() == Instruction::LShr &&
+             I.hasNoSignedWrap()));
         NewShl->setHasNoSignedWrap(I.hasNoSignedWrap());
         return NewShl;
       }
@@ -1068,7 +1072,11 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
         // If C1 < C: (X >>? C1) << C --> (X << (C - C1)) & (-1 << C)
         Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShrAmt);
         auto *NewShl = BinaryOperator::CreateShl(X, ShiftDiff);
-        NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
+        NewShl->setHasNoUnsignedWrap(
+            I.hasNoUnsignedWrap() ||
+            (ShrAmt &&
+             cast<Instruction>(Op0)->getOpcode() == Instruction::LShr &&
+             I.hasNoSignedWrap()));
         NewShl->setHasNoSignedWrap(I.hasNoSignedWrap());
         Builder.Insert(NewShl);
         APInt Mask(APInt::getHighBitsSet(BitWidth, BitWidth - ShAmtC));

diff  --git a/llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll b/llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll
index 501967f0c901e65..719fdd036a01b64 100644
--- a/llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll
+++ b/llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll
@@ -141,8 +141,8 @@ define i8 @positive_biggerlshr_shlnsw(i8 %x) {
 
 define i8 @positive_biggershl_shlnsw(i8 %x) {
 ; CHECK-LABEL: @positive_biggershl_shlnsw(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw i8 [[X:%.*]], 3
-; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], -64
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw nsw i8 [[X:%.*]], 3
+; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], 64
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
   %t0 = lshr i8 %x, 3
@@ -273,7 +273,7 @@ define i8 @positive_biggerlshr_shlnsw_lshrexact(i8 %x) {
 
 define i8 @positive_biggershl_shlnsw_lshrexact(i8 %x) {
 ; CHECK-LABEL: @positive_biggershl_shlnsw_lshrexact(
-; CHECK-NEXT:    [[RET:%.*]] = shl nsw i8 [[X:%.*]], 3
+; CHECK-NEXT:    [[RET:%.*]] = shl nuw nsw i8 [[X:%.*]], 3
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
   %t0 = lshr exact i8 %x, 3

diff  --git a/llvm/test/Transforms/InstCombine/known-signbit-shift.ll b/llvm/test/Transforms/InstCombine/known-signbit-shift.ll
index 17c7fbab12dc470..7492bf96b4fbcb5 100644
--- a/llvm/test/Transforms/InstCombine/known-signbit-shift.ll
+++ b/llvm/test/Transforms/InstCombine/known-signbit-shift.ll
@@ -5,8 +5,7 @@
 ; with nsw flag should also be non-negative
 define i1 @test_shift_nonnegative(i32 %a) {
 ; CHECK-LABEL: @test_shift_nonnegative(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %b = lshr i32 %a, 2
   %shift = shl nsw i32 %b, 3


        


More information about the llvm-commits mailing list