[llvm] [RISCV] Combine chained `V[SZ]EXT_VL` ops (PR #211583)
Sean Clarke via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 28 07:21:44 PDT 2026
https://github.com/xarkenz updated https://github.com/llvm/llvm-project/pull/211583
>From ad805eed9f8a850e271f865ee5d625512ed5bb06 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Wed, 22 Jul 2026 17:01:56 -0500
Subject: [PATCH 1/4] Add combine for nested V[SZ]EXT_VL
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 29 +++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 37505a5b187f8..157b67eaef388 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20702,6 +20702,32 @@ static SDValue performVFMADD_VLCombine(SDNode *N,
return combineOp_VLToVWOp_VL(N, DCI, Subtarget);
}
+static SDValue performVEXT_VLCombine(SDNode *N,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const RISCVSubtarget &Subtarget) {
+ SDValue Inner = N->getOperand(0);
+ SDValue Mask = N->getOperand(1);
+ SDValue VL = N->getOperand(2);
+
+ // Combine (vext_vl (vext_vl x, m, vl), m, vl) -> (vext_vl x, m, vl)
+ // where vext_vl is either vsext_vl or vzext_vl.
+ using namespace SDPatternMatch;
+ SDValue Src;
+ if (!sd_match(Inner, m_OneUse(m_Node(N->getOpcode(), m_Value(Src),
+ m_Specific(Mask), m_Specific(VL)))))
+ return SDValue();
+
+ MVT SrcVT = Src.getSimpleValueType();
+ MVT DstVT = N->getSimpleValueType(0);
+ unsigned Factor = DstVT.getScalarSizeInBits() / SrcVT.getScalarSizeInBits();
+
+ // Only vf2, vf4, vf8 are legal with RVV.
+ if (Factor != 2 && Factor != 4 && Factor != 8)
+ return SDValue();
+
+ return DCI.DAG.getNode(N->getOpcode(), SDLoc(N), DstVT, Src, Mask, VL);
+}
+
static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
const RISCVSubtarget &Subtarget) {
assert(N->getOpcode() == ISD::SRA && "Unexpected opcode");
@@ -23482,6 +23508,9 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
case RISCVISD::VFWADD_W_VL:
case RISCVISD::VFWSUB_W_VL:
return combineOp_VLToVWOp_VL(N, DCI, Subtarget);
+ case RISCVISD::VSEXT_VL:
+ case RISCVISD::VZEXT_VL:
+ return performVEXT_VLCombine(N, DCI, Subtarget);
case ISD::LOAD:
case ISD::STORE: {
if (DCI.isAfterLegalizeDAG())
>From 107b89de316d616cffb0a3114f4fc34810d5d00d Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Thu, 23 Jul 2026 11:40:42 -0500
Subject: [PATCH 2/4] Add opcode assert
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 157b67eaef388..2bee2722c9eb2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20705,6 +20705,10 @@ static SDValue performVFMADD_VLCombine(SDNode *N,
static SDValue performVEXT_VLCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI,
const RISCVSubtarget &Subtarget) {
+ unsigned Opcode = N->getOpcode();
+ assert((Opcode == RISCVISD::VSEXT_VL || Opcode == RISCVISD::VZEXT_VL) &&
+ "Unexpected opcode");
+
SDValue Inner = N->getOperand(0);
SDValue Mask = N->getOperand(1);
SDValue VL = N->getOperand(2);
@@ -20713,8 +20717,8 @@ static SDValue performVEXT_VLCombine(SDNode *N,
// where vext_vl is either vsext_vl or vzext_vl.
using namespace SDPatternMatch;
SDValue Src;
- if (!sd_match(Inner, m_OneUse(m_Node(N->getOpcode(), m_Value(Src),
- m_Specific(Mask), m_Specific(VL)))))
+ if (!sd_match(Inner, m_OneUse(m_Node(Opcode, m_Value(Src), m_Specific(Mask),
+ m_Specific(VL)))))
return SDValue();
MVT SrcVT = Src.getSimpleValueType();
@@ -20725,7 +20729,7 @@ static SDValue performVEXT_VLCombine(SDNode *N,
if (Factor != 2 && Factor != 4 && Factor != 8)
return SDValue();
- return DCI.DAG.getNode(N->getOpcode(), SDLoc(N), DstVT, Src, Mask, VL);
+ return DCI.DAG.getNode(Opcode, SDLoc(N), DstVT, Src, Mask, VL);
}
static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
>From 358820d43c31dd1a96129f6865ea57fa70bae8c9 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Mon, 27 Jul 2026 09:43:32 -0500
Subject: [PATCH 3/4] Remove unnecessary factor check
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 7 -------
1 file changed, 7 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 2bee2722c9eb2..b6d7ff71e8b29 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20721,14 +20721,7 @@ static SDValue performVEXT_VLCombine(SDNode *N,
m_Specific(VL)))))
return SDValue();
- MVT SrcVT = Src.getSimpleValueType();
MVT DstVT = N->getSimpleValueType(0);
- unsigned Factor = DstVT.getScalarSizeInBits() / SrcVT.getScalarSizeInBits();
-
- // Only vf2, vf4, vf8 are legal with RVV.
- if (Factor != 2 && Factor != 4 && Factor != 8)
- return SDValue();
-
return DCI.DAG.getNode(Opcode, SDLoc(N), DstVT, Src, Mask, VL);
}
>From 3225811c2e76ae97bcecb432a16f4072dc87a776 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Tue, 28 Jul 2026 09:20:41 -0500
Subject: [PATCH 4/4] Update tests after rebase
---
.../CodeGen/RISCV/rvv/fixed-vectors-clmul.ll | 11 ++++------
.../CodeGen/RISCV/rvv/fixed-vectors-clmulh.ll | 22 +++++++------------
2 files changed, 12 insertions(+), 21 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-clmul.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-clmul.ll
index eb0dc89d0bc33..cea53a0bf934f 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-clmul.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-clmul.ll
@@ -1949,13 +1949,10 @@ define <4 x i8> @clmulr_v4i8(<4 x i8> %a, <4 x i8> %b) nounwind {
;
; ZVBC-LABEL: clmulr_v4i8:
; ZVBC: # %bb.0:
-; ZVBC-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
-; ZVBC-NEXT: vzext.vf2 v10, v9
-; ZVBC-NEXT: vzext.vf2 v12, v8
-; ZVBC-NEXT: vsetvli zero, zero, e64, m2, ta, ma
-; ZVBC-NEXT: vzext.vf4 v8, v10
-; ZVBC-NEXT: vzext.vf4 v10, v12
-; ZVBC-NEXT: vclmul.vv v8, v10, v8
+; ZVBC-NEXT: vsetivli zero, 4, e64, m2, ta, ma
+; ZVBC-NEXT: vzext.vf8 v10, v9
+; ZVBC-NEXT: vzext.vf8 v12, v8
+; ZVBC-NEXT: vclmul.vv v8, v12, v10
; ZVBC-NEXT: vsetvli zero, zero, e32, m1, ta, ma
; ZVBC-NEXT: vnsrl.wi v10, v8, 0
; ZVBC-NEXT: vsetvli zero, zero, e16, mf2, ta, ma
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-clmulh.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-clmulh.ll
index 0516628c5cd0b..027dd1038958c 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-clmulh.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-clmulh.ll
@@ -5395,13 +5395,10 @@ define <4 x i8> @clmulh_v4i8(<4 x i8> %a, <4 x i8> %b) nounwind {
;
; ZVBC-LABEL: clmulh_v4i8:
; ZVBC: # %bb.0:
-; ZVBC-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
-; ZVBC-NEXT: vzext.vf2 v10, v9
-; ZVBC-NEXT: vzext.vf2 v12, v8
-; ZVBC-NEXT: vsetvli zero, zero, e64, m2, ta, ma
-; ZVBC-NEXT: vzext.vf4 v8, v10
-; ZVBC-NEXT: vzext.vf4 v10, v12
-; ZVBC-NEXT: vclmul.vv v8, v10, v8
+; ZVBC-NEXT: vsetivli zero, 4, e64, m2, ta, ma
+; ZVBC-NEXT: vzext.vf8 v10, v9
+; ZVBC-NEXT: vzext.vf8 v12, v8
+; ZVBC-NEXT: vclmul.vv v8, v12, v10
; ZVBC-NEXT: vsetvli zero, zero, e32, m1, ta, ma
; ZVBC-NEXT: vnsrl.wi v10, v8, 0
; ZVBC-NEXT: vsetvli zero, zero, e16, mf2, ta, ma
@@ -5486,13 +5483,10 @@ define <4 x i16> @clmulh_v4i16(<4 x i16> %a, <4 x i16> %b) nounwind {
;
; ZVBC-LABEL: clmulh_v4i16:
; ZVBC: # %bb.0:
-; ZVBC-NEXT: vsetivli zero, 4, e32, m1, ta, ma
-; ZVBC-NEXT: vzext.vf2 v10, v9
-; ZVBC-NEXT: vzext.vf2 v12, v8
-; ZVBC-NEXT: vsetvli zero, zero, e64, m2, ta, ma
-; ZVBC-NEXT: vzext.vf2 v8, v10
-; ZVBC-NEXT: vzext.vf2 v10, v12
-; ZVBC-NEXT: vclmul.vv v8, v10, v8
+; ZVBC-NEXT: vsetivli zero, 4, e64, m2, ta, ma
+; ZVBC-NEXT: vzext.vf4 v10, v9
+; ZVBC-NEXT: vzext.vf4 v12, v8
+; ZVBC-NEXT: vclmul.vv v8, v12, v10
; ZVBC-NEXT: vsetvli zero, zero, e32, m1, ta, ma
; ZVBC-NEXT: vnsrl.wi v10, v8, 0
; ZVBC-NEXT: vsetvli zero, zero, e16, mf2, ta, ma
More information about the llvm-commits
mailing list