From 78f29acae6dc159660753ac91faefa390e2bad93 Mon Sep 17 00:00:00 2001 From: Noah Goldstein Date: Thu, 19 Jan 2023 11:02:26 -0800 Subject: [PATCH] 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 --- llvm/lib/Analysis/InstructionSimplify.cpp | 4 ++++ llvm/test/Transforms/InstSimplify/ctpop-pow2.ll | 16 ++++------------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 20a036c..3f3f6c6 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 caa605c..2711d36 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> , [[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> ; %shl = shl <2 x i32> , %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> , [[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> ; %shr = lshr <2 x i32> , %x %cnt = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %shr) -- 2.7.4