Skip to content

Commit 236c452

Browse files
committed
[InstSimplify] remove ctpop of 1 (low) bit
https://llvm.org/PR48608 As noted in the test comment, we could handle a more general case in instcombine and remove this, but I don't have evidence that we need to do that. https://alive2.llvm.org/ce/z/MRW9gD
1 parent 1351f71 commit 236c452

File tree

3 files changed

+20
-9
lines changed

3 files changed

+20
-9
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5246,6 +5246,15 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
52465246
// bitreverse(bitreverse(x)) -> x
52475247
if (match(Op0, m_BitReverse(m_Value(X)))) return X;
52485248
break;
5249+
case Intrinsic::ctpop: {
5250+
// If everything but the lowest bit is zero, that bit is the pop-count. Ex:
5251+
// ctpop(and X, 1) --> and X, 1
5252+
unsigned BitWidth = Op0->getType()->getScalarSizeInBits();
5253+
if (MaskedValueIsZero(Op0, APInt::getHighBitsSet(BitWidth, BitWidth - 1),
5254+
Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
5255+
return Op0;
5256+
break;
5257+
}
52495258
case Intrinsic::exp:
52505259
// exp(log(x)) -> x
52515260
if (Q.CxtI->hasAllowReassoc() &&

llvm/test/Transforms/InstCombine/ctpop.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ define <2 x i1> @test5vec(<2 x i32> %arg) {
8484
ret <2 x i1> %res
8585
}
8686

87-
; Make sure we don't add range metadata to i1 ctpop.
87+
; No intrinsic or range needed - ctpop of bool bit is the bit itself.
88+
8889
define i1 @test6(i1 %arg) {
8990
; CHECK-LABEL: @test6(
90-
; CHECK-NEXT: [[CNT:%.*]] = call i1 @llvm.ctpop.i1(i1 [[ARG:%.*]])
91-
; CHECK-NEXT: ret i1 [[CNT]]
91+
; CHECK-NEXT: ret i1 [[ARG:%.*]]
9292
;
9393
%cnt = call i1 @llvm.ctpop.i1(i1 %arg)
9494
ret i1 %cnt

llvm/test/Transforms/InstSimplify/call.ll

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,14 +1308,16 @@ declare i1 @llvm.ctpop.i1(i1)
13081308
define i32 @ctpop_lowbit(i32 %x) {
13091309
; CHECK-LABEL: @ctpop_lowbit(
13101310
; CHECK-NEXT: [[B:%.*]] = and i32 [[X:%.*]], 1
1311-
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.ctpop.i32(i32 [[B]])
1312-
; CHECK-NEXT: ret i32 [[R]]
1311+
; CHECK-NEXT: ret i32 [[B]]
13131312
;
13141313
%b = and i32 %x, 1
13151314
%r = call i32 @llvm.ctpop.i32(i32 %b)
13161315
ret i32 %r
13171316
}
13181317

1318+
; Negative test - only low bit allowed
1319+
; This could be reduced by instcombine to and+shift.
1320+
13191321
define i32 @ctpop_pow2(i32 %x) {
13201322
; CHECK-LABEL: @ctpop_pow2(
13211323
; CHECK-NEXT: [[B:%.*]] = and i32 [[X:%.*]], 4
@@ -1330,14 +1332,15 @@ define i32 @ctpop_pow2(i32 %x) {
13301332
define <3 x i33> @ctpop_signbit(<3 x i33> %x) {
13311333
; CHECK-LABEL: @ctpop_signbit(
13321334
; CHECK-NEXT: [[B:%.*]] = lshr <3 x i33> [[X:%.*]], <i33 32, i33 32, i33 32>
1333-
; CHECK-NEXT: [[R:%.*]] = tail call <3 x i33> @llvm.ctpop.v3i33(<3 x i33> [[B]])
1334-
; CHECK-NEXT: ret <3 x i33> [[R]]
1335+
; CHECK-NEXT: ret <3 x i33> [[B]]
13351336
;
13361337
%b = lshr <3 x i33> %x, <i33 32, i33 32, i33 32>
13371338
%r = tail call <3 x i33> @llvm.ctpop.v3i33(<3 x i33> %b)
13381339
ret <3 x i33> %r
13391340
}
13401341

1342+
; Negative test - only 1 bit allowed
1343+
13411344
define <3 x i33> @ctpop_notsignbit(<3 x i33> %x) {
13421345
; CHECK-LABEL: @ctpop_notsignbit(
13431346
; CHECK-NEXT: [[B:%.*]] = lshr <3 x i33> [[X:%.*]], <i33 31, i33 31, i33 31>
@@ -1351,8 +1354,7 @@ define <3 x i33> @ctpop_notsignbit(<3 x i33> %x) {
13511354

13521355
define i1 @ctpop_bool(i1 %x) {
13531356
; CHECK-LABEL: @ctpop_bool(
1354-
; CHECK-NEXT: [[R:%.*]] = tail call i1 @llvm.ctpop.i1(i1 [[X:%.*]])
1355-
; CHECK-NEXT: ret i1 [[R]]
1357+
; CHECK-NEXT: ret i1 [[X:%.*]]
13561358
;
13571359
%r = tail call i1 @llvm.ctpop.i1(i1 %x)
13581360
ret i1 %r

0 commit comments

Comments
 (0)