[llvm] fdcb271 - [InstCombine] Limit CTPOP -> CTTZ simplifications to one use

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 23 07:33:51 PDT 2020


Author: Simon Pilgrim
Date: 2020-03-23T14:33:41Z
New Revision: fdcb27105537f77c78c4473d4f7c47146ddbab69

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

LOG: [InstCombine] Limit CTPOP -> CTTZ simplifications to one use

Tweak D76568 so we only combine if it will remove the bit-twiddling.

Suggested by @spatel

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/test/Transforms/InstCombine/ctpop-cttz.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index b8d899df65ad..a234779ba24f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1333,7 +1333,8 @@ static Instruction *foldCtpop(IntrinsicInst &II, InstCombiner &IC) {
     return IC.replaceOperand(II, 0, X);
 
   // ctpop(x | -x) -> bitwidth - cttz(x, false)
-  if (match(Op0, m_c_Or(m_Value(X), m_Neg(m_Deferred(X))))) {
+  if (Op0->hasOneUse() &&
+      match(Op0, m_c_Or(m_Value(X), m_Neg(m_Deferred(X))))) {
     Function *F =
         Intrinsic::getDeclaration(II.getModule(), Intrinsic::cttz, Ty);
     auto *Cttz = IC.Builder.CreateCall(F, {X, IC.Builder.getFalse()});
@@ -1342,7 +1343,8 @@ static Instruction *foldCtpop(IntrinsicInst &II, InstCombiner &IC) {
   }
 
   // ctpop(~x & (x - 1)) -> cttz(x, false)
-  if (match(Op0,
+  if (Op0->hasOneUse() &&
+      match(Op0,
             m_c_And(m_Not(m_Value(X)), m_Add(m_Deferred(X), m_AllOnes())))) {
     Function *F =
         Intrinsic::getDeclaration(II.getModule(), Intrinsic::cttz, Ty);

diff  --git a/llvm/test/Transforms/InstCombine/ctpop-cttz.ll b/llvm/test/Transforms/InstCombine/ctpop-cttz.ll
index 15244d212dfb..f1fe9384e3fe 100644
--- a/llvm/test/Transforms/InstCombine/ctpop-cttz.ll
+++ b/llvm/test/Transforms/InstCombine/ctpop-cttz.ll
@@ -30,6 +30,23 @@ define <2 x i32> @ctpop1v(<2 x i32> %0) {
   ret <2 x i32> %4
 }
 
+define i32 @ctpop1_multiuse(i32 %0) {
+; CHECK-LABEL: @ctpop1_multiuse(
+; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 0, [[TMP0:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = or i32 [[TMP2]], [[TMP0]]
+; CHECK-NEXT:    [[TMP4:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[TMP3]]), !range !0
+; CHECK-NEXT:    [[TMP5:%.*]] = sub nuw nsw i32 32, [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = add i32 [[TMP5]], [[TMP3]]
+; CHECK-NEXT:    ret i32 [[TMP6]]
+;
+  %2 = sub i32 0, %0
+  %3 = or i32 %0, %2
+  %4 = tail call i32 @llvm.ctpop.i32(i32 %3)
+  %5 = sub i32 32, %4
+  %6 = add i32 %5, %3
+  ret i32 %6
+}
+
 ; PR43513
 ; __builtin_popcount(~i & (i-1)) -> __builtin_cttz(i, false)
 define i32 @ctpop2(i32 %0) {
@@ -55,3 +72,20 @@ define <2 x i32> @ctpop2v(<2 x i32> %0) {
   %5 = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %4)
   ret <2 x i32> %5
 }
+
+define i32 @ctpop2_multiuse(i32 %0) {
+; CHECK-LABEL: @ctpop2_multiuse(
+; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP0:%.*]], -1
+; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[TMP0]], -1
+; CHECK-NEXT:    [[TMP4:%.*]] = and i32 [[TMP3]], [[TMP2]]
+; CHECK-NEXT:    [[TMP5:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[TMP4]]), !range !0
+; CHECK-NEXT:    [[TMP6:%.*]] = add i32 [[TMP5]], [[TMP4]]
+; CHECK-NEXT:    ret i32 [[TMP6]]
+;
+  %2 = xor i32 %0, -1
+  %3 = sub i32 %0, 1
+  %4 = and i32 %3, %2
+  %5 = tail call i32 @llvm.ctpop.i32(i32 %4)
+  %6 = add i32 %5, %4
+  ret i32 %6
+}


        


More information about the llvm-commits mailing list