[llvm] [DAG] Matched FixedWidth pattern for ISD::AVGFLOORU (PR #84903)

Shourya Goel via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 16 04:56:34 PDT 2024


https://github.com/Sh0g0-1758 updated https://github.com/llvm/llvm-project/pull/84903

>From f24f2515ac6fadcb4bab54b5a3d5613ba72f295b Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Tue, 12 Mar 2024 15:05:36 +0530
Subject: [PATCH 01/11] Matched some basic ISD::AVGFLOORU patterns

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 34 +++++++++++++++++++
 llvm/test/CodeGen/AArch64/hadd-combine.ll     | 15 ++++++++
 2 files changed, 49 insertions(+)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 5476ef87971436..c721db178a0dff 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2826,6 +2826,36 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
   return SDValue();
 }
 
+// Attempt to form ext(avgflooru(A, B)) from add(and(A, B), lshr(xor(A, B), 1))
+static SDValue combineFixedwidthToAVG(SDNode *N, SelectionDAG &DAG) {
+  assert(N->getOpcode() == ISD::ADD && "ADD node is required here");
+  SDValue And = N->getOperand(0);
+  SDValue Lshr = N->getOperand(1);
+  if (And.getOpcode() != ISD::AND || Lshr.getOpcode() != ISD::SRL)
+    return SDValue();
+  SDValue Xor = Lshr.getOperand(0);
+  if (Xor.getOpcode() != ISD::XOR)
+    return SDValue();
+  SDValue And1 = And.getOperand(0);
+  SDValue And2 = And.getOperand(1);
+  SDValue Xor1 = Xor.getOperand(0);
+  SDValue Xor2 = Xor.getOperand(1);
+  if (Xor1 != And1 && Xor2 != And2)
+    return SDValue();
+  // Is the right shift using an immediate value of 1?
+  ConstantSDNode *N1C = isConstOrConstSplat(Lshr.getOperand(1));
+  if (!N1C || N1C->getAPIntValue() != 1)
+    return SDValue();
+  EVT VT = And.getValueType();
+  SDLoc DL(N);
+  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+  if (!TLI.isOperationLegalOrCustom(ISD::AVGFLOORU, VT))
+    return SDValue();
+  return DAG.getNode(ISD::AVGFLOORU, DL, VT,
+                     DAG.getExtOrTrunc(false, And1, DL, VT),
+                     DAG.getExtOrTrunc(false, And2, DL, VT));
+}
+
 SDValue DAGCombiner::visitADD(SDNode *N) {
   SDValue N0 = N->getOperand(0);
   SDValue N1 = N->getOperand(1);
@@ -2841,6 +2871,10 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
   if (SDValue V = foldAddSubOfSignBit(N, DAG))
     return V;
 
+  // Try to match AVG fixedwidth pattern
+  if (SDValue V = combineFixedwidthToAVG(N, DAG))
+    return V;
+
   // fold (a+b) -> (a|b) iff a and b share no bits.
   if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) &&
       DAG.haveNoCommonBitsSet(N0, N1))
diff --git a/llvm/test/CodeGen/AArch64/hadd-combine.ll b/llvm/test/CodeGen/AArch64/hadd-combine.ll
index 2269d75cdbb9ed..8806caa676c8af 100644
--- a/llvm/test/CodeGen/AArch64/hadd-combine.ll
+++ b/llvm/test/CodeGen/AArch64/hadd-combine.ll
@@ -859,6 +859,21 @@ define <4 x i32> @urhadd_v4i32(<4 x i32> %x) {
   ret <4 x i32> %r
 }
 
+define i4 @fixedwidth(i4 %a0, i4 %a1)  {
+; CHECK-LABEL: fixedwidth:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    eor w8, w0, w1
+; CHECK-NEXT:    and w9, w0, w1
+; CHECK-NEXT:    and w8, w8, #0xe
+; CHECK-NEXT:    add w0, w9, w8, lsr #1
+; CHECK-NEXT:    ret
+  %and = and i4 %a0, %a1
+  %xor = xor i4 %a0, %a1
+  %srl = lshr i4 %xor, 1
+  %res = add i4 %and, %srl
+  ret i4 %res
+}
+
 declare <8 x i8> @llvm.aarch64.neon.shadd.v8i8(<8 x i8>, <8 x i8>)
 declare <4 x i16> @llvm.aarch64.neon.shadd.v4i16(<4 x i16>, <4 x i16>)
 declare <2 x i32> @llvm.aarch64.neon.shadd.v2i32(<2 x i32>, <2 x i32>)

