[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