Author: Sanjay Patel Date: 2020-12-28T16:06:20-05:00 New Revision: 236c4524a7cd3051a150690b4f4f55f496e7e248
URL: https://github.com/llvm/llvm-project/commit/236c4524a7cd3051a150690b4f4f55f496e7e248 DIFF: https://github.com/llvm/llvm-project/commit/236c4524a7cd3051a150690b4f4f55f496e7e248.diff LOG: [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 Added: Modified: llvm/lib/Analysis/InstructionSimplify.cpp llvm/test/Transforms/InstCombine/ctpop.ll llvm/test/Transforms/InstSimplify/call.ll Removed: ################################################################################ diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 27b73a5a8236..30c7ecff7940 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -5246,6 +5246,15 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0, // bitreverse(bitreverse(x)) -> x if (match(Op0, m_BitReverse(m_Value(X)))) return X; break; + case Intrinsic::ctpop: { + // If everything but the lowest bit is zero, that bit is the pop-count. Ex: + // ctpop(and X, 1) --> and X, 1 + unsigned BitWidth = Op0->getType()->getScalarSizeInBits(); + if (MaskedValueIsZero(Op0, APInt::getHighBitsSet(BitWidth, BitWidth - 1), + Q.DL, 0, Q.AC, Q.CxtI, Q.DT)) + return Op0; + break; + } case Intrinsic::exp: // exp(log(x)) -> x if (Q.CxtI->hasAllowReassoc() && diff --git a/llvm/test/Transforms/InstCombine/ctpop.ll b/llvm/test/Transforms/InstCombine/ctpop.ll index 33b95b02dd2e..237fb0458225 100644 --- a/llvm/test/Transforms/InstCombine/ctpop.ll +++ b/llvm/test/Transforms/InstCombine/ctpop.ll @@ -84,11 +84,11 @@ define <2 x i1> @test5vec(<2 x i32> %arg) { ret <2 x i1> %res } -; Make sure we don't add range metadata to i1 ctpop. +; No intrinsic or range needed - ctpop of bool bit is the bit itself. + define i1 @test6(i1 %arg) { ; CHECK-LABEL: @test6( -; CHECK-NEXT: [[CNT:%.*]] = call i1 @llvm.ctpop.i1(i1 [[ARG:%.*]]) -; CHECK-NEXT: ret i1 [[CNT]] +; CHECK-NEXT: ret i1 [[ARG:%.*]] ; %cnt = call i1 @llvm.ctpop.i1(i1 %arg) ret i1 %cnt diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll index fa73e07b4c45..841582ab8974 100644 --- a/llvm/test/Transforms/InstSimplify/call.ll +++ b/llvm/test/Transforms/InstSimplify/call.ll @@ -1308,14 +1308,16 @@ declare i1 @llvm.ctpop.i1(i1) define i32 @ctpop_lowbit(i32 %x) { ; CHECK-LABEL: @ctpop_lowbit( ; CHECK-NEXT: [[B:%.*]] = and i32 [[X:%.*]], 1 -; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.ctpop.i32(i32 [[B]]) -; CHECK-NEXT: ret i32 [[R]] +; CHECK-NEXT: ret i32 [[B]] ; %b = and i32 %x, 1 %r = call i32 @llvm.ctpop.i32(i32 %b) ret i32 %r } +; Negative test - only low bit allowed +; This could be reduced by instcombine to and+shift. + define i32 @ctpop_pow2(i32 %x) { ; CHECK-LABEL: @ctpop_pow2( ; CHECK-NEXT: [[B:%.*]] = and i32 [[X:%.*]], 4 @@ -1330,14 +1332,15 @@ define i32 @ctpop_pow2(i32 %x) { define <3 x i33> @ctpop_signbit(<3 x i33> %x) { ; CHECK-LABEL: @ctpop_signbit( ; CHECK-NEXT: [[B:%.*]] = lshr <3 x i33> [[X:%.*]], <i33 32, i33 32, i33 32> -; CHECK-NEXT: [[R:%.*]] = tail call <3 x i33> @llvm.ctpop.v3i33(<3 x i33> [[B]]) -; CHECK-NEXT: ret <3 x i33> [[R]] +; CHECK-NEXT: ret <3 x i33> [[B]] ; %b = lshr <3 x i33> %x, <i33 32, i33 32, i33 32> %r = tail call <3 x i33> @llvm.ctpop.v3i33(<3 x i33> %b) ret <3 x i33> %r } +; Negative test - only 1 bit allowed + define <3 x i33> @ctpop_notsignbit(<3 x i33> %x) { ; CHECK-LABEL: @ctpop_notsignbit( ; 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) { define i1 @ctpop_bool(i1 %x) { ; CHECK-LABEL: @ctpop_bool( -; CHECK-NEXT: [[R:%.*]] = tail call i1 @llvm.ctpop.i1(i1 [[X:%.*]]) -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[X:%.*]] ; %r = tail call i1 @llvm.ctpop.i1(i1 %x) ret i1 %r _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits