diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -7691,6 +7691,43 @@ break; } + case RISCVISD::VMV_S_X_VL: { + SDValue Src = N->getOperand(1); + if (Src.getOpcode() == RISCVISD::VMV_X_S && + Src.getOperand(0).getValueType() == N->getValueType(0) && + isa(N->getOperand(2))) { + if (N->getOperand(0).isUndef()) + return Src.getOperand(0); + if (cast(N->getOperand(2))->getZExtValue() == 0) + return N->getOperand(0); + SDLoc DL(N); + if (Src.getOperand(0).getOpcode() == RISCVISD::VSLIDEDOWN_VL && + Src.getOperand(0).getOperand(0).isUndef()) { + auto Slidedown = Src.getOperand(0); + if (isa(Slidedown.getOperand(4)) && + cast(Slidedown.getOperand(4))->getZExtValue() == 0) + return N->getOperand(0); + if ((!isa(Slidedown.getOperand(4)) || + 1 < cast(Slidedown.getOperand(4)) + ->getZExtValue()) && + !Slidedown.hasOneUse()) + return SDValue(); + return DAG.getNode(Slidedown.getOpcode(), DL, + Slidedown.getSimpleValueType(), N->getOperand(0), + Slidedown.getOperand(1), Slidedown.getOperand(2), + Slidedown.getOperand(3), Slidedown.getOperand(4)); + } + MVT VecVT = N->getSimpleValueType(0); + MVT XLenVT = Subtarget.getXLenVT(); + SDValue Mask, VL; + std::tie(Mask, VL) = getDefaultScalableVLOps(VecVT, DL, DAG, Subtarget); + SDValue Zero = DAG.getConstant(0, DL, XLenVT); + SDValue OneVL = DAG.getConstant(1, DL, XLenVT); + return DAG.getNode(RISCVISD::VSLIDEUP_VL, DL, VecVT, N->getOperand(0), + Src.getOperand(0), Zero, Mask, OneVL); + } + break; + } } return SDValue(); diff --git a/llvm/test/CodeGen/RISCV/rvv/vmv.s.x-vmv.x.s.ll b/llvm/test/CodeGen/RISCV/rvv/vmv.s.x-vmv.x.s.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/vmv.s.x-vmv.x.s.ll @@ -0,0 +1,49 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+experimental-v -riscv-v-vector-bits-min=128 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -riscv-v-vector-bits-min=128 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK + +define <4 x i32> @test_0_0(<4 x i32> %0, <4 x i32> %1) { +; CHECK-LABEL: test_0_0: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, tu, mu +; CHECK-NEXT: vslideup.vi v8, v9, 0 +; CHECK-NEXT: ret + %3 = extractelement <4 x i32> %1, i64 0 + %4 = insertelement <4 x i32> %0, i32 %3, i64 0 + ret <4 x i32> %4 +} + +define <4 x i32> @test_0_1(<4 x i32> %0, <4 x i32> %1) { +; CHECK-LABEL: test_0_1: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, tu, mu +; CHECK-NEXT: vslidedown.vi v8, v9, 1 +; CHECK-NEXT: ret + %3 = extractelement <4 x i32> %1, i64 1 + %4 = insertelement <4 x i32> %0, i32 %3, i64 0 + ret <4 x i32> %4 +} + +define <4 x i32> @test_1_0(<4 x i32> %0, <4 x i32> %1) { +; CHECK-LABEL: test_1_0: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, mu +; CHECK-NEXT: vslideup.vi v8, v9, 1 +; CHECK-NEXT: ret + %3 = extractelement <4 x i32> %1, i64 0 + %4 = insertelement <4 x i32> %0, i32 %3, i64 1 + ret <4 x i32> %4 +} + +define <4 x i32> @test_1_1(<4 x i32> %0, <4 x i32> %1) { +; CHECK-LABEL: test_1_1: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, mu +; CHECK-NEXT: vslidedown.vi v9, v9, 1 +; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, mu +; CHECK-NEXT: vslideup.vi v8, v9, 1 +; CHECK-NEXT: ret + %3 = extractelement <4 x i32> %1, i64 1 + %4 = insertelement <4 x i32> %0, i32 %3, i64 1 + ret <4 x i32> %4 +}