Skip to content

Commit c26fff8

Browse files
committed
Add fold for zero
Propagate nowrap flags to new shift Use named values in tests Remove intrinsic declarations
1 parent 9f70feb commit c26fff8

File tree

2 files changed

+19
-22
lines changed

2 files changed

+19
-22
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,18 +1614,19 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
16141614
return Overflow;
16151615

16161616
// Transform ((pow2 << x) >> cttz(pow2 << y)) -> ((1 << x) >> y)
1617-
Value *Shl0_Op0, *Shl0_Op1, *Shl1_Op0, *Shl1_Op1;
1617+
Value *Shl0_Op0, *Shl0_Op1, *Shl1_Op1;
16181618
BinaryOperator *Shl1;
16191619
if (match(Op0, m_Shl(m_Value(Shl0_Op0), m_Value(Shl0_Op1))) &&
16201620
match(Op1, m_Intrinsic<Intrinsic::cttz>(m_BinOp(Shl1))) &&
1621-
match(Shl1, m_Shl(m_Value(Shl1_Op0), m_Value(Shl1_Op1))) &&
1622-
isKnownToBeAPowerOfTwo(Shl1, false, 0, SQ.getWithInstruction(&I).CxtI) &&
1623-
Shl0_Op0 == Shl1_Op0) {
1621+
match(Shl1, m_Shl(m_Specific(Shl0_Op0), m_Value(Shl1_Op1))) &&
1622+
isKnownToBeAPowerOfTwo(Shl0_Op0, /*OrZero=*/true, 0, &I)) {
16241623
auto *Shl0 = cast<BinaryOperator>(Op0);
1625-
if ((Shl0->hasNoUnsignedWrap() && Shl1->hasNoUnsignedWrap()) ||
1626-
(Shl0->hasNoSignedWrap() && Shl1->hasNoSignedWrap())) {
1627-
Value *NewShl =
1628-
Builder.CreateShl(ConstantInt::get(Shl1->getType(), 1), Shl0_Op1);
1624+
bool HasNUW = Shl0->hasNoUnsignedWrap() && Shl1->hasNoUnsignedWrap();
1625+
bool HasNSW = Shl0->hasNoSignedWrap() && Shl1->hasNoSignedWrap();
1626+
if (HasNUW || HasNSW) {
1627+
Value *NewShl = Builder.CreateShl(ConstantInt::get(Shl1->getType(), 1),
1628+
Shl0_Op1, "", HasNUW, HasNSW);
1629+
Builder.CreateShl(ConstantInt::get(Shl1->getType(), 1), Shl0_Op1);
16291630
return BinaryOperator::CreateLShr(NewShl, Shl1_Op1);
16301631
}
16311632
}

llvm/test/Transforms/InstCombine/shift-cttz-ctlz.ll

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,11 @@ define i64 @fold_cttz_64() vscale_range(1,16) {
110110
; CHECK-NEXT: ret i64 4
111111
;
112112
entry:
113-
%0 = tail call i64 @llvm.vscale.i64()
114-
%1 = shl nuw nsw i64 %0, 4
115-
%2 = shl nuw nsw i64 %0, 2
116-
%3 = tail call range(i64 2, 65) i64 @llvm.cttz.i64(i64 %2, i1 true)
117-
%div1 = lshr i64 %1, %3
113+
%vscale = tail call i64 @llvm.vscale.i64()
114+
%shl0 = shl nuw nsw i64 %vscale, 4
115+
%shl1 = shl nuw nsw i64 %vscale, 2
116+
%cttz = tail call range(i64 2, 65) i64 @llvm.cttz.i64(i64 %shl1, i1 true)
117+
%div1 = lshr i64 %shl0, %cttz
118118
ret i64 %div1
119119
}
120120

@@ -125,16 +125,12 @@ define i32 @fold_cttz_32() vscale_range(1,16) {
125125
; CHECK-NEXT: ret i32 4
126126
;
127127
entry:
128-
%0 = tail call i32 @llvm.vscale.i32()
129-
%1 = shl nuw nsw i32 %0, 4
130-
%2 = shl nuw nsw i32 %0, 2
131-
%3 = tail call range(i32 2, 65) i32 @llvm.cttz.i32(i32 %2, i1 true)
132-
%div1 = lshr i32 %1, %3
128+
%vscale = tail call i32 @llvm.vscale.i32()
129+
%shl0 = shl nuw nsw i32 %vscale, 4
130+
%shl1 = shl nuw nsw i32 %vscale, 2
131+
%cttz = tail call range(i32 2, 65) i32 @llvm.cttz.i32(i32 %shl1, i1 true)
132+
%div1 = lshr i32 %shl0, %cttz
133133
ret i32 %div1
134134
}
135135

136-
declare i64 @llvm.vscale.i64()
137-
declare i64 @llvm.cttz.i64(i64, i1 immarg)
138-
declare i32 @llvm.vscale.i32()
139-
declare i32 @llvm.cttz.i32(i32, i1 immarg)
140136
declare void @use(i32)

0 commit comments

Comments
 (0)