[llvm] [RISCV] Handle sign_extend of i32 in insert_vector_elt for RV32 (PR #185548)
Jim Lin via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 9 18:04:37 PDT 2026
https://github.com/tclin914 created https://github.com/llvm/llvm-project/pull/185548
On RV32 with <N x i64> vectors, inserting a value that is a
sign_extend of an i32 only uses the lower 32 bits, so it can be
lowered without scalar legalization, same as i32 constants.
>From a5832fd72a462faa9655b51ad1406393f2bccf03 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Mon, 9 Mar 2026 15:20:11 +0800
Subject: [PATCH 1/2] [RISCV] Pre-commit test
---
.../CodeGen/RISCV/rvv/fixed-vectors-insert.ll | 25 +++++++++++++++++++
.../CodeGen/RISCV/rvv/insertelt-int-rv32.ll | 15 +++++++++++
2 files changed, 40 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll
index 79286c0304e0c..26b03ddc71e2e 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll
@@ -574,6 +574,31 @@ define <8 x i64> @insertelt_v8i64_0(<8 x i64> %a, ptr %x) {
ret <8 x i64> %b
}
+define <8 x i64> @insertelt_v8i64_sext_0(<8 x i64> %a, ptr %x, i32 signext %elt) {
+; RV32-LABEL: insertelt_v8i64_sext_0:
+; RV32: # %bb.0:
+; RV32-NEXT: srai a0, a1, 31
+; RV32-NEXT: vsetivli zero, 2, e32, m1, tu, ma
+; RV32-NEXT: vslide1down.vx v8, v8, a1
+; RV32-NEXT: vslide1down.vx v8, v8, a0
+; RV32-NEXT: ret
+;
+; RV64-LABEL: insertelt_v8i64_sext_0:
+; RV64: # %bb.0:
+; RV64-NEXT: vsetivli zero, 8, e64, m1, tu, ma
+; RV64-NEXT: vmv.s.x v8, a1
+; RV64-NEXT: ret
+;
+; VISNI-LABEL: insertelt_v8i64_sext_0:
+; VISNI: # %bb.0:
+; VISNI-NEXT: vsetivli zero, 8, e64, m1, tu, ma
+; VISNI-NEXT: vmv.s.x v8, a1
+; VISNI-NEXT: ret
+ %sext = sext i32 %elt to i64
+ %b = insertelement <8 x i64> %a, i64 %sext, i32 0
+ ret <8 x i64> %b
+}
+
define void @insertelt_v8i64_0_store(ptr %x) {
; RV32-LABEL: insertelt_v8i64_0_store:
; RV32: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rvv/insertelt-int-rv32.ll b/llvm/test/CodeGen/RISCV/rvv/insertelt-int-rv32.ll
index c3cc90c6a8de3..10cb3d42b6475 100644
--- a/llvm/test/CodeGen/RISCV/rvv/insertelt-int-rv32.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/insertelt-int-rv32.ll
@@ -838,3 +838,18 @@ define <vscale x 2 x i64> @insertelt_nxv2i64_idx_cn1(<vscale x 2 x i64> %v, i32
%r = insertelement <vscale x 2 x i64> %v, i64 -1, i32 %idx
ret <vscale x 2 x i64> %r
}
+
+define <vscale x 2 x i64> @insertelt_nxv2i64_sext(<vscale x 2 x i64> %v, i32 signext %elt, i32 %idx) {
+; CHECK-LABEL: insertelt_nxv2i64_sext:
+; CHECK: # %bb.0:
+; CHECK-NEXT: srai a1, a0, 31
+; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma
+; CHECK-NEXT: vslide1down.vx v10, v8, a0
+; CHECK-NEXT: vslide1down.vx v10, v10, a1
+; CHECK-NEXT: vsetivli zero, 4, e64, m2, tu, ma
+; CHECK-NEXT: vslideup.vi v8, v10, 3
+; CHECK-NEXT: ret
+ %sext = sext i32 %elt to i64
+ %r = insertelement <vscale x 2 x i64> %v, i64 %sext, i32 3
+ ret <vscale x 2 x i64> %r
+}
>From 78b4a7ba6586b444b814cd9d32ce7a166a9527d0 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Fri, 6 Mar 2026 11:08:16 +0800
Subject: [PATCH 2/2] [RISCV] Handle sign_extend of i32 in insert_vector_elt
for RV32
On RV32 with <N x i64> vectors, inserting a value that is a
sign_extend of an i32 only uses the lower 32 bits, so it can be
lowered without scalar legalization, same as i32 constants.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 18 ++++++++++++------
.../CodeGen/RISCV/rvv/fixed-vectors-insert.ll | 18 +++++-------------
.../CodeGen/RISCV/rvv/insertelt-int-rv32.ll | 5 +----
3 files changed, 18 insertions(+), 23 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 808c8b2be818b..5773ec754d2b7 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -10990,13 +10990,19 @@ SDValue RISCVTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
bool IsLegalInsert = Subtarget.is64Bit() || Val.getValueType() != MVT::i64;
// Even i64-element vectors on RV32 can be lowered without scalar
// legalization if the most-significant 32 bits of the value are not affected
- // by the sign-extension of the lower 32 bits.
- // TODO: We could also catch sign extensions of a 32-bit value.
- if (!IsLegalInsert && isa<ConstantSDNode>(Val)) {
- const auto *CVal = cast<ConstantSDNode>(Val);
- if (isInt<32>(CVal->getSExtValue())) {
+ // by the sign-extension of the lower 32 bits. This applies to i32 constants
+ // and sign_extend of i32 values.
+ if (!IsLegalInsert) {
+ if (isa<ConstantSDNode>(Val)) {
+ const auto *CVal = cast<ConstantSDNode>(Val);
+ if (isInt<32>(CVal->getSExtValue())) {
+ IsLegalInsert = true;
+ Val = DAG.getSignedConstant(CVal->getSExtValue(), DL, MVT::i32);
+ }
+ } else if (Val.getOpcode() == ISD::SIGN_EXTEND &&
+ Val.getOperand(0).getValueType() == MVT::i32) {
IsLegalInsert = true;
- Val = DAG.getSignedConstant(CVal->getSExtValue(), DL, MVT::i32);
+ Val = Val.getOperand(0);
}
}
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll
index 26b03ddc71e2e..b95a12ff62571 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll
@@ -575,19 +575,11 @@ define <8 x i64> @insertelt_v8i64_0(<8 x i64> %a, ptr %x) {
}
define <8 x i64> @insertelt_v8i64_sext_0(<8 x i64> %a, ptr %x, i32 signext %elt) {
-; RV32-LABEL: insertelt_v8i64_sext_0:
-; RV32: # %bb.0:
-; RV32-NEXT: srai a0, a1, 31
-; RV32-NEXT: vsetivli zero, 2, e32, m1, tu, ma
-; RV32-NEXT: vslide1down.vx v8, v8, a1
-; RV32-NEXT: vslide1down.vx v8, v8, a0
-; RV32-NEXT: ret
-;
-; RV64-LABEL: insertelt_v8i64_sext_0:
-; RV64: # %bb.0:
-; RV64-NEXT: vsetivli zero, 8, e64, m1, tu, ma
-; RV64-NEXT: vmv.s.x v8, a1
-; RV64-NEXT: ret
+; CHECK-LABEL: insertelt_v8i64_sext_0:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e64, m1, tu, ma
+; CHECK-NEXT: vmv.s.x v8, a1
+; CHECK-NEXT: ret
;
; VISNI-LABEL: insertelt_v8i64_sext_0:
; VISNI: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rvv/insertelt-int-rv32.ll b/llvm/test/CodeGen/RISCV/rvv/insertelt-int-rv32.ll
index 10cb3d42b6475..3daf7dba85ba0 100644
--- a/llvm/test/CodeGen/RISCV/rvv/insertelt-int-rv32.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/insertelt-int-rv32.ll
@@ -842,11 +842,8 @@ define <vscale x 2 x i64> @insertelt_nxv2i64_idx_cn1(<vscale x 2 x i64> %v, i32
define <vscale x 2 x i64> @insertelt_nxv2i64_sext(<vscale x 2 x i64> %v, i32 signext %elt, i32 %idx) {
; CHECK-LABEL: insertelt_nxv2i64_sext:
; CHECK: # %bb.0:
-; CHECK-NEXT: srai a1, a0, 31
-; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma
-; CHECK-NEXT: vslide1down.vx v10, v8, a0
-; CHECK-NEXT: vslide1down.vx v10, v10, a1
; CHECK-NEXT: vsetivli zero, 4, e64, m2, tu, ma
+; CHECK-NEXT: vmv.s.x v10, a0
; CHECK-NEXT: vslideup.vi v8, v10, 3
; CHECK-NEXT: ret
%sext = sext i32 %elt to i64
More information about the llvm-commits
mailing list