From 9945af021eb170c501146b5e507bd1381426677b Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 16 Sep 2025 15:37:32 -0700 Subject: [PATCH 1/4] Pre-commit test --- .../fixed-vectors-vw-web-simplification.ll | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll index 227a428831b60..b8e9ba3183ac4 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll @@ -58,3 +58,26 @@ define <2 x i16> @vwmul_v2i16_multiple_users(ptr %x, ptr %y, ptr %z) { %i = or <2 x i16> %h, %g ret <2 x i16> %i } + +; FIXME: We should have a vsext.vl instead of vzext.vl. +define <4 x i32> @pr159152(<4 x i8> %x) { +; NO_FOLDING-LABEL: pr159152: +; NO_FOLDING: # %bb.0: +; NO_FOLDING-NEXT: vsetivli zero, 4, e16, mf2, ta, ma +; NO_FOLDING-NEXT: vzext.vf2 v9, v8 +; NO_FOLDING-NEXT: li a0, 9 +; NO_FOLDING-NEXT: vwaddu.vx v8, v9, a0 +; NO_FOLDING-NEXT: ret +; +; FOLDING-LABEL: pr159152: +; FOLDING: # %bb.0: +; FOLDING-NEXT: vsetivli zero, 4, e16, mf2, ta, ma +; FOLDING-NEXT: vzext.vf2 v9, v8 +; FOLDING-NEXT: li a0, 9 +; FOLDING-NEXT: vwaddu.vx v8, v9, a0 +; FOLDING-NEXT: ret + %a = sext <4 x i8> %x to <4 x i16> + %b = zext <4 x i16> %a to <4 x i32> + %c = add <4 x i32> %b, + ret <4 x i32> %c +} From a15647526d630a2bf0573b7480eaf75cfaba9f61 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 16 Sep 2025 15:07:50 -0700 Subject: [PATCH 2/4] [RISCV] Re-work how VWADD_W_VL and similar _W_VL nodes are handled in combineOp_VLToVWOp_VL. These instructions have one already narrow operand. Previously, we pretended like this operand was a supported extension. This could cause problems when we called getOrCreateExtendedOp on this narrow operand when creating the the VWADD_VL. If the narrow operand happened to be an extend of the opposite type, we would peek through it and then rebuild it with the wrong extension type. So (vwadd_w_vl (i32 (sext X)), (i16 (zext Y))) would become (vwadd_vl (i16 (sext X)), (i16 (sext Y))). To prevent this, we ignore the operand instead and pass std::nullopt for SupportsExt to getOrCreateExtendedOp so it won't peek through any extends on the narrow source. Fixes #159152. --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 86 +++++++++++-------- .../fixed-vectors-vw-web-simplification.ll | 4 +- 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 66ebda7aa586b..863b6b5b36d3b 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -17325,18 +17325,9 @@ struct NodeExtensionHelper { case RISCVISD::VWSUBU_W_VL: case RISCVISD::VFWADD_W_VL: case RISCVISD::VFWSUB_W_VL: - if (OperandIdx == 1) { - SupportsZExt = - Opc == RISCVISD::VWADDU_W_VL || Opc == RISCVISD::VWSUBU_W_VL; - SupportsSExt = - Opc == RISCVISD::VWADD_W_VL || Opc == RISCVISD::VWSUB_W_VL; - SupportsFPExt = - Opc == RISCVISD::VFWADD_W_VL || Opc == RISCVISD::VFWSUB_W_VL; - // There's no existing extension here, so we don't have to worry about - // making sure it gets removed. - EnforceOneUse = false; + // Operand 1 can't be changed. + if (OperandIdx == 1) break; - } [[fallthrough]]; default: fillUpExtensionSupport(Root, DAG, Subtarget); @@ -17374,20 +17365,20 @@ struct NodeExtensionHelper { case RISCVISD::ADD_VL: case RISCVISD::MUL_VL: case RISCVISD::OR_VL: - case RISCVISD::VWADD_W_VL: - case RISCVISD::VWADDU_W_VL: case RISCVISD::FADD_VL: case RISCVISD::FMUL_VL: - case RISCVISD::VFWADD_W_VL: case RISCVISD::VFMADD_VL: case RISCVISD::VFNMSUB_VL: case RISCVISD::VFNMADD_VL: case RISCVISD::VFMSUB_VL: return true; + case RISCVISD::VWADD_W_VL: + case RISCVISD::VWADDU_W_VL: case ISD::SUB: case RISCVISD::SUB_VL: case RISCVISD::VWSUB_W_VL: case RISCVISD::VWSUBU_W_VL: + case RISCVISD::VFWADD_W_VL: case RISCVISD::FSUB_VL: case RISCVISD::VFWSUB_W_VL: case ISD::SHL: @@ -17506,6 +17497,30 @@ canFoldToVWWithSameExtension(SDNode *Root, const NodeExtensionHelper &LHS, Subtarget); } +/// Check if \p Root follows a pattern Root(bf16ext(LHS), bf16ext(RHS)) +/// +/// \returns std::nullopt if the pattern doesn't match or a CombineResult that +/// can be used to apply the pattern. +static std::optional +canFoldToVWWithSameExtZEXT(SDNode *Root, const NodeExtensionHelper &LHS, + const NodeExtensionHelper &RHS, SelectionDAG &DAG, + const RISCVSubtarget &Subtarget) { + return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::ZExt, DAG, + Subtarget); +} + +/// Check if \p Root follows a pattern Root(ext(LHS), zext(RHS)) +/// +/// \returns std::nullopt if the pattern doesn't match or a CombineResult that +/// can be used to apply the pattern. +static std::optional +canFoldToVWWithSameExtBF16(SDNode *Root, const NodeExtensionHelper &LHS, + const NodeExtensionHelper &RHS, SelectionDAG &DAG, + const RISCVSubtarget &Subtarget) { + return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::BF16Ext, DAG, + Subtarget); +} + /// Check if \p Root follows a pattern Root(LHS, ext(RHS)) /// /// \returns std::nullopt if the pattern doesn't match or a CombineResult that @@ -17534,7 +17549,7 @@ canFoldToVW_W(SDNode *Root, const NodeExtensionHelper &LHS, return std::nullopt; } -/// Check if \p Root follows a pattern Root(sext(LHS), sext(RHS)) +/// Check if \p Root follows a pattern Root(sext(LHS), RHS) /// /// \returns std::nullopt if the pattern doesn't match or a CombineResult that /// can be used to apply the pattern. @@ -17542,11 +17557,14 @@ static std::optional canFoldToVWWithSEXT(SDNode *Root, const NodeExtensionHelper &LHS, const NodeExtensionHelper &RHS, SelectionDAG &DAG, const RISCVSubtarget &Subtarget) { - return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::SExt, DAG, - Subtarget); + if (LHS.SupportsSExt) + return CombineResult(NodeExtensionHelper::getSExtOpcode(Root->getOpcode()), + Root, LHS, /*LHSExt=*/{ExtKind::SExt}, RHS, + /*RHSExt=*/std::nullopt); + return std::nullopt; } -/// Check if \p Root follows a pattern Root(zext(LHS), zext(RHS)) +/// Check if \p Root follows a pattern Root(zext(LHS), RHS) /// /// \returns std::nullopt if the pattern doesn't match or a CombineResult that /// can be used to apply the pattern. @@ -17554,11 +17572,14 @@ static std::optional canFoldToVWWithZEXT(SDNode *Root, const NodeExtensionHelper &LHS, const NodeExtensionHelper &RHS, SelectionDAG &DAG, const RISCVSubtarget &Subtarget) { - return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::ZExt, DAG, - Subtarget); + if (LHS.SupportsZExt) + return CombineResult(NodeExtensionHelper::getZExtOpcode(Root->getOpcode()), + Root, LHS, /*LHSExt=*/{ExtKind::ZExt}, RHS, + /*RHSExt=*/std::nullopt); + return std::nullopt; } -/// Check if \p Root follows a pattern Root(fpext(LHS), fpext(RHS)) +/// Check if \p Root follows a pattern Root(fpext(LHS), RHS) /// /// \returns std::nullopt if the pattern doesn't match or a CombineResult that /// can be used to apply the pattern. @@ -17566,20 +17587,11 @@ static std::optional canFoldToVWWithFPEXT(SDNode *Root, const NodeExtensionHelper &LHS, const NodeExtensionHelper &RHS, SelectionDAG &DAG, const RISCVSubtarget &Subtarget) { - return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::FPExt, DAG, - Subtarget); -} - -/// Check if \p Root follows a pattern Root(bf16ext(LHS), bf16ext(RHS)) -/// -/// \returns std::nullopt if the pattern doesn't match or a CombineResult that -/// can be used to apply the pattern. -static std::optional -canFoldToVWWithBF16EXT(SDNode *Root, const NodeExtensionHelper &LHS, - const NodeExtensionHelper &RHS, SelectionDAG &DAG, - const RISCVSubtarget &Subtarget) { - return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::BF16Ext, DAG, - Subtarget); + if (LHS.SupportsFPExt) + return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->getOpcode()), + Root, LHS, /*LHSExt=*/{ExtKind::FPExt}, RHS, + /*RHSExt=*/std::nullopt); + return std::nullopt; } /// Check if \p Root follows a pattern Root(sext(LHS), zext(RHS)) @@ -17622,7 +17634,7 @@ NodeExtensionHelper::getSupportedFoldings(const SDNode *Root) { case RISCVISD::VFNMSUB_VL: Strategies.push_back(canFoldToVWWithSameExtension); if (Root->getOpcode() == RISCVISD::VFMADD_VL) - Strategies.push_back(canFoldToVWWithBF16EXT); + Strategies.push_back(canFoldToVWWithSameExtBF16); break; case ISD::MUL: case RISCVISD::MUL_VL: @@ -17634,7 +17646,7 @@ NodeExtensionHelper::getSupportedFoldings(const SDNode *Root) { case ISD::SHL: case RISCVISD::SHL_VL: // shl -> vwsll - Strategies.push_back(canFoldToVWWithZEXT); + Strategies.push_back(canFoldToVWWithSameExtZEXT); break; case RISCVISD::VWADD_W_VL: case RISCVISD::VWSUB_W_VL: diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll index b8e9ba3183ac4..ea5f92d529887 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll @@ -64,7 +64,7 @@ define <4 x i32> @pr159152(<4 x i8> %x) { ; NO_FOLDING-LABEL: pr159152: ; NO_FOLDING: # %bb.0: ; NO_FOLDING-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; NO_FOLDING-NEXT: vzext.vf2 v9, v8 +; NO_FOLDING-NEXT: vsext.vf2 v9, v8 ; NO_FOLDING-NEXT: li a0, 9 ; NO_FOLDING-NEXT: vwaddu.vx v8, v9, a0 ; NO_FOLDING-NEXT: ret @@ -72,7 +72,7 @@ define <4 x i32> @pr159152(<4 x i8> %x) { ; FOLDING-LABEL: pr159152: ; FOLDING: # %bb.0: ; FOLDING-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; FOLDING-NEXT: vzext.vf2 v9, v8 +; FOLDING-NEXT: vsext.vf2 v9, v8 ; FOLDING-NEXT: li a0, 9 ; FOLDING-NEXT: vwaddu.vx v8, v9, a0 ; FOLDING-NEXT: ret From ef8ff36ad9ac6d0d9bc1237f207f49d6047cd483 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 17 Sep 2025 09:02:16 -0700 Subject: [PATCH 3/4] fixup! Adjust FIXME. --- .../CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll index ea5f92d529887..ea4add2da5ebc 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vw-web-simplification.ll @@ -59,7 +59,7 @@ define <2 x i16> @vwmul_v2i16_multiple_users(ptr %x, ptr %y, ptr %z) { ret <2 x i16> %i } -; FIXME: We should have a vsext.vl instead of vzext.vl. +; Make sure we have a vsext.vl and a vwaddu.vx. define <4 x i32> @pr159152(<4 x i8> %x) { ; NO_FOLDING-LABEL: pr159152: ; NO_FOLDING: # %bb.0: From 1e4fae0eed3fb49ea56856fee6dce4b63fbc38f9 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 18 Sep 2025 21:31:09 -0700 Subject: [PATCH 4/4] fixup! Fix mistake in comment --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 863b6b5b36d3b..91e9975ba9256 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -17497,7 +17497,7 @@ canFoldToVWWithSameExtension(SDNode *Root, const NodeExtensionHelper &LHS, Subtarget); } -/// Check if \p Root follows a pattern Root(bf16ext(LHS), bf16ext(RHS)) +/// Check if \p Root follows a pattern Root(zext(LHS), zext(RHS)) /// /// \returns std::nullopt if the pattern doesn't match or a CombineResult that /// can be used to apply the pattern. @@ -17509,7 +17509,7 @@ canFoldToVWWithSameExtZEXT(SDNode *Root, const NodeExtensionHelper &LHS, Subtarget); } -/// Check if \p Root follows a pattern Root(ext(LHS), zext(RHS)) +/// Check if \p Root follows a pattern Root(bf16ext(LHS), bf16ext(RHS)) /// /// \returns std::nullopt if the pattern doesn't match or a CombineResult that /// can be used to apply the pattern.