[llvm] [InstCombine] Add ctpop(A | B) + ctpop(A & B) -> ctpop(A) + ctpop(B) (PR #79089)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 22 20:00:34 PST 2024


https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/79089

>From 8cd2cfe40c4a9df0c1fed272479a2ad32a7e0f71 Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Mon, 22 Jan 2024 22:06:36 -0500
Subject: [PATCH 1/4] [InstCombine] Add pre-commit tests (NFC)

---
 llvm/test/Transforms/InstCombine/ctpop.ll | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/ctpop.ll b/llvm/test/Transforms/InstCombine/ctpop.ll
index dcea5fa87479eb..63169f1e6f8f28 100644
--- a/llvm/test/Transforms/InstCombine/ctpop.ll
+++ b/llvm/test/Transforms/InstCombine/ctpop.ll
@@ -264,6 +264,23 @@ define <2 x i32> @ctpop_add_no_common_bits_vec_use2(<2 x i32> %a, <2 x i32> %b,
   ret <2 x i32> %res
 }
 
+define i32 @ctpop_and_or_combine(i32 %a, i32 %b) {
+; CHECK-LABEL: @ctpop_and_or_combine(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[CTPOP1:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[AND]]), !range [[RNG1]]
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A]], [[B]]
+; CHECK-NEXT:    [[CTPOP2:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[OR]]), !range [[RNG1]]
+; CHECK-NEXT:    [[RES:%.*]] = add nuw nsw i32 [[CTPOP1]], [[CTPOP2]]
+; CHECK-NEXT:    ret i32 [[RES]]
+;
+  %and = and i32 %a, %b
+  %ctpop1 = tail call i32 @llvm.ctpop.i32(i32 %and)
+  %or = or i32 %a, %b
+  %ctpop2 = tail call i32 @llvm.ctpop.i32(i32 %or)
+  %res = add nuw nsw i32 %ctpop1, %ctpop2
+  ret i32 %res
+}
+
 define i8 @ctpop_rotate_left(i8 %a, i8 %amt)  {
 ; CHECK-LABEL: @ctpop_rotate_left(
 ; CHECK-NEXT:    [[RES:%.*]] = tail call i8 @llvm.ctpop.i8(i8 [[A:%.*]]), !range [[RNG0]]

>From 5146e1f4774370339e3d0b4be42fef68bb51bb24 Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Mon, 22 Jan 2024 20:38:11 -0500
Subject: [PATCH 2/4] [InstCombine] Add ctpop(A | B) + ctpop(A & B) -> ctpop(A)
 + ctpop(B)

---
 .../InstCombine/InstCombineAddSub.cpp         | 19 +++++++++++++++++++
 llvm/test/Transforms/InstCombine/ctpop.ll     |  8 +++-----
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 8a00b75a1f7404..d8ef770d6fcef0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1718,6 +1718,25 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
         Builder.CreateIntrinsic(Intrinsic::umax, {I.getType()}, {A, B}));
   }
 
+  // ctpop(A | B) + ctpop(A & B) -> ctpop(A) + ctpop(B)
+  if ((match(LHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
+                      m_And(m_Value(A), m_Value(B))))) &&
+       (match(RHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
+                       m_Or(m_Specific(A), m_Specific(B))))) ||
+        match(RHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
+                       m_Or(m_Specific(B), m_Specific(A))))))) ||
+      (match(LHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
+                      m_Or(m_Value(A), m_Value(B))))) &&
+       (match(RHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
+                       m_And(m_Specific(A), m_Specific(B))))) ||
+        match(RHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
+                       m_And(m_Specific(B), m_Specific(A)))))))) {
+    return replaceInstUsesWith(
+        I, Builder.CreateAdd(
+               Builder.CreateIntrinsic(Intrinsic::ctpop, {A->getType()}, {A}),
+               Builder.CreateIntrinsic(Intrinsic::ctpop, {B->getType()}, {B})));
+  }
+
   // ctpop(A) + ctpop(B) => ctpop(A | B) if A and B have no bits set in common.
   if (match(LHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(m_Value(A)))) &&
       match(RHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(m_Value(B)))) &&
