[RISCV] Handle sign_extend of i32 in insert_vector_elt for RV32 (#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.
This commit is contained in:
Jim Lin 2026-03-10 13:12:55 +08:00 committed by GitHub
parent 269b17a215
commit 48473ddcc7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 6 deletions

View File

@ -11009,13 +11009,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);
}
}

View File

@ -574,6 +574,23 @@ 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) {
; 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:
; 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:

View File

@ -838,3 +838,15 @@ 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: 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
%r = insertelement <vscale x 2 x i64> %v, i64 %sext, i32 3
ret <vscale x 2 x i64> %r
}