[llvm] [DAG] Matched FixedWidth pattern for ISD::AVGFLOORU (PR #84903)
Shourya Goel via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 17 07:40:26 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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) {
>From 830ac3cf1daec2dd2d5098142da973227087b2b1 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Sun, 17 Mar 2024 20:10:06 +0530
Subject: [PATCH 12/12] nit
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 15c27162b1e1f2..94cd5f2d97cf77 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2820,7 +2820,7 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
return SDValue();
}
-// Attempt to form avgflooru(A, B) from add(and(A, B), lshr(xor(A, B), 1))
+// Attempt to form avgflooru(A, B) from (A & B) + ((A ^ B) >> 1)
static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
SDValue N0 = N->getOperand(0);
@@ -2834,6 +2834,7 @@ static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) {
return DAG.getNode(ISD::AVGFLOORU, DL, VT, A, B);
}
}
+ return SDValue();
}
SDValue DAGCombiner::visitADD(SDNode *N) {
More information about the llvm-commits
mailing list