diff --git a/llvm/test/Transforms/InstCombine/ctpop.ll b/llvm/test/Transforms/InstCombine/ctpop.ll
index 63169f1e6f8f28..6dd8faf65a6ff8 100644
--- a/llvm/test/Transforms/InstCombine/ctpop.ll
+++ b/llvm/test/Transforms/InstCombine/ctpop.ll
@@ -266,11 +266,9 @@ define <2 x i32> @ctpop_add_no_common_bits_vec_use2(<2 x i32> %a, <2 x i32> %b,
 
 define i32 @ctpop_and_or_combine(i32 %a, i32 %b) {
 ; CHECK-LABEL: @ctpop_and_or_combine(
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[CTPOP1:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[AND]]), !range [[RNG1]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A]], [[B]]
-; CHECK-NEXT:    [[CTPOP2:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[OR]]), !range [[RNG1]]
-; CHECK-NEXT:    [[RES:%.*]] = add nuw nsw i32 [[CTPOP1]], [[CTPOP2]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]]), !range [[RNG1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.ctpop.i32(i32 [[B:%.*]]), !range [[RNG1]]
+; CHECK-NEXT:    [[RES:%.*]] = add nuw nsw i32 [[TMP1]], [[TMP2]]
 ; CHECK-NEXT:    ret i32 [[RES]]
 ;
   %and = and i32 %a, %b

>From ef94d60a44b4d42956009796f4e916e699d20b39 Mon Sep 17 00:00:00 2001
From: AtariDreams <83477269+AtariDreams at users.noreply.github.com>
Date: Mon, 22 Jan 2024 23:00:18 -0500
Subject: [PATCH 3/4] Update
 llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Co-authored-by: Yingwei Zheng <dtcxzyw at qq.com>
---
 .../Transforms/InstCombine/InstCombineAddSub.cpp  | 15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index d8ef770d6fcef0..9be3a228c65d40 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1719,18 +1719,9 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
   }
 
   // ctpop(A | B) + ctpop(A & B) -> ctpop(A) + ctpop(B)
-  if ((match(LHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
-                      m_And(m_Value(A), m_Value(B))))) &&
-       (match(RHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
-                       m_Or(m_Specific(A), m_Specific(B))))) ||
-        match(RHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
-                       m_Or(m_Specific(B), m_Specific(A))))))) ||
-      (match(LHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
-                      m_Or(m_Value(A), m_Value(B))))) &&
-       (match(RHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
-                       m_And(m_Specific(A), m_Specific(B))))) ||
-        match(RHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
-                       m_And(m_Specific(B), m_Specific(A)))))))) {
+  if (match(&I, m_c_Add(m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
+                       m_And(m_Value(A), m_Value(B))))), mOneUse(m_Intrinsic<Intrinsic::ctpop>(
+                       m_c_Or(m_Specific(A), m_Specific(B)))))))) {
     return replaceInstUsesWith(
         I, Builder.CreateAdd(
                Builder.CreateIntrinsic(Intrinsic::ctpop, {A->getType()}, {A}),

>From 6528ccbd8c584017390eb829987c1d1d4c8852bd Mon Sep 17 00:00:00 2001
From: AtariDreams <83477269+AtariDreams at users.noreply.github.com>
Date: Mon, 22 Jan 2024 23:00:27 -0500
Subject: [PATCH 4/4] Update
 llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Co-authored-by: Yingwei Zheng <dtcxzyw at qq.com>
---
 llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 9be3a228c65d40..72d0bf475acac6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1722,10 +1722,9 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
   if (match(&I, m_c_Add(m_OneUse(m_Intrinsic<Intrinsic::ctpop>(
                        m_And(m_Value(A), m_Value(B))))), mOneUse(m_Intrinsic<Intrinsic::ctpop>(
                        m_c_Or(m_Specific(A), m_Specific(B)))))))) {
-    return replaceInstUsesWith(
-        I, Builder.CreateAdd(
-               Builder.CreateIntrinsic(Intrinsic::ctpop, {A->getType()}, {A}),
-               Builder.CreateIntrinsic(Intrinsic::ctpop, {B->getType()}, {B})));
+    return BinaryOperator::CreateAdd(
+               Builder.CreateUnaryIntrinsic(Intrinsic::ctpop, A),
+               Builder.CreateUnaryIntrinsic(Intrinsic::ctpop, B));
   }
 
   // ctpop(A) + ctpop(B) => ctpop(A | B) if A and B have no bits set in common.



More information about the llvm-commits mailing list