[RISCV] Teach lowerSPLAT_VECTOR_PARTS to detect cases where Hi is sign extended from Lo.
authorCraig Topper <craig.topper@sifive.com>
Thu, 22 Apr 2021 03:15:39 +0000 (20:15 -0700)
committerCraig Topper <craig.topper@sifive.com>
Thu, 22 Apr 2021 03:24:23 +0000 (20:24 -0700)
This recognizes the case when Hi is (sra Lo, 31). We can use
SPLAT_VECTOR_I64 rather than splatting the high bits and
combining them in the vector register.

llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/test/CodeGen/RISCV/rvv/vsplats-i64.ll

index 28958b8..b624fb8 100644 (file)
@@ -2642,6 +2642,12 @@ SDValue RISCVTargetLowering::lowerSPLAT_VECTOR_PARTS(SDValue Op,
       return DAG.getNode(RISCVISD::SPLAT_VECTOR_I64, DL, VecVT, Lo);
   }
 
+  // Detect cases where Hi is (SRA Lo, 31) which means Hi is Lo sign extended.
+  if (Hi.getOpcode() == ISD::SRA && Hi.getOperand(0) == Lo &&
+      isa<ConstantSDNode>(Hi.getOperand(1)) &&
+      Hi.getConstantOperandVal(1) == 31)
+    return DAG.getNode(RISCVISD::SPLAT_VECTOR_I64, DL, VecVT, Lo);
+
   // Else, on RV32 we lower an i64-element SPLAT_VECTOR thus, being careful not
   // to accidentally sign-extend the 32-bit halves to the e64 SEW:
   // vmv.v.x vX, hi
index fded19c..819dded 100644 (file)
@@ -264,3 +264,45 @@ define <vscale x 8 x i64> @vadd_vx_nxv8i64_12(<vscale x 8 x i64> %v, i64 %a) {
   %vret = add <vscale x 8 x i64> %v, %splat
   ret <vscale x 8 x i64> %vret
 }
+
+define <vscale x 8 x i64> @vsplat_nxv8i64_13(i32 %a) {
+; RV32V-LABEL: vsplat_nxv8i64_13:
+; RV32V:       # %bb.0:
+; RV32V-NEXT:    vsetvli a1, zero, e64,m8,ta,mu
+; RV32V-NEXT:    vmv.v.x v8, a0
+; RV32V-NEXT:    ret
+;
+; RV64V-LABEL: vsplat_nxv8i64_13:
+; RV64V:       # %bb.0:
+; RV64V-NEXT:    sext.w a0, a0
+; RV64V-NEXT:    vsetvli a1, zero, e64,m8,ta,mu
+; RV64V-NEXT:    vmv.v.x v8, a0
+; RV64V-NEXT:    ret
+  %b = sext i32 %a to i64
+  %head = insertelement <vscale x 8 x i64> undef, i64 %b, i32 0
+  %splat = shufflevector <vscale x 8 x i64> %head, <vscale x 8 x i64> undef, <vscale x 8 x i32> zeroinitializer
+  ret <vscale x 8 x i64> %splat
+}
+
+define <vscale x 8 x i64> @vsplat_nxv8i64_14(i32 %a) {
+; RV32V-LABEL: vsplat_nxv8i64_14:
+; RV32V:       # %bb.0:
+; RV32V-NEXT:    vsetvli a1, zero, e64,m8,ta,mu
+; RV32V-NEXT:    vmv.v.x v8, a0
+; RV32V-NEXT:    addi a0, zero, 32
+; RV32V-NEXT:    vsll.vx v8, v8, a0
+; RV32V-NEXT:    vsrl.vx v8, v8, a0
+; RV32V-NEXT:    ret
+;
+; RV64V-LABEL: vsplat_nxv8i64_14:
+; RV64V:       # %bb.0:
+; RV64V-NEXT:    slli a0, a0, 32
+; RV64V-NEXT:    srli a0, a0, 32
+; RV64V-NEXT:    vsetvli a1, zero, e64,m8,ta,mu
+; RV64V-NEXT:    vmv.v.x v8, a0
+; RV64V-NEXT:    ret
+  %b = zext i32 %a to i64
+  %head = insertelement <vscale x 8 x i64> undef, i64 %b, i32 0
+  %splat = shufflevector <vscale x 8 x i64> %head, <vscale x 8 x i64> undef, <vscale x 8 x i32> zeroinitializer
+  ret <vscale x 8 x i64> %splat
+}