[llvm-branch-commits] [llvm] 236c452 - [InstSimplify] remove ctpop of 1 (low) bit

Sanjay Patel via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Dec 28 13:12:14 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-branch-commits mailing list