[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