[llvm] 396a2d7 - [RISCV][P-ext] Fold packed insert-into-zero to zero-extend (#208006)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 15 01:09:17 PDT 2026
Author: SiHuaN
Date: 2026-07-15T16:09:12+08:00
New Revision: 396a2d700bba0f9d4ac97198921beb7413e5ce5c
URL: https://github.com/llvm/llvm-project/commit/396a2d700bba0f9d4ac97198921beb7413e5ce5c
DIFF: https://github.com/llvm/llvm-project/commit/396a2d700bba0f9d4ac97198921beb7413e5ce5c.diff
LOG: [RISCV][P-ext] Fold packed insert-into-zero to zero-extend (#208006)
An insert_subvector of a 32-bit packed type (v4i8/v2i16) into a zero-filled
64-bit packed vector at index 0 is a zero-extend. Fold it so RV64 emits a
single zext.w instead of scalarizing into a byte-wise repack; RV32
concatenates with a zero half into the GPRPair.
Added:
llvm/test/CodeGen/RISCV/rvp-insert-subvector.ll
Modified:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 32434508c809d..96b6f391863c4 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -595,6 +595,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
{MVT::v2i16, MVT::v4i8}, Custom);
setOperationAction(ISD::INTRINSIC_WO_CHAIN, {MVT::v2i16, MVT::v4i8},
Custom);
+ // Operand legalization queries the action using the illegal subvector.
+ setOperationAction(ISD::INSERT_SUBVECTOR, {MVT::v2i16, MVT::v4i8},
+ Custom);
} else {
VTs = P32VecVTs;
}
@@ -709,6 +712,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
{ISD::SETGE, ISD::SETUGT, ISD::SETUGE, ISD::SETULE, ISD::SETLE},
P64VecVTs, Expand);
setCondCodeAction({ISD::SETNE, ISD::SETGT}, P64VecVTs, Custom);
+ // Operation legalization queries the action using the result type.
+ setOperationAction(ISD::INSERT_SUBVECTOR, {MVT::v4i16, MVT::v8i8},
+ Custom);
} else {
setOperationAction({ISD::MUL, ISD::MULHS, ISD::MULHU}, P64VecVTs, Legal);
setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG,
@@ -13006,6 +13012,9 @@ SDValue RISCVTargetLowering::lowerVPREDUCE(SDValue Op,
DAG.getConstantFP(APFloat::getNaN(ResVT.getFltSemantics()), DL, ResVT));
}
+static SDValue widenPackedVectorWithZeros(SelectionDAG &DAG, const SDLoc &DL,
+ SDValue V, MVT WideVT);
+
SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
SelectionDAG &DAG) const {
SDValue Vec = Op.getOperand(0);
@@ -13018,6 +13027,27 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
unsigned OrigIdx = Op.getConstantOperandVal(2);
const RISCVRegisterInfo *TRI = Subtarget.getRegisterInfo();
+ bool IsPExtInsert =
+ Subtarget.hasStdExtP() &&
+ ((Subtarget.is64Bit() &&
+ (SubVecVT == MVT::v2i16 || SubVecVT == MVT::v4i8)) ||
+ (!Subtarget.is64Bit() && (VecVT == MVT::v4i16 || VecVT == MVT::v8i8)));
+
+ // Fold insert of a 32-bit packed type into a zero-filled 64-bit packed vector
+ // at index 0 (a zero-extend) to avoid scalarizing it into a byte-wise repack.
+ if (IsPExtInsert) {
+ if ((VecVT != MVT::v4i16 && VecVT != MVT::v8i8) ||
+ SubVecVT.getSizeInBits() != 32 || OrigIdx != 0 ||
+ !ISD::isConstantSplatVectorAllZeros(Vec.getNode()))
+ return SDValue();
+
+ if (!Subtarget.is64Bit()) {
+ SDValue Zero = DAG.getBitcast(SubVecVT, DAG.getConstant(0, DL, MVT::i32));
+ return DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, SubVec, Zero);
+ }
+ return widenPackedVectorWithZeros(DAG, DL, SubVec, VecVT);
+ }
+
if (OrigIdx == 0 && Vec.isUndef())
return Op;
diff --git a/llvm/test/CodeGen/RISCV/rvp-insert-subvector.ll b/llvm/test/CodeGen/RISCV/rvp-insert-subvector.ll
new file mode 100644
index 0000000000000..07a54badc04e9
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvp-insert-subvector.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-p,+m,+zbb -verify-machineinstrs < %s | FileCheck %s --check-prefixes=RV32
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-p,+m,+zbb -verify-machineinstrs < %s | FileCheck %s --check-prefixes=RV64
+
+define <8 x i8> @insert_zero_v4i8(<4 x i8> %v) {
+; RV32-LABEL: insert_zero_v4i8:
+; RV32: # %bb.0:
+; RV32-NEXT: li a1, 0
+; RV32-NEXT: ret
+;
+; RV64-LABEL: insert_zero_v4i8:
+; RV64: # %bb.0:
+; RV64-NEXT: zext.w a0, a0
+; RV64-NEXT: ret
+ %r = call <8 x i8> @llvm.vector.insert.v8i8.v4i8(<8 x i8> zeroinitializer, <4 x i8> %v, i64 0)
+ ret <8 x i8> %r
+}
+
+define <4 x i16> @insert_zero_v2i16(<2 x i16> %v) {
+; RV32-LABEL: insert_zero_v2i16:
+; RV32: # %bb.0:
+; RV32-NEXT: li a1, 0
+; RV32-NEXT: ret
+;
+; RV64-LABEL: insert_zero_v2i16:
+; RV64: # %bb.0:
+; RV64-NEXT: zext.w a0, a0
+; RV64-NEXT: ret
+ %r = call <4 x i16> @llvm.vector.insert.v4i16.v2i16(<4 x i16> zeroinitializer, <2 x i16> %v, i64 0)
+ ret <4 x i16> %r
+}
+
+define <2 x i32> @insert_zero_v1i32(<1 x i32> %v) {
+; RV32-LABEL: insert_zero_v1i32:
+; RV32: # %bb.0:
+; RV32-NEXT: li a1, 0
+; RV32-NEXT: ret
+;
+; RV64-LABEL: insert_zero_v1i32:
+; RV64: # %bb.0:
+; RV64-NEXT: pack a0, a0, zero
+; RV64-NEXT: ret
+ %r = call <2 x i32> @llvm.vector.insert.v2i32.v1i32(<2 x i32> zeroinitializer, <1 x i32> %v, i64 0)
+ ret <2 x i32> %r
+}
More information about the llvm-commits
mailing list