[llvm] 55c6d91 - [InstCombine] Preserve nuw/nsw/exact flags when transforming (C shift (A add nuw C1)) --> ((C shift C1) shift A). (#79490)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 26 11:33:57 PST 2024


Author: Craig Topper
Date: 2024-01-26T11:33:53-08:00
New Revision: 55c6d9103444aaf70bf680c3768c14e8649bf580

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

LOG: [InstCombine] Preserve nuw/nsw/exact flags when transforming (C shift (A add nuw C1)) --> ((C shift C1) shift A). (#79490)

If we weren't shifting out any non-zero bits or changing the sign before the transform, we
shouldn't be after.

Alive2: https://alive2.llvm.org/ce/z/mB-rWz

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
    llvm/test/Transforms/InstCombine/shift-add.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 54490c46dfaefc..3fbe98fae0b61b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -439,7 +439,14 @@ Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
   if (match(Op0, m_Constant(C)) &&
       match(Op1, m_NUWAdd(m_Value(A), m_Constant(C1)))) {
     Value *NewC = Builder.CreateBinOp(I.getOpcode(), C, C1);
-    return BinaryOperator::Create(I.getOpcode(), NewC, A);
+    BinaryOperator *NewShiftOp = BinaryOperator::Create(I.getOpcode(), NewC, A);
+    if (I.getOpcode() == Instruction::Shl) {
+      NewShiftOp->setHasNoSignedWrap(I.hasNoSignedWrap());
+      NewShiftOp->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
+    } else {
+      NewShiftOp->setIsExact(I.isExact());
+    }
+    return NewShiftOp;
   }
 
   unsigned BitWidth = Ty->getScalarSizeInBits();

diff  --git a/llvm/test/Transforms/InstCombine/shift-add.ll b/llvm/test/Transforms/InstCombine/shift-add.ll
index 6ea2718abb2bbc..1b25675059930b 100644
--- a/llvm/test/Transforms/InstCombine/shift-add.ll
+++ b/llvm/test/Transforms/InstCombine/shift-add.ll
@@ -159,6 +159,48 @@ define i32 @ashr_add_nuw(i32 %x, ptr %p) {
   ret i32 %r
 }
 
+; Preserve nuw and exact flags.
+
+define i32 @shl_nuw_add_nuw(i32 %x) {
+; CHECK-LABEL: @shl_nuw_add_nuw(
+; CHECK-NEXT:    [[R:%.*]] = shl nuw i32 2, [[X:%.*]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %a = add nuw i32 %x, 1
+  %r = shl nuw i32 1, %a
+  ret i32 %r
+}
+
+define i32 @shl_nsw_add_nuw(i32 %x) {
+; CHECK-LABEL: @shl_nsw_add_nuw(
+; CHECK-NEXT:    [[R:%.*]] = shl nsw i32 -2, [[X:%.*]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %a = add nuw i32 %x, 1
+  %r = shl nsw i32 -1, %a
+  ret i32 %r
+}
+
+define i32 @lshr_exact_add_nuw(i32 %x) {
+; CHECK-LABEL: @lshr_exact_add_nuw(
+; CHECK-NEXT:    [[R:%.*]] = lshr exact i32 2, [[X:%.*]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %a = add nuw i32 %x, 1
+  %r = lshr exact i32 4, %a
+  ret i32 %r
+}
+
+define i32 @ashr_exact_add_nuw(i32 %x) {
+; CHECK-LABEL: @ashr_exact_add_nuw(
+; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 -2, [[X:%.*]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %a = add nuw i32 %x, 1
+  %r = ashr exact i32 -4, %a
+  ret i32 %r
+}
+
 ; negative test - must have 'nuw'
 
 define i32 @shl_add_nsw(i32 %x) {


        


More information about the llvm-commits mailing list