[llvm] 236c452 - [InstSimplify] remove ctpop of 1 (low) bit
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 28 13:08:22 PST 2020
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
More information about the llvm-commits
mailing list