[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