[llvm] [SelectionDAG] Add m_Neg and m_Not pattern matcher and update DAGCombiner (PR #85365)

via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 15 09:59:08 PDT 2024


https://github.com/ZiCong-Wang updated https://github.com/llvm/llvm-project/pull/85365

>From fac4e977dfc7a13d68a6c375377b824b2b0b0c1d Mon Sep 17 00:00:00 2001
From: ZiCong-Wang <wzcxd000103 at 163.com>
Date: Thu, 14 Mar 2024 15:40:10 +0000
Subject: [PATCH 1/3] Add m_Neg and m_Not pattern matcher and update
 DAGCombiner

---
 llvm/include/llvm/CodeGen/SDPatternMatch.h         | 14 ++++++++++++++
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp      |  6 +++---
 .../CodeGen/SelectionDAGPatternMatchTest.cpp       |  8 ++++++++
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SDPatternMatch.h b/llvm/include/llvm/CodeGen/SDPatternMatch.h
index a86c7400fa0945..2a475651b58a17 100644
--- a/llvm/include/llvm/CodeGen/SDPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/SDPatternMatch.h
@@ -705,6 +705,20 @@ inline auto m_False() {
       },
       m_Value()};
 }
+
+/// Match a negtive as a sub(0, v)
+template <typename ValTy>
+inline BinaryOpc_match<SpecificInt_match, ValTy>
+m_Neg(const ValTy &V) {
+  return m_Sub(m_Zero(), V);
+}
+
+/// Match a Not as a xor(v, 1) or xor(1, v)
+template <typename ValTy>
+inline BinaryOpc_match<SpecificInt_match, ValTy, true>
+m_Not(const ValTy &V) {
+  return m_Xor(m_AllOnes(), V);
+}
 } // namespace SDPatternMatch
 } // namespace llvm
 #endif
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 40b078a201ace6..df084b86087c32 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2703,11 +2703,11 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
   SDValue A, B, C;
 
   // fold ((0-A) + B) -> B-A
-  if (sd_match(N0, m_Sub(m_Zero(), m_Value(A))))
+  if (sd_match(N0, m_Neg(m_Value(A))))
     return DAG.getNode(ISD::SUB, DL, VT, N1, A);
 
   // fold (A + (0-B)) -> A-B
-  if (sd_match(N1, m_Sub(m_Zero(), m_Value(B))))
+  if (sd_match(N1, m_Neg(m_Value(B))))
     return DAG.getNode(ISD::SUB, DL, VT, N0, B);
 
   // fold (A+(B-A)) -> B
@@ -3812,7 +3812,7 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
     return DAG.getNode(ISD::AND, DL, VT, N0, DAG.getNOT(DL, B, VT));
 
   // fold (A - (-B * C)) -> (A + (B * C))
-  if (sd_match(N1, m_OneUse(m_Mul(m_Sub(m_Zero(), m_Value(B)), m_Value(C)))))
+  if (sd_match(N1, m_OneUse(m_Mul(m_Neg(m_Value(B)), m_Value(C)))))
     return DAG.getNode(ISD::ADD, DL, VT, N0,
                        DAG.getNode(ISD::MUL, DL, VT, B, C));
 
diff --git a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
index 2b764c9e1f0fd6..372431f3080c8c 100644
--- a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
+++ b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
@@ -174,10 +174,18 @@ TEST_F(SelectionDAGPatternMatchTest, matchUnaryOp) {
   SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op0);
   SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op1);
 
+  SDValue Zero = DAG->getConstant(0, DL, Int32VT);
+  SDValue AllOnes = DAG->getConstant(APInt::getAllOnes(32), DL, Int32VT);
+  SDValue Neg = DAG->getNode(ISD::SUB, DL, Int32VT, Zero, Op0);
+  SDValue Not = DAG->getNode(ISD::XOR, DL, Int32VT, AllOnes, Op0);
+
   using namespace SDPatternMatch;
   EXPECT_TRUE(sd_match(ZExt, m_UnaryOp(ISD::ZERO_EXTEND, m_Value())));
   EXPECT_TRUE(sd_match(SExt, m_SExt(m_Value())));
   EXPECT_TRUE(sd_match(Trunc, m_Trunc(m_Specific(Op1))));
