[llvm] [DAG] Matched FixedWidth pattern for ISD::AVGFLOORU (PR #84903)
Shourya Goel via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 13 03:47:44 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 1/8] 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 2/8] 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 3/8] 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 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 5/8] 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 6/8] 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 7/8] 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 8/8] 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));
More information about the llvm-commits
mailing list