Skip to content

Commit 2900d03

Browse files
committed
[InstCombine] Propagate flags when folding consecutative shifts
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 #94872
1 parent c2d68c4 commit 2900d03

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -767,11 +767,20 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *C1,
767767
// (C2 >> X) >> C1 --> (C2 >> C1) >> X
768768
Constant *C2;
769769
Value *X;
770-
if (match(Op0, m_BinOp(I.getOpcode(), m_ImmConstant(C2), m_Value(X))))
771-
return BinaryOperator::Create(
770+
bool IsLeftShift = I.getOpcode() == Instruction::Shl;
771+
if (match(Op0, m_BinOp(I.getOpcode(), m_ImmConstant(C2), m_Value(X)))) {
772+
Instruction *R = BinaryOperator::Create(
772773
I.getOpcode(), Builder.CreateBinOp(I.getOpcode(), C2, C1), X);
774+
BinaryOperator *BO0 = cast<BinaryOperator>(Op0);
775+
if (IsLeftShift) {
776+
R->setHasNoUnsignedWrap(I.hasNoUnsignedWrap() &&
777+
BO0->hasNoUnsignedWrap());
778+
R->setHasNoSignedWrap(I.hasNoSignedWrap() && BO0->hasNoSignedWrap());
779+
} else
780+
R->setIsExact(I.isExact() && BO0->isExact());
781+
return R;
782+
}
773783

774-
bool IsLeftShift = I.getOpcode() == Instruction::Shl;
775784
Type *Ty = I.getType();
776785
unsigned TypeBits = Ty->getScalarSizeInBits();
777786

llvm/test/Transforms/InstCombine/shift.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,7 +2242,7 @@ define i129 @shift_zext_not_nneg(i8 %arg) {
22422242

22432243
define i8 @src_shl_nsw(i8 %x) {
22442244
; CHECK-LABEL: @src_shl_nsw(
2245-
; CHECK-NEXT: [[R:%.*]] = shl i8 32, [[X:%.*]]
2245+
; CHECK-NEXT: [[R:%.*]] = shl nsw i8 32, [[X:%.*]]
22462246
; CHECK-NEXT: ret i8 [[R]]
22472247
;
22482248
%sh = shl nsw i8 1, %x
@@ -2262,7 +2262,7 @@ define i8 @src_shl_nsw_fail(i8 %x) {
22622262

22632263
define i8 @src_shl_nuw(i8 %x) {
22642264
; CHECK-LABEL: @src_shl_nuw(
2265-
; CHECK-NEXT: [[R:%.*]] = shl i8 12, [[X:%.*]]
2265+
; CHECK-NEXT: [[R:%.*]] = shl nuw i8 12, [[X:%.*]]
22662266
; CHECK-NEXT: ret i8 [[R]]
22672267
;
22682268
%sh = shl nuw i8 3, %x
@@ -2282,7 +2282,7 @@ define i8 @src_shl_nuw_fail(i8 %x) {
22822282

22832283
define i8 @src_lshr_exact(i8 %x) {
22842284
; CHECK-LABEL: @src_lshr_exact(
2285-
; CHECK-NEXT: [[R:%.*]] = lshr i8 48, [[X:%.*]]
2285+
; CHECK-NEXT: [[R:%.*]] = lshr exact i8 48, [[X:%.*]]
22862286
; CHECK-NEXT: ret i8 [[R]]
22872287
;
22882288
%sh = lshr exact i8 96, %x
@@ -2302,7 +2302,7 @@ define i8 @src_lshr_exact_fail(i8 %x) {
23022302

23032303
define i8 @src_ashr_exact(i8 %x) {
23042304
; CHECK-LABEL: @src_ashr_exact(
2305-
; CHECK-NEXT: [[R:%.*]] = ashr i8 -8, [[X:%.*]]
2305+
; CHECK-NEXT: [[R:%.*]] = ashr exact i8 -8, [[X:%.*]]
23062306
; CHECK-NEXT: ret i8 [[R]]
23072307
;
23082308
%sh = ashr exact i8 -32, %x

0 commit comments

Comments
 (0)