+
+  EXPECT_TRUE(sd_match(Neg, m_Neg(m_Value())));
+  EXPECT_TRUE(sd_match(Not, m_Not(m_Value())));
 }
 
 TEST_F(SelectionDAGPatternMatchTest, matchConstants) {

>From 556b164f8acb072476ce1a1f9a94c49893f1ad75 Mon Sep 17 00:00:00 2001
From: ZiCong-Wang <wzcxd000103 at 163.com>
Date: Fri, 15 Mar 2024 12:16:49 +0000
Subject: [PATCH 2/3] Apply getNOT helper and reschedule operands in m_Not

---
 llvm/include/llvm/CodeGen/SDPatternMatch.h             | 10 ++++------
 .../unittests/CodeGen/SelectionDAGPatternMatchTest.cpp |  6 ++----
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SDPatternMatch.h b/llvm/include/llvm/CodeGen/SDPatternMatch.h
index 2a475651b58a17..1475ea3fa77b68 100644
--- a/llvm/include/llvm/CodeGen/SDPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/SDPatternMatch.h
@@ -708,16 +708,14 @@ inline auto m_False() {
 
 /// Match a negtive as a sub(0, v)
 template <typename ValTy>
-inline BinaryOpc_match<SpecificInt_match, ValTy>
-m_Neg(const ValTy &V) {
+inline BinaryOpc_match<SpecificInt_match, ValTy> m_Neg(const ValTy &V) {
   return m_Sub(m_Zero(), V);
 }
 
-/// Match a Not as a xor(v, 1) or xor(1, v)
+/// Match a Not as a xor(v, -1) or xor(-1, v)
 template <typename ValTy>
-inline BinaryOpc_match<SpecificInt_match, ValTy, true>
-m_Not(const ValTy &V) {
-  return m_Xor(m_AllOnes(), V);
+inline BinaryOpc_match<ValTy, SpecificInt_match, true> m_Not(const ValTy &V) {
+  return m_Xor(V, m_AllOnes());
 }
 } // namespace SDPatternMatch
 } // namespace llvm
diff --git a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
index 372431f3080c8c..efa97d782c4292 100644
--- a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
+++ b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
@@ -174,10 +174,8 @@ TEST_F(SelectionDAGPatternMatchTest, matchUnaryOp) {
   SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op0);
   SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op1);
 
-  SDValue Zero = DAG->getConstant(0, DL, Int32VT);
-  SDValue AllOnes = DAG->getConstant(APInt::getAllOnes(32), DL, Int32VT);
-  SDValue Neg = DAG->getNode(ISD::SUB, DL, Int32VT, Zero, Op0);
-  SDValue Not = DAG->getNode(ISD::XOR, DL, Int32VT, AllOnes, Op0);
+  SDValue Neg = DAG->getNegative(Op0, DL, Int32VT);
+  SDValue Not = DAG->getNOT(DL, Op0, Int32VT);
 
   using namespace SDPatternMatch;
   EXPECT_TRUE(sd_match(ZExt, m_UnaryOp(ISD::ZERO_EXTEND, m_Value())));

>From 904c9a9110c0a238dee45e26f3bb344446966a12 Mon Sep 17 00:00:00 2001
From: ZiCong-Wang <wzcxd000103 at 163.com>
Date: Fri, 15 Mar 2024 16:57:43 +0000
Subject: [PATCH 3/3] Add EXPECT_FALSE test

---
 llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
index efa97d782c4292..a0d0253a53f7bf 100644
--- a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
+++ b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
@@ -184,6 +184,9 @@ TEST_F(SelectionDAGPatternMatchTest, matchUnaryOp) {
 
   EXPECT_TRUE(sd_match(Neg, m_Neg(m_Value())));
   EXPECT_TRUE(sd_match(Not, m_Not(m_Value())));
+  EXPECT_FALSE(sd_match(Neg, m_Node(ISD::SUB, m_Value())));
+  EXPECT_FALSE(sd_match(Neg, m_Sub(m_Value(), m_Zero())));
+  EXPECT_FALSE(sd_match(Not, m_Xor(m_Value(), m_SpecificInt(54))));
 }
 
 TEST_F(SelectionDAGPatternMatchTest, matchConstants) {



More information about the llvm-commits mailing list