[llvm] 78f29ac - Add transform ctpop(X) -> 1 iff X is non-zero power of 2

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 19 11:29:40 PST 2023


Author: Noah Goldstein
Date: 2023-01-19T11:26:24-08:00
New Revision: 78f29acae6dc159660753ac91faefa390e2bad93

URL: https://github.com/llvm/llvm-project/commit/78f29acae6dc159660753ac91faefa390e2bad93
DIFF: https://github.com/llvm/llvm-project/commit/78f29acae6dc159660753ac91faefa390e2bad93.diff

LOG: Add transform ctpop(X) -> 1 iff X is non-zero power of 2

Definitionally a non-zero power of 2 will only have 1 bit set so this
is a freebee.

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D141990

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/ctpop-pow2.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 20a036cd61436..3f3f6c6e0d1a9 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5928,6 +5928,10 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
       return X;
     break;
   case Intrinsic::ctpop: {
+    // ctpop(X) -> 1 iff X is non-zero power of 2.
+    if (isKnownToBeAPowerOfTwo(Op0, Q.DL, /*OrZero*/ false, 0, Q.AC, Q.CxtI,
+                               Q.DT))
+      return ConstantInt::get(Op0->getType(), 1);
     // 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();

diff  --git a/llvm/test/Transforms/InstSimplify/ctpop-pow2.ll b/llvm/test/Transforms/InstSimplify/ctpop-pow2.ll
index caa605c34e8c1..2711d36d6a461 100644
--- a/llvm/test/Transforms/InstSimplify/ctpop-pow2.ll
+++ b/llvm/test/Transforms/InstSimplify/ctpop-pow2.ll
@@ -10,9 +10,7 @@ declare void @llvm.assume(i1)
 
 define i64 @ctpop_1_shl(i64 %x) {
 ; CHECK-LABEL: @ctpop_1_shl(
-; CHECK-NEXT:    [[V:%.*]] = shl i64 1, [[X:%.*]]
-; CHECK-NEXT:    [[CNT:%.*]] = call i64 @llvm.ctpop.i64(i64 [[V]])
-; CHECK-NEXT:    ret i64 [[CNT]]
+; CHECK-NEXT:    ret i64 1
 ;
   %v = shl i64 1, %x
   %cnt = call i64 @llvm.ctpop.i64(i64 %v)
@@ -21,9 +19,7 @@ define i64 @ctpop_1_shl(i64 %x) {
 
 define i32 @ctpop_imin_lshr(i32 %x) {
 ; CHECK-LABEL: @ctpop_imin_lshr(
-; CHECK-NEXT:    [[V:%.*]] = lshr i32 -2147483648, [[X:%.*]]
-; CHECK-NEXT:    [[CNT:%.*]] = call i32 @llvm.ctpop.i32(i32 [[V]])
-; CHECK-NEXT:    ret i32 [[CNT]]
+; CHECK-NEXT:    ret i32 1
 ;
   %v = lshr i32 2147483648, %x
   %cnt = call i32 @llvm.ctpop.i32(i32 %v)
@@ -129,9 +125,7 @@ define i64 @ctpop_x_and_negx_nz(i64 %x) {
 
 define <2 x i32> @ctpop_shl1_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @ctpop_shl1_vec(
-; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[X:%.*]]
-; CHECK-NEXT:    [[CNT:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[SHL]])
-; CHECK-NEXT:    ret <2 x i32> [[CNT]]
+; CHECK-NEXT:    ret <2 x i32> <i32 1, i32 1>
 ;
   %shl = shl <2 x i32> <i32 1 ,i32 1>, %x
   %cnt = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %shl)
@@ -151,9 +145,7 @@ define <2 x i32> @ctpop_shl2_1_vec(<2 x i32> %x) {
 
 define <2 x i32> @ctpop_lshr_intmin_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @ctpop_lshr_intmin_vec(
-; CHECK-NEXT:    [[SHR:%.*]] = lshr <2 x i32> <i32 -2147483648, i32 -2147483648>, [[X:%.*]]
-; CHECK-NEXT:    [[CNT:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[SHR]])
-; CHECK-NEXT:    ret <2 x i32> [[CNT]]
+; CHECK-NEXT:    ret <2 x i32> <i32 1, i32 1>
 ;
   %shr = lshr <2 x i32> <i32 2147483648 ,i32 2147483648>, %x
   %cnt = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %shr)


        


More information about the llvm-commits mailing list