[llvm] 51940d6 - [RISCV] Special case sign extended scalars when type legalizing nxvXi64 .vx instrinsics on RV32.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 22 10:31:56 PDT 2022


Author: Craig Topper
Date: 2022-03-22T10:29:06-07:00
New Revision: 51940d69cb5d95417b914ec75961ffb78901fb53

URL: https://github.com/llvm/llvm-project/commit/51940d69cb5d95417b914ec75961ffb78901fb53
DIFF: https://github.com/llvm/llvm-project/commit/51940d69cb5d95417b914ec75961ffb78901fb53.diff

LOG: [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.

Reviewed By: khchen

Differential Revision: https://reviews.llvm.org/D122186

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/rvv/vadd.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index d793b7f92dca8..d607ebbbb82f0 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -4621,13 +4621,11 @@ static SDValue lowerVectorIntrinsicScalars(SDValue Op, SelectionDAG &DAG,
   assert(XLenVT == MVT::i32 && OpVT == MVT::i64 &&
          VT.getVectorElementType() == MVT::i64 && "Unexpected VTs!");
 
-  // If this is a sign-extended 32-bit constant, we can truncate it and rely
-  // on the instruction to sign-extend since SEW>XLEN.
-  if (auto *CVal = dyn_cast<ConstantSDNode>(ScalarOp)) {
-    if (isInt<32>(CVal->getSExtValue())) {
-      ScalarOp = DAG.getConstant(CVal->getSExtValue(), DL, MVT::i32);
-      return DAG.getNode(Op->getOpcode(), DL, Op->getVTList(), Operands);
-    }
+  // If this is a sign-extended 32-bit value, we can truncate it and rely on the
+  // instruction to sign-extend since SEW>XLEN.
+  if (DAG.ComputeNumSignBits(ScalarOp) > 32) {
+    ScalarOp = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, ScalarOp);
+    return DAG.getNode(Op->getOpcode(), DL, Op->getVTList(), Operands);
   }
 
   switch (IntNo) {
@@ -4749,8 +4747,6 @@ static SDValue lowerVectorIntrinsicScalars(SDValue Op, SelectionDAG &DAG,
   }
 
   // We need to convert the scalar to a splat vector.
-  // FIXME: Can we implicitly truncate the scalar if it is known to
-  // be sign extended?
   SDValue VL = getVLOperand(Op);
   assert(VL.getValueType() == XLenVT);
   ScalarOp = splatSplitI64WithVL(DL, VT, SDValue(), ScalarOp, VL, DAG);

diff  --git a/llvm/test/CodeGen/RISCV/rvv/vadd.ll b/llvm/test/CodeGen/RISCV/rvv/vadd.ll
index ac5dde5cb985d..c6328f4e7cd49 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vadd.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vadd.ll
@@ -1881,6 +1881,49 @@ entry:
   ret <vscale x 1 x i64> %a
 }
 
+define <vscale x 1 x i64> @intrinsic_vadd_vx_sext_nxv1i64_nxv1i64_i64(<vscale x 1 x i64> %0, i32 %1, iXLen %2) nounwind {
+; RV32-LABEL: intrinsic_vadd_vx_sext_nxv1i64_nxv1i64_i64:
+; RV32:       # %bb.0: # %entry
+; RV32-NEXT:    vsetvli zero, a1, e64, m1, ta, mu
+; RV32-NEXT:    vadd.vx v8, v8, a0
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: intrinsic_vadd_vx_sext_nxv1i64_nxv1i64_i64:
+; RV64:       # %bb.0: # %entry
+; RV64-NEXT:    sext.w a0, a0
+; RV64-NEXT:    vsetvli zero, a1, e64, m1, ta, mu
+; RV64-NEXT:    vadd.vx v8, v8, a0
+; RV64-NEXT:    ret
+entry:
+  %ext = sext i32 %1 to i64
+  %a = call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.i64(
+    <vscale x 1 x i64> undef,
+    <vscale x 1 x i64> %0,
+    i64 %ext,
+    iXLen %2)
+
+  ret <vscale x 1 x i64> %a
+}
+
+define <vscale x 1 x i64> @intrinsic_vadd_vx_sextload_nxv1i64_nxv1i64_i64(<vscale x 1 x i64> %0, i32* %1, iXLen %2) nounwind {
+; CHECK-LABEL: intrinsic_vadd_vx_sextload_nxv1i64_nxv1i64_i64:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lw a0, 0(a0)
+; CHECK-NEXT:    vsetvli zero, a1, e64, m1, ta, mu
+; CHECK-NEXT:    vadd.vx v8, v8, a0
+; CHECK-NEXT:    ret
+entry:
+  %load = load i32, i32* %1
+  %ext = sext i32 %load to i64
+  %a = call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.i64(
+    <vscale x 1 x i64> undef,
+    <vscale x 1 x i64> %0,
+    i64 %ext,
+    iXLen %2)
+
+  ret <vscale x 1 x i64> %a
+}
+
 declare <vscale x 1 x i64> @llvm.riscv.vadd.mask.nxv1i64.i64(
   <vscale x 1 x i64>,
   <vscale x 1 x i64>,


        


More information about the llvm-commits mailing list