>From c2f47d6af35972b38fda17d59ff9528298ff5997 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Tue, 12 Mar 2024 23:35:34 +0530
Subject: [PATCH 02/11] Shifted Tests to vector types

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  2 ++
 llvm/test/CodeGen/AArch64/hadd-combine.ll     | 20 +++++++++----------
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c721db178a0dff..9e4db814e89493 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2847,6 +2847,8 @@ static SDValue combineFixedwidthToAVG(SDNode *N, SelectionDAG &DAG) {
   if (!N1C || N1C->getAPIntValue() != 1)
     return SDValue();
   EVT VT = And.getValueType();
+  if (VT.isVector())
+    return SDValue();
   SDLoc DL(N);
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
   if (!TLI.isOperationLegalOrCustom(ISD::AVGFLOORU, VT))
diff --git a/llvm/test/CodeGen/AArch64/hadd-combine.ll b/llvm/test/CodeGen/AArch64/hadd-combine.ll
index 8806caa676c8af..3f9bd2baa3e114 100644
--- a/llvm/test/CodeGen/AArch64/hadd-combine.ll
+++ b/llvm/test/CodeGen/AArch64/hadd-combine.ll
@@ -859,19 +859,19 @@ define <4 x i32> @urhadd_v4i32(<4 x i32> %x) {
   ret <4 x i32> %r
 }
 
-define i4 @fixedwidth(i4 %a0, i4 %a1)  {
+define <4 x i32> @fixedwidth(<4 x i32> %a0, <4 x i32> %a1)  {
 ; CHECK-LABEL: fixedwidth:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    eor w8, w0, w1
-; CHECK-NEXT:    and w9, w0, w1
-; CHECK-NEXT:    and w8, w8, #0xe
-; CHECK-NEXT:    add w0, w9, w8, lsr #1
+; CHECK-NEXT:    and v2.16b, v0.16b, v1.16b
+; CHECK-NEXT:    eor v0.16b, v0.16b, v1.16b
+; CHECK-NEXT:    usra v2.4s, v0.4s, #1
+; CHECK-NEXT:    mov v0.16b, v2.16b
 ; CHECK-NEXT:    ret
-  %and = and i4 %a0, %a1
-  %xor = xor i4 %a0, %a1
-  %srl = lshr i4 %xor, 1
-  %res = add i4 %and, %srl
-  ret i4 %res
+  %and = and <4 x i32> %a0, %a1
+  %xor = xor <4 x i32> %a0, %a1
+  %srl = lshr <4 x i32> %xor, <i32 1,i32 1,i32 1,i32 1>
+  %res = add <4 x i32> %and, %srl
+  ret <4 x i32> %res
 }
 
 declare <8 x i8> @llvm.aarch64.neon.shadd.v8i8(<8 x i8>, <8 x i8>)

>From 93c93058afc508e1ad59c915cfb4a378cf4500cc Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 13 Mar 2024 05:17:27 +0530
Subject: [PATCH 03/11] Implement Correct Matching Logic

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 11 ++++++-----
 llvm/test/CodeGen/AArch64/hadd-combine.ll     | 19 +++++++++++++++++--
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index a300349f974fe9..c6b174e8a11c7c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2841,16 +2841,17 @@ static SDValue combineFixedwidthToAVG(SDNode *N, SelectionDAG &DAG) {
   ConstantSDNode *N1C = isConstOrConstSplat(Lshr.getOperand(1));
   if (!N1C || N1C->getAPIntValue() != 1)
     return SDValue();
-  EVT VT = And.getValueType();
+  EVT VT = And1.getValueType();
+  EVT NVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
   if (VT.isVector())
-    return SDValue();
+    VT = EVT::getVectorVT(*DAG.getContext(), NVT, VT.getVectorElementCount());
+  else
+    VT = NVT;
   SDLoc DL(N);
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
   if (!TLI.isOperationLegalOrCustom(ISD::AVGFLOORU, VT))
     return SDValue();
-  return DAG.getNode(ISD::AVGFLOORU, DL, VT,
-                     DAG.getExtOrTrunc(false, And1, DL, VT),
-                     DAG.getExtOrTrunc(false, And2, DL, VT));
+  return DAG.getNode(ISD::AVGFLOORU, DL, VT, And1, And2);
 }
 
 SDValue DAGCombiner::visitADD(SDNode *N) {
diff --git a/llvm/test/CodeGen/AArch64/hadd-combine.ll b/llvm/test/CodeGen/AArch64/hadd-combine.ll
index 3f9bd2baa3e114..4a576a3b7789a2 100644
--- a/llvm/test/CodeGen/AArch64/hadd-combine.ll
+++ b/llvm/test/CodeGen/AArch64/hadd-combine.ll
@@ -859,8 +859,23 @@ define <4 x i32> @urhadd_v4i32(<4 x i32> %x) {
   ret <4 x i32> %r
 }
 
-define <4 x i32> @fixedwidth(<4 x i32> %a0, <4 x i32> %a1)  {
-; CHECK-LABEL: fixedwidth:
+define i4 @uhadd_fixedwidth_i4(i4 %a0, i4 %a1)  {
+; CHECK-LABEL: uhadd_fixedwidth_i4:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    eor w8, w0, w1
+; CHECK-NEXT:    and w9, w0, w1
+; CHECK-NEXT:    and w8, w8, #0xe
+; CHECK-NEXT:    add w0, w9, w8, lsr #1
+; CHECK-NEXT:    ret
+  %and = and i4 %a0, %a1
+  %xor = xor i4 %a0, %a1
+  %srl = lshr i4 %xor, 1
+  %res = add i4 %and, %srl
+  ret i4 %res
+}
+
+define <4 x i32> @uhadd_fixedwidth_v4i32(<4 x i32> %a0, <4 x i32> %a1)  {
+; CHECK-LABEL: uhadd_fixedwidth_v4i32:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    and v2.16b, v0.16b, v1.16b
 ; CHECK-NEXT:    eor v0.16b, v0.16b, v1.16b

>From 194fd2841107515eec29b5a1a7e4e8f140186e27 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 13 Mar 2024 05:26:53 +0530
Subject: [PATCH 04/11] Checking


>From 46c23cb7201c2fe25e53c067fcaad49405fa2e40 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 13 Mar 2024 11:31:07 +0530
Subject: [PATCH 05/11] Renamed Function

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c6b174e8a11c7c..771fe982abac8e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2822,7 +2822,7 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
 }
 
 // Attempt to form ext(avgflooru(A, B)) from add(and(A, B), lshr(xor(A, B), 1))
-static SDValue combineFixedwidthToAVG(SDNode *N, SelectionDAG &DAG) {
+static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
   assert(N->getOpcode() == ISD::ADD && "ADD node is required here");
   SDValue And = N->getOperand(0);
   SDValue Lshr = N->getOperand(1);
@@ -2869,8 +2869,8 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
   if (SDValue V = foldAddSubOfSignBit(N, DAG))
     return V;
 
-  // Try to match AVG fixedwidth pattern
-  if (SDValue V = combineFixedwidthToAVG(N, DAG))
+  // Try to match AVGFLOORU fixedwidth pattern
+  if (SDValue V = combineFixedwidthToAVGFLOORU(N, DAG))
     return V;
 
   // fold (a+b) -> (a|b) iff a and b share no bits.

>From ed3aae85d517a5ab234fab06a4d87465f05a1acb Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 13 Mar 2024 12:19:22 +0530
Subject: [PATCH 06/11] Fixed minor bug

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 771fe982abac8e..51d90d372bc3ab 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2823,10 +2823,10 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
 
 // Attempt to form ext(avgflooru(A, B)) from add(and(A, B), lshr(xor(A, B), 1))
 static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
-  assert(N->getOpcode() == ISD::ADD && "ADD node is required here");
+  assert(N->getOpcode() == ISD::ADD and "ADD node is required here");
   SDValue And = N->getOperand(0);
   SDValue Lshr = N->getOperand(1);
-  if (And.getOpcode() != ISD::AND || Lshr.getOpcode() != ISD::SRL)
+  if (And.getOpcode() != ISD::AND or Lshr.getOpcode() != ISD::SRL)
     return SDValue();
   SDValue Xor = Lshr.getOperand(0);
   if (Xor.getOpcode() != ISD::XOR)
@@ -2835,11 +2835,11 @@ static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
   SDValue And2 = And.getOperand(1);
   SDValue Xor1 = Xor.getOperand(0);
   SDValue Xor2 = Xor.getOperand(1);
-  if (Xor1 != And1 && Xor2 != And2)
+  if (Xor1 != And1 or Xor2 != And2)
     return SDValue();
   // Is the right shift using an immediate value of 1?
   ConstantSDNode *N1C = isConstOrConstSplat(Lshr.getOperand(1));
-  if (!N1C || N1C->getAPIntValue() != 1)
+  if (!N1C or N1C->getAPIntValue() != 1)
     return SDValue();
   EVT VT = And1.getValueType();
   EVT NVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());

>From 766caedb244dd01372a828bf9964db7553de1ded Mon Sep 17 00:00:00 2001
From: Shourya Goel <shouryagoel10000 at gmail.com>
Date: Wed, 13 Mar 2024 15:48:57 +0530
Subject: [PATCH 07/11] Removed ext

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 51d90d372bc3ab..6eabfd84b8be1e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2821,7 +2821,7 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
   return SDValue();
 }
 
-// Attempt to form ext(avgflooru(A, B)) from add(and(A, B), lshr(xor(A, B), 1))
+// Attempt to form avgflooru(A, B) from add(and(A, B), lshr(xor(A, B), 1))
 static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
   assert(N->getOpcode() == ISD::ADD and "ADD node is required here");
   SDValue And = N->getOperand(0);

>From 93653177f96e2e62496aa9ca7eb5abe5dac9eed5 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 13 Mar 2024 16:17:24 +0530
Subject: [PATCH 08/11] Commutative logic

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 6eabfd84b8be1e..6a9587ec726f3c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2826,7 +2826,11 @@ static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
   assert(N->getOpcode() == ISD::ADD and "ADD node is required here");
   SDValue And = N->getOperand(0);
   SDValue Lshr = N->getOperand(1);
-  if (And.getOpcode() != ISD::AND or Lshr.getOpcode() != ISD::SRL)
+  if (And.getOpcode() == ISD::SRL and Lshr.getOpcode() == ISD::AND) {
+    SDValue temp = And;
+    And = Lshr;
+    Lshr = temp;
+  } else if (And.getOpcode() != ISD::AND or Lshr.getOpcode() != ISD::SRL)
     return SDValue();
   SDValue Xor = Lshr.getOperand(0);
   if (Xor.getOpcode() != ISD::XOR)
@@ -2835,7 +2839,11 @@ static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
   SDValue And2 = And.getOperand(1);
   SDValue Xor1 = Xor.getOperand(0);
   SDValue Xor2 = Xor.getOperand(1);
-  if (Xor1 != And1 or Xor2 != And2)
+  if (And1 == Xor2 and And2 == Xor1) {
+    SDValue temp = And1;
+    And1 = And2;
+    And2 = temp;
+  } else if (And1 != Xor1 or And2 != Xor2)
     return SDValue();
   // Is the right shift using an immediate value of 1?
   ConstantSDNode *N1C = isConstOrConstSplat(Lshr.getOperand(1));

>From 00986c49b3fe4cd2806d1422f61f34fc798c28d9 Mon Sep 17 00:00:00 2001
From: Shourya Goel <shouryagoel10000 at gmail.com>
Date: Wed, 13 Mar 2024 16:25:20 +0530
Subject: [PATCH 09/11] Replaced and with && and similar changes

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 6a9587ec726f3c..1dab97318215fc 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2823,14 +2823,14 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
 
 // Attempt to form avgflooru(A, B) from add(and(A, B), lshr(xor(A, B), 1))
 static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
-  assert(N->getOpcode() == ISD::ADD and "ADD node is required here");
+  assert(N->getOpcode() == ISD::ADD && "ADD node is required here");
   SDValue And = N->getOperand(0);
   SDValue Lshr = N->getOperand(1);
-  if (And.getOpcode() == ISD::SRL and Lshr.getOpcode() == ISD::AND) {
+  if (And.getOpcode() == ISD::SRL && Lshr.getOpcode() == ISD::AND) {
     SDValue temp = And;
     And = Lshr;
     Lshr = temp;
-  } else if (And.getOpcode() != ISD::AND or Lshr.getOpcode() != ISD::SRL)
+  } else if (And.getOpcode() != ISD::AND || Lshr.getOpcode() != ISD::SRL)
     return SDValue();
   SDValue Xor = Lshr.getOperand(0);
   if (Xor.getOpcode() != ISD::XOR)
@@ -2839,11 +2839,11 @@ static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
   SDValue And2 = And.getOperand(1);
   SDValue Xor1 = Xor.getOperand(0);
   SDValue Xor2 = Xor.getOperand(1);
-  if (And1 == Xor2 and And2 == Xor1) {
+  if (And1 == Xor2 && And2 == Xor1) {
     SDValue temp = And1;
     And1 = And2;
     And2 = temp;
-  } else if (And1 != Xor1 or And2 != Xor2)
+  } else if (And1 != Xor1 || And2 != Xor2)
     return SDValue();
   // Is the right shift using an immediate value of 1?
   ConstantSDNode *N1C = isConstOrConstSplat(Lshr.getOperand(1));

>From eb994e0f3339c89e2041a965df0d36b3a0386795 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 14 Mar 2024 21:55:06 +0530
Subject: [PATCH 10/11] Changed VT

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  5 ---
 llvm/test/CodeGen/AArch64/hadd-combine.ll     | 32 ++++---------------
 2 files changed, 7 insertions(+), 30 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 1dab97318215fc..7486104c584b5e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2850,11 +2850,6 @@ static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
   if (!N1C or N1C->getAPIntValue() != 1)
     return SDValue();
   EVT VT = And1.getValueType();
-  EVT NVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
-  if (VT.isVector())
-    VT = EVT::getVectorVT(*DAG.getContext(), NVT, VT.getVectorElementCount());
-  else
-    VT = NVT;
   SDLoc DL(N);
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
   if (!TLI.isOperationLegalOrCustom(ISD::AVGFLOORU, VT))
diff --git a/llvm/test/CodeGen/AArch64/hadd-combine.ll b/llvm/test/CodeGen/AArch64/hadd-combine.ll
index 4a576a3b7789a2..b035ba03529ccc 100644
--- a/llvm/test/CodeGen/AArch64/hadd-combine.ll
+++ b/llvm/test/CodeGen/AArch64/hadd-combine.ll
@@ -859,34 +859,16 @@ define <4 x i32> @urhadd_v4i32(<4 x i32> %x) {
   ret <4 x i32> %r
 }
 
-define i4 @uhadd_fixedwidth_i4(i4 %a0, i4 %a1)  {
-; CHECK-LABEL: uhadd_fixedwidth_i4:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    eor w8, w0, w1
-; CHECK-NEXT:    and w9, w0, w1
-; CHECK-NEXT:    and w8, w8, #0xe
-; CHECK-NEXT:    add w0, w9, w8, lsr #1
-; CHECK-NEXT:    ret
-  %and = and i4 %a0, %a1
-  %xor = xor i4 %a0, %a1
-  %srl = lshr i4 %xor, 1
-  %res = add i4 %and, %srl
-  ret i4 %res
-}
-
-define <4 x i32> @uhadd_fixedwidth_v4i32(<4 x i32> %a0, <4 x i32> %a1)  {
+define <8 x i16> @uhadd_fixedwidth_v4i32(<8 x i16> %a0, <8 x i16> %a1)  {
 ; CHECK-LABEL: uhadd_fixedwidth_v4i32:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    and v2.16b, v0.16b, v1.16b
-; CHECK-NEXT:    eor v0.16b, v0.16b, v1.16b
-; CHECK-NEXT:    usra v2.4s, v0.4s, #1
-; CHECK-NEXT:    mov v0.16b, v2.16b
+; CHECK-NEXT:    uhadd v0.8h, v0.8h, v1.8h
 ; CHECK-NEXT:    ret
-  %and = and <4 x i32> %a0, %a1
-  %xor = xor <4 x i32> %a0, %a1
-  %srl = lshr <4 x i32> %xor, <i32 1,i32 1,i32 1,i32 1>
-  %res = add <4 x i32> %and, %srl
-  ret <4 x i32> %res
+  %and = and <8 x i16> %a0, %a1
+  %xor = xor <8 x i16> %a0, %a1
+  %srl = lshr <8 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+  %res = add <8 x i16> %and, %srl
+  ret <8 x i16> %res
 }
 
 declare <8 x i8> @llvm.aarch64.neon.shadd.v8i8(<8 x i8>, <8 x i8>)

>From e7dc0c01c40eba02a60bbd8d6ed1a3107b6f13af Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Sat, 16 Mar 2024 17:25:55 +0530
Subject: [PATCH 11/11] Modified with sd_match pattern helper

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 42 +++++--------------
 1 file changed, 11 insertions(+), 31 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index fed50d7a73559f..15c27162b1e1f2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2822,38 +2822,18 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
 
 // Attempt to form avgflooru(A, B) from add(and(A, B), lshr(xor(A, B), 1))
 static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
-  assert(N->getOpcode() == ISD::ADD && "ADD node is required here");
-  SDValue And = N->getOperand(0);
-  SDValue Lshr = N->getOperand(1);
-  if (And.getOpcode() == ISD::SRL && Lshr.getOpcode() == ISD::AND) {
-    SDValue temp = And;
-    And = Lshr;
-    Lshr = temp;
-  } else if (And.getOpcode() != ISD::AND || Lshr.getOpcode() != ISD::SRL)
-    return SDValue();
-  SDValue Xor = Lshr.getOperand(0);
-  if (Xor.getOpcode() != ISD::XOR)
-    return SDValue();
-  SDValue And1 = And.getOperand(0);
-  SDValue And2 = And.getOperand(1);
-  SDValue Xor1 = Xor.getOperand(0);
-  SDValue Xor2 = Xor.getOperand(1);
-  if (And1 == Xor2 && And2 == Xor1) {
-    SDValue temp = And1;
-    And1 = And2;
-    And2 = temp;
-  } else if (And1 != Xor1 || And2 != Xor2)
-    return SDValue();
-  // Is the right shift using an immediate value of 1?
-  ConstantSDNode *N1C = isConstOrConstSplat(Lshr.getOperand(1));
-  if (!N1C or N1C->getAPIntValue() != 1)
-    return SDValue();
-  EVT VT = And1.getValueType();
-  SDLoc DL(N);
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
-  if (!TLI.isOperationLegalOrCustom(ISD::AVGFLOORU, VT))
-    return SDValue();
-  return DAG.getNode(ISD::AVGFLOORU, DL, VT, And1, And2);
+  SDValue N0 = N->getOperand(0);
+  EVT VT = N0.getValueType();
+  SDLoc DL(N);
+  if (TLI.isOperationLegal(ISD::AVGFLOORU, VT)) {
+    SDValue A, B;
+    if (sd_match(N, m_Add(m_And(m_Value(A), m_Value(B)),
+                          m_Srl(m_Xor(m_Deferred(A), m_Deferred(B)),
+                                m_SpecificInt(1))))) {
+      return DAG.getNode(ISD::AVGFLOORU, DL, VT, A, B);
+    }
+  }
 }
 
 SDValue DAGCombiner::visitADD(SDNode *N) {



More information about the llvm-commits mailing list