From: Craig Topper Date: Thu, 22 Apr 2021 03:15:39 +0000 (-0700) Subject: [RISCV] Teach lowerSPLAT_VECTOR_PARTS to detect cases where Hi is sign extended from Lo. X-Git-Tag: llvmorg-14-init~8846 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f6d8cf7798440f303d5a273999e6647cbe795ac6;p=platform%2Fupstream%2Fllvm.git [RISCV] Teach lowerSPLAT_VECTOR_PARTS to detect cases where Hi is sign extended from Lo. 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. --- diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 28958b8..b624fb8 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -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(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 diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-i64.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-i64.ll index fded19c..819dded 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vsplats-i64.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-i64.ll @@ -264,3 +264,45 @@ define @vadd_vx_nxv8i64_12( %v, i64 %a) { %vret = add %v, %splat ret %vret } + +define @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 undef, i64 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + ret %splat +} + +define @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 undef, i64 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + ret %splat +}