-
Notifications
You must be signed in to change notification settings - Fork 14.2k
[InstCombine] Propagate flags when folding consecutative shifts #94872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
When we fold `(shift (shift C0, x), C1)` we can propagate flags that are common to both shifts. Proofs: https://alive2.llvm.org/ce/z/LkEzXD
@llvm/pr-subscribers-llvm-transforms Author: None (goldsteinn) Changes
Full diff: https://github.com/llvm/llvm-project/pull/94872.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 9ff817da79368..4a014ab6e044e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -767,11 +767,20 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *C1,
// (C2 >> X) >> C1 --> (C2 >> C1) >> X
Constant *C2;
Value *X;
- if (match(Op0, m_BinOp(I.getOpcode(), m_ImmConstant(C2), m_Value(X))))
- return BinaryOperator::Create(
+ bool IsLeftShift = I.getOpcode() == Instruction::Shl;
+ if (match(Op0, m_BinOp(I.getOpcode(), m_ImmConstant(C2), m_Value(X)))) {
+ Instruction *R = BinaryOperator::Create(
I.getOpcode(), Builder.CreateBinOp(I.getOpcode(), C2, C1), X);
+ BinaryOperator *BO0 = cast<BinaryOperator>(Op0);
+ if (IsLeftShift) {
+ R->setHasNoUnsignedWrap(I.hasNoUnsignedWrap() &&
+ BO0->hasNoUnsignedWrap());
+ R->setHasNoSignedWrap(I.hasNoSignedWrap() && BO0->hasNoSignedWrap());
+ } else
+ R->setIsExact(I.isExact() && BO0->isExact());
+ return R;
+ }
- bool IsLeftShift = I.getOpcode() == Instruction::Shl;
Type *Ty = I.getType();
unsigned TypeBits = Ty->getScalarSizeInBits();
diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll
index 8da52e0746373..03536f37fe762 100644
--- a/llvm/test/Transforms/InstCombine/shift.ll
+++ b/llvm/test/Transforms/InstCombine/shift.ll
@@ -2240,4 +2240,84 @@ define i129 @shift_zext_not_nneg(i8 %arg) {
ret i129 %shl
}
+define i8 @src_shl_nsw(i8 %x) {
+; CHECK-LABEL: @src_shl_nsw(
+; CHECK-NEXT: [[R:%.*]] = shl nsw i8 32, [[X:%.*]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %sh = shl nsw i8 1, %x
+ %r = shl nsw i8 %sh, 5
+ ret i8 %r
+}
+
+define i8 @src_shl_nsw_fail(i8 %x) {
+; CHECK-LABEL: @src_shl_nsw_fail(
+; CHECK-NEXT: [[R:%.*]] = shl i8 32, [[X:%.*]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %sh = shl nsw i8 1, %x
+ %r = shl i8 %sh, 5
+ ret i8 %r
+}
+
+define i8 @src_shl_nuw(i8 %x) {
+; CHECK-LABEL: @src_shl_nuw(
+; CHECK-NEXT: [[R:%.*]] = shl nuw i8 12, [[X:%.*]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %sh = shl nuw i8 3, %x
+ %r = shl nuw i8 %sh, 2
+ ret i8 %r
+}
+
+define i8 @src_shl_nuw_fail(i8 %x) {
+; CHECK-LABEL: @src_shl_nuw_fail(
+; CHECK-NEXT: [[R:%.*]] = shl i8 12, [[X:%.*]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %sh = shl i8 3, %x
+ %r = shl nuw i8 %sh, 2
+ ret i8 %r
+}
+
+define i8 @src_lshr_exact(i8 %x) {
+; CHECK-LABEL: @src_lshr_exact(
+; CHECK-NEXT: [[R:%.*]] = lshr exact i8 48, [[X:%.*]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %sh = lshr exact i8 96, %x
+ %r = lshr exact i8 %sh, 1
+ ret i8 %r
+}
+
+define i8 @src_lshr_exact_fail(i8 %x) {
+; CHECK-LABEL: @src_lshr_exact_fail(
+; CHECK-NEXT: [[R:%.*]] = lshr i8 48, [[X:%.*]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %sh = lshr exact i8 96, %x
+ %r = lshr i8 %sh, 1
+ ret i8 %r
+}
+
+define i8 @src_ashr_exact(i8 %x) {
+; CHECK-LABEL: @src_ashr_exact(
+; CHECK-NEXT: [[R:%.*]] = lshr exact i8 8, [[X:%.*]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %sh = ashr exact i8 32, %x
+ %r = ashr exact i8 %sh, 2
+ ret i8 %r
+}
+
+define i8 @src_ashr_exact_fail(i8 %x) {
+; CHECK-LABEL: @src_ashr_exact_fail(
+; CHECK-NEXT: [[R:%.*]] = lshr i8 8, [[X:%.*]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %sh = ashr i8 32, %x
+ %r = ashr exact i8 %sh, 2
+ ret i8 %r
+}
+
declare i16 @llvm.umax.i16(i16, i16)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
(It looks like your alive2 link also has the proofs for flag-preservation for a related case that's not part of this PR.)
Bah sorry for the confusion. Realized that case is already handled after writing the proofs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
; CHECK-NEXT: [[R:%.*]] = lshr exact i8 8, [[X:%.*]] | ||
; CHECK-NEXT: ret i8 [[R]] | ||
; | ||
%sh = ashr exact i8 32, %x |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you replace LHS with a negative number?
When we fold `(shift (shift C0, x), C1)` we can propagate flags that are common to both shifts. Proofs: https://alive2.llvm.org/ce/z/LkEzXD Closes llvm#94872 Signed-off-by: Hafidz Muzakky <[email protected]>
When we fold
(shift (shift C0, x), C1)
we can propagate flags thatare common to both shifts.
Proofs: https://alive2.llvm.org/ce/z/LkEzXD