Skip to content

Commit 8c4937b

Browse files
committed
[RISCV] Special case sign extended scalars when type legalizing nxvXi64 .vx instrinsics on RV32.
On RV32, we need to type legalize i64 scalar arguments to intrinsics. We usually do this by splatting the value into a vector separately. If the scalar happens to be sign extended, we can continue using a .vx intrinsic. We already special cased sign extended constants, this extends it to any sign extended value. I've only added tests for one case of vadd. Most intrinsics go through the same check. I can add more tests if we're concerned. Differential Revision: https://reviews.llvm.org/D122186
1 parent b40f420 commit 8c4937b

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4624,11 +4624,9 @@ static SDValue lowerVectorIntrinsicScalars(SDValue Op, SelectionDAG &DAG,
46244624

46254625
// If this is a sign-extended 32-bit constant, we can truncate it and rely
46264626
// on the instruction to sign-extend since SEW>XLEN.
4627-
if (auto *CVal = dyn_cast<ConstantSDNode>(ScalarOp)) {
4628-
if (isInt<32>(CVal->getSExtValue())) {
4629-
ScalarOp = DAG.getConstant(CVal->getSExtValue(), DL, MVT::i32);
4630-
return DAG.getNode(Op->getOpcode(), DL, Op->getVTList(), Operands);
4631-
}
4627+
if (DAG.ComputeNumSignBits(ScalarOp) > 32) {
4628+
ScalarOp = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, ScalarOp);
4629+
return DAG.getNode(Op->getOpcode(), DL, Op->getVTList(), Operands);
46324630
}
46334631

46344632
switch (IntNo) {

llvm/test/CodeGen/RISCV/rvv/vadd.ll

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,6 +1881,49 @@ entry:
18811881
ret <vscale x 1 x i64> %a
18821882
}
18831883

1884+
define <vscale x 1 x i64> @intrinsic_vadd_vx_sext_nxv1i64_nxv1i64_i64(<vscale x 1 x i64> %0, i32 %1, iXLen %2) nounwind {
1885+
; RV32-LABEL: intrinsic_vadd_vx_sext_nxv1i64_nxv1i64_i64:
1886+
; RV32: # %bb.0: # %entry
1887+
; RV32-NEXT: vsetvli zero, a1, e64, m1, ta, mu
1888+
; RV32-NEXT: vadd.vx v8, v8, a0
1889+
; RV32-NEXT: ret
1890+
;
1891+
; RV64-LABEL: intrinsic_vadd_vx_sext_nxv1i64_nxv1i64_i64:
1892+
; RV64: # %bb.0: # %entry
1893+
; RV64-NEXT: sext.w a0, a0
1894+
; RV64-NEXT: vsetvli zero, a1, e64, m1, ta, mu
1895+
; RV64-NEXT: vadd.vx v8, v8, a0
1896+
; RV64-NEXT: ret
1897+
entry:
1898+
%ext = sext i32 %1 to i64
1899+
%a = call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.i64(
1900+
<vscale x 1 x i64> undef,
1901+
<vscale x 1 x i64> %0,
1902+
i64 %ext,
1903+
iXLen %2)
1904+
1905+
ret <vscale x 1 x i64> %a
1906+
}
1907+
1908+
define <vscale x 1 x i64> @intrinsic_vadd_vx_sextload_nxv1i64_nxv1i64_i64(<vscale x 1 x i64> %0, i32* %1, iXLen %2) nounwind {
1909+
; CHECK-LABEL: intrinsic_vadd_vx_sextload_nxv1i64_nxv1i64_i64:
1910+
; CHECK: # %bb.0: # %entry
1911+
; CHECK-NEXT: lw a0, 0(a0)
1912+
; CHECK-NEXT: vsetvli zero, a1, e64, m1, ta, mu
1913+
; CHECK-NEXT: vadd.vx v8, v8, a0
1914+
; CHECK-NEXT: ret
1915+
entry:
1916+
%load = load i32, i32* %1
1917+
%ext = sext i32 %load to i64
1918+
%a = call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.i64(
1919+
<vscale x 1 x i64> undef,
1920+
<vscale x 1 x i64> %0,
1921+
i64 %ext,
1922+
iXLen %2)
1923+
1924+
ret <vscale x 1 x i64> %a
1925+
}
1926+
18841927
declare <vscale x 1 x i64> @llvm.riscv.vadd.mask.nxv1i64.i64(
18851928
<vscale x 1 x i64>,
18861929
<vscale x 1 x i64>,

0 commit comments

Comments
 (0)