[llvm] [RISCV][GISEL] instruction-select for G_SPLAT_VECTOR (PR #111193)
Michael Maitland via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 4 11:55:10 PDT 2024
https://github.com/michaelmaitland updated https://github.com/llvm/llvm-project/pull/111193
>From 85cf231ef1eaa29c59637166bbd1e162f252a657 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Tue, 1 Oct 2024 15:33:05 -0700
Subject: [PATCH 1/3] [RISCV][GISEL] instruction-select for G_SPLAT_VECTOR
SelectionDAG lowers ISD::SPLAT_VECTOR in a pre-instruction-select step too.
By taking this approach, we allow the generic combiner to operate on
G_SPLAT_VECTOR instead of RISCV Generic Opcodes.
---
.../RISCV/GISel/RISCVInstructionSelector.cpp | 39 ++
llvm/lib/Target/RISCV/RISCVInstrGISel.td | 16 +
.../rvv/splatvector-rv32.mir | 600 +++++++++++++++++
.../rvv/splatvector-rv64.mir | 611 ++++++++++++++++++
4 files changed, 1266 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/splatvector-rv32.mir
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/splatvector-rv64.mir
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index cfe8644b892298..eb3152ad768890 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -568,6 +568,18 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
return true;
}
+ // FIXME: We create a IMPLICIT_DEF and a G_CONSTANT in preISelLower when
+ // we encounter a G_SPLAT_VECTOR. We cannot select the G_CONSTANT until after
+ // the MI is lowered, since renderVLOp needs to see the G_CONSTANT. It would
+ // be nice if the InstructionSelector selected these instructions without
+ // needing to call select on them explicitly.
+ if (Opc == RISCV::G_VMV_V_X_VL || Opc == RISCV::G_VFMV_V_F_VL) {
+ MachineInstr *Passthru = MRI->getVRegDef(MI.getOperand(1).getReg());
+ MachineInstr *VL = MRI->getVRegDef(MI.getOperand(3).getReg());
+ if (selectImpl(MI, *CoverageInfo))
+ return select(*Passthru) && select(*VL);
+ }
+
if (selectImpl(MI, *CoverageInfo))
return true;
@@ -800,6 +812,33 @@ void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
replacePtrWithInt(MI.getOperand(1), MIB);
MI.setDesc(TII.get(TargetOpcode::G_AND));
MRI->setType(DstReg, sXLen);
+ break;
+ }
+ case TargetOpcode::G_SPLAT_VECTOR: {
+ // Convert integer SPLAT_VECTOR to VMV_V_X_VL and floating-point
+ // SPLAT_VECTOR to VFMV_V_F_VL to reduce isel burden.
+ Register Scalar = MI.getOperand(1).getReg();
+ bool IsGPRSplat = isRegInGprb(Scalar);
+ const LLT sXLen = LLT::scalar(STI.getXLen());
+ if (IsGPRSplat && TypeSize::isKnownLT(MRI->getType(Scalar).getSizeInBits(),
+ sXLen.getSizeInBits()))
+ Scalar = MIB.buildAnyExt(sXLen, Scalar).getReg(0);
+
+ // Convert MI in place, since select function is trying to select this
+ // instruction.
+ unsigned Opc = IsGPRSplat ? RISCV::G_VMV_V_X_VL : RISCV::G_VFMV_V_F_VL;
+ MI.setDesc(TII.get(Opc));
+ MI.removeOperand(1);
+ LLT VecTy = MRI->getType(MI.getOperand(0).getReg());
+ auto Passthru = MIB.buildUndef(VecTy);
+ auto VLMax = MIB.buildConstant(sXLen, -1);
+ MRI->setRegBank(Passthru.getReg(0), RBI.getRegBank(RISCV::VRBRegBankID));
+ MRI->setRegBank(VLMax.getReg(0), RBI.getRegBank(RISCV::GPRBRegBankID));
+ MachineInstrBuilder(*MI.getMF(), &MI)
+ .addUse(Passthru.getReg(0))
+ .addUse(Scalar)
+ .addUse(VLMax.getReg(0));
+ break;
}
}
}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrGISel.td b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
index f6bf74c565ab38..b26751a3c8e8e5 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
@@ -49,6 +49,22 @@ def G_VMSET_VL : RISCVGenericInstruction {
}
def : GINodeEquiv<G_VMSET_VL, riscv_vmset_vl>;
+// Pseudo equivalent to a RISCVISD::VMV_V_X_VL
+def G_VMV_V_X_VL : RISCVGenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$src);
+ let hasSideEffects = false;
+}
+def : GINodeEquiv<G_VMV_V_X_VL, riscv_vmv_v_x_vl>;
+
+// Pseudo equivalent to a RISCVISD::VFMV_V_F_VL
+def G_VFMV_V_F_VL : RISCVGenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$src);
+ let hasSideEffects = false;
+}
+def : GINodeEquiv<G_VFMV_V_F_VL, riscv_vfmv_v_f_vl>;
+
// Pseudo equivalent to a RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL. There is no
// record to mark as equivalent to using GINodeEquiv because it gets lowered
// before instruction selection.
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/splatvector-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/splatvector-rv32.mir
new file mode 100644
index 00000000000000..4066c4c36a8d53
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/splatvector-rv32.mir
@@ -0,0 +1,600 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+v,+m -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: splat_zero_nxv1i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF8_:%[0-9]+]]:vr = PseudoVMV_V_X_MF8 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 1 x s8>) = G_SPLAT_VECTOR %3(s32)
+ $v8 = COPY %0(<vscale x 1 x s8>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF4_:%[0-9]+]]:vr = PseudoVMV_V_X_MF4 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 2 x s8>) = G_SPLAT_VECTOR %3(s32)
+ $v8 = COPY %0(<vscale x 2 x s8>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv4i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF2_:%[0-9]+]]:vr = PseudoVMV_V_X_MF2 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 4 x s8>) = G_SPLAT_VECTOR %3(s32)
+ $v8 = COPY %0(<vscale x 4 x s8>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv8i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M1_:%[0-9]+]]:vr = PseudoVMV_V_X_M1 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 8 x s8>) = G_SPLAT_VECTOR %3(s32)
+ $v8 = COPY %0(<vscale x 8 x s8>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv16i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv16i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M2_:%[0-9]+]]:vrm2 = PseudoVMV_V_X_M2 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVMV_V_X_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 16 x s8>) = G_SPLAT_VECTOR %3(s32)
+ $v8m2 = COPY %0(<vscale x 16 x s8>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv32i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv32i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M4_:%[0-9]+]]:vrm4 = PseudoVMV_V_X_M4 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVMV_V_X_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 32 x s8>) = G_SPLAT_VECTOR %3(s32)
+ $v8m4 = COPY %0(<vscale x 32 x s8>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv64i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv64i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M8_:%[0-9]+]]:vrm8 = PseudoVMV_V_X_M8 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVMV_V_X_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 64 x s8>) = G_SPLAT_VECTOR %3(s32)
+ $v8m8 = COPY %0(<vscale x 64 x s8>)
+ PseudoRET implicit $v8m8
+
+...
+---
+name: splat_zero_nxv1i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF4_:%[0-9]+]]:vr = PseudoVMV_V_X_MF4 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 1 x s16>) = G_SPLAT_VECTOR %3(s32)
+ $v8 = COPY %0(<vscale x 1 x s16>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF2_:%[0-9]+]]:vr = PseudoVMV_V_X_MF2 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 2 x s16>) = G_SPLAT_VECTOR %3(s32)
+ $v8 = COPY %0(<vscale x 2 x s16>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv4i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M1_:%[0-9]+]]:vr = PseudoVMV_V_X_M1 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 4 x s16>) = G_SPLAT_VECTOR %3(s32)
+ $v8 = COPY %0(<vscale x 4 x s16>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv8i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M2_:%[0-9]+]]:vrm2 = PseudoVMV_V_X_M2 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVMV_V_X_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 8 x s16>) = G_SPLAT_VECTOR %3(s32)
+ $v8m2 = COPY %0(<vscale x 8 x s16>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv16i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv16i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M4_:%[0-9]+]]:vrm4 = PseudoVMV_V_X_M4 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVMV_V_X_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 16 x s16>) = G_SPLAT_VECTOR %3(s32)
+ $v8m4 = COPY %0(<vscale x 16 x s16>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv32i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv32i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M8_:%[0-9]+]]:vrm8 = PseudoVMV_V_X_M8 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVMV_V_X_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 32 x s16>) = G_SPLAT_VECTOR %3(s32)
+ $v8m8 = COPY %0(<vscale x 32 x s16>)
+ PseudoRET implicit $v8m8
+
+...
+---
+name: splat_zero_nxv1i32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1i32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF2_:%[0-9]+]]:vr = PseudoVMV_V_X_MF2 [[DEF]], [[COPY]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 1 x s32>) = G_SPLAT_VECTOR %1(s32)
+ $v8 = COPY %0(<vscale x 1 x s32>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2i32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2i32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M1_:%[0-9]+]]:vr = PseudoVMV_V_X_M1 [[DEF]], [[COPY]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 2 x s32>) = G_SPLAT_VECTOR %1(s32)
+ $v8 = COPY %0(<vscale x 2 x s32>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv4i32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4i32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M2_:%[0-9]+]]:vrm2 = PseudoVMV_V_X_M2 [[DEF]], [[COPY]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVMV_V_X_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %1:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 4 x s32>) = G_SPLAT_VECTOR %1(s32)
+ $v8m2 = COPY %0(<vscale x 4 x s32>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv8i32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8i32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M4_:%[0-9]+]]:vrm4 = PseudoVMV_V_X_M4 [[DEF]], [[COPY]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVMV_V_X_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %1:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 8 x s32>) = G_SPLAT_VECTOR %1(s32)
+ $v8m4 = COPY %0(<vscale x 8 x s32>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv16i32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv16i32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M8_:%[0-9]+]]:vrm8 = PseudoVMV_V_X_M8 [[DEF]], [[COPY]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVMV_V_X_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %1:gprb(s32) = G_CONSTANT i32 0
+ %0:vrb(<vscale x 16 x s32>) = G_SPLAT_VECTOR %1(s32)
+ $v8m8 = COPY %0(<vscale x 16 x s32>)
+ PseudoRET implicit $v8m8
+
+...
+---
+name: splat_zero_nxv1i64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1i64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[BuildPairF64Pseudo:%[0-9]+]]:fpr64 = BuildPairF64Pseudo [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVFMV_V_FPR64_M1_:%[0-9]+]]:vr = PseudoVFMV_V_FPR64_M1 [[DEF]], [[BuildPairF64Pseudo]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVFMV_V_FPR64_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %2:gprb(s32) = G_CONSTANT i32 0
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %1:fprb(s64) = G_MERGE_VALUES %2(s32), %3(s32)
+ %0:vrb(<vscale x 1 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8 = COPY %0(<vscale x 1 x s64>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2i64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2i64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[BuildPairF64Pseudo:%[0-9]+]]:fpr64 = BuildPairF64Pseudo [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVFMV_V_FPR64_M2_:%[0-9]+]]:vrm2 = PseudoVFMV_V_FPR64_M2 [[DEF]], [[BuildPairF64Pseudo]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVFMV_V_FPR64_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %2:gprb(s32) = G_CONSTANT i32 0
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %1:fprb(s64) = G_MERGE_VALUES %2(s32), %3(s32)
+ %0:vrb(<vscale x 2 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8m2 = COPY %0(<vscale x 2 x s64>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv4i64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4i64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[BuildPairF64Pseudo:%[0-9]+]]:fpr64 = BuildPairF64Pseudo [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVFMV_V_FPR64_M4_:%[0-9]+]]:vrm4 = PseudoVFMV_V_FPR64_M4 [[DEF]], [[BuildPairF64Pseudo]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVFMV_V_FPR64_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %2:gprb(s32) = G_CONSTANT i32 0
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %1:fprb(s64) = G_MERGE_VALUES %2(s32), %3(s32)
+ %0:vrb(<vscale x 4 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8m4 = COPY %0(<vscale x 4 x s64>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv8i64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8i64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[BuildPairF64Pseudo:%[0-9]+]]:fpr64 = BuildPairF64Pseudo [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVFMV_V_FPR64_M8_:%[0-9]+]]:vrm8 = PseudoVFMV_V_FPR64_M8 [[DEF]], [[BuildPairF64Pseudo]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVFMV_V_FPR64_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %2:gprb(s32) = G_CONSTANT i32 0
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %1:fprb(s64) = G_MERGE_VALUES %2(s32), %3(s32)
+ %0:vrb(<vscale x 8 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8m8 = COPY %0(<vscale x 8 x s64>)
+ PseudoRET implicit $v8m8
+
+...
+---
+name: splat_zero_nxv1f32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1f32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_W_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF2_:%[0-9]+]]:vr = PseudoVMV_V_X_MF2 [[DEF]], [[COPY1]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
+ %2:gprb(s32) = COPY %1(s32)
+ %0:vrb(<vscale x 1 x s32>) = G_SPLAT_VECTOR %2(s32)
+ $v8 = COPY %0(<vscale x 1 x s32>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2f32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2f32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_W_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M1_:%[0-9]+]]:vr = PseudoVMV_V_X_M1 [[DEF]], [[COPY1]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
+ %2:gprb(s32) = COPY %1(s32)
+ %0:vrb(<vscale x 2 x s32>) = G_SPLAT_VECTOR %2(s32)
+ $v8 = COPY %0(<vscale x 2 x s32>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv4f32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4f32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_W_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M2_:%[0-9]+]]:vrm2 = PseudoVMV_V_X_M2 [[DEF]], [[COPY1]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVMV_V_X_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
+ %2:gprb(s32) = COPY %1(s32)
+ %0:vrb(<vscale x 4 x s32>) = G_SPLAT_VECTOR %2(s32)
+ $v8m2 = COPY %0(<vscale x 4 x s32>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv8f32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8f32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_W_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M4_:%[0-9]+]]:vrm4 = PseudoVMV_V_X_M4 [[DEF]], [[COPY1]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVMV_V_X_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
+ %2:gprb(s32) = COPY %1(s32)
+ %0:vrb(<vscale x 8 x s32>) = G_SPLAT_VECTOR %2(s32)
+ $v8m4 = COPY %0(<vscale x 8 x s32>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv16f32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv16f32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_W_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M8_:%[0-9]+]]:vrm8 = PseudoVMV_V_X_M8 [[DEF]], [[COPY1]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVMV_V_X_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
+ %2:gprb(s32) = COPY %1(s32)
+ %0:vrb(<vscale x 16 x s32>) = G_SPLAT_VECTOR %2(s32)
+ $v8m8 = COPY %0(<vscale x 16 x s32>)
+ PseudoRET implicit $v8m8
+
+...
+---
+name: splat_zero_nxv1f64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1f64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[BuildPairF64Pseudo:%[0-9]+]]:fpr64 = BuildPairF64Pseudo [[COPY1]], [[COPY]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVFMV_V_FPR64_M1_:%[0-9]+]]:vr = PseudoVFMV_V_FPR64_M1 [[DEF]], [[BuildPairF64Pseudo]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVFMV_V_FPR64_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:fprb(s64) = G_FCONSTANT double 0.000000e+00
+ %0:vrb(<vscale x 1 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8 = COPY %0(<vscale x 1 x s64>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2f64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2f64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[BuildPairF64Pseudo:%[0-9]+]]:fpr64 = BuildPairF64Pseudo [[COPY1]], [[COPY]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVFMV_V_FPR64_M2_:%[0-9]+]]:vrm2 = PseudoVFMV_V_FPR64_M2 [[DEF]], [[BuildPairF64Pseudo]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVFMV_V_FPR64_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %1:fprb(s64) = G_FCONSTANT double 0.000000e+00
+ %0:vrb(<vscale x 2 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8m2 = COPY %0(<vscale x 2 x s64>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv4f64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4f64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[BuildPairF64Pseudo:%[0-9]+]]:fpr64 = BuildPairF64Pseudo [[COPY1]], [[COPY]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVFMV_V_FPR64_M4_:%[0-9]+]]:vrm4 = PseudoVFMV_V_FPR64_M4 [[DEF]], [[BuildPairF64Pseudo]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVFMV_V_FPR64_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %1:fprb(s64) = G_FCONSTANT double 0.000000e+00
+ %0:vrb(<vscale x 4 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8m4 = COPY %0(<vscale x 4 x s64>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv8f64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8f64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[BuildPairF64Pseudo:%[0-9]+]]:fpr64 = BuildPairF64Pseudo [[COPY1]], [[COPY]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVFMV_V_FPR64_M8_:%[0-9]+]]:vrm8 = PseudoVFMV_V_FPR64_M8 [[DEF]], [[BuildPairF64Pseudo]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVFMV_V_FPR64_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %1:fprb(s64) = G_FCONSTANT double 0.000000e+00
+ %0:vrb(<vscale x 8 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8m8 = COPY %0(<vscale x 8 x s64>)
+ PseudoRET implicit $v8m8
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/splatvector-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/splatvector-rv64.mir
new file mode 100644
index 00000000000000..09c6c3b65d7c05
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/splatvector-rv64.mir
@@ -0,0 +1,611 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=riscv64 -mattr=+v,+m -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: splat_zero_nxv1i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF8_:%[0-9]+]]:vr = PseudoVMV_V_X_MF8 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 1 x s8>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 1 x s8>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF4_:%[0-9]+]]:vr = PseudoVMV_V_X_MF4 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 2 x s8>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 2 x s8>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv4i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF2_:%[0-9]+]]:vr = PseudoVMV_V_X_MF2 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 4 x s8>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 4 x s8>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv8i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M1_:%[0-9]+]]:vr = PseudoVMV_V_X_M1 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 8 x s8>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 8 x s8>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv16i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv16i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M2_:%[0-9]+]]:vrm2 = PseudoVMV_V_X_M2 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVMV_V_X_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 16 x s8>) = G_SPLAT_VECTOR %2(s64)
+ $v8m2 = COPY %0(<vscale x 16 x s8>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv32i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv32i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M4_:%[0-9]+]]:vrm4 = PseudoVMV_V_X_M4 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVMV_V_X_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 32 x s8>) = G_SPLAT_VECTOR %2(s64)
+ $v8m4 = COPY %0(<vscale x 32 x s8>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv64i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv64i8
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M8_:%[0-9]+]]:vrm8 = PseudoVMV_V_X_M8 [[DEF]], [[COPY]], -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVMV_V_X_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 64 x s8>) = G_SPLAT_VECTOR %2(s64)
+ $v8m8 = COPY %0(<vscale x 64 x s8>)
+ PseudoRET implicit $v8m8
+
+...
+---
+name: splat_zero_nxv1i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF4_:%[0-9]+]]:vr = PseudoVMV_V_X_MF4 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 1 x s16>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 1 x s16>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF2_:%[0-9]+]]:vr = PseudoVMV_V_X_MF2 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 2 x s16>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 2 x s16>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv4i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M1_:%[0-9]+]]:vr = PseudoVMV_V_X_M1 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 4 x s16>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 4 x s16>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv8i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M2_:%[0-9]+]]:vrm2 = PseudoVMV_V_X_M2 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVMV_V_X_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 8 x s16>) = G_SPLAT_VECTOR %2(s64)
+ $v8m2 = COPY %0(<vscale x 8 x s16>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv16i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv16i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M4_:%[0-9]+]]:vrm4 = PseudoVMV_V_X_M4 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVMV_V_X_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 16 x s16>) = G_SPLAT_VECTOR %2(s64)
+ $v8m4 = COPY %0(<vscale x 16 x s16>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv32i16
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv32i16
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M8_:%[0-9]+]]:vrm8 = PseudoVMV_V_X_M8 [[DEF]], [[COPY]], -1, 4 /* e16 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVMV_V_X_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %3:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 32 x s16>) = G_SPLAT_VECTOR %2(s64)
+ $v8m8 = COPY %0(<vscale x 32 x s16>)
+ PseudoRET implicit $v8m8
+
+...
+---
+name: splat_zero_nxv1i32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1i32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF2_:%[0-9]+]]:vr = PseudoVMV_V_X_MF2 [[DEF]], [[COPY]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %1(s32)
+ %0:vrb(<vscale x 1 x s32>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 1 x s32>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2i32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2i32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M1_:%[0-9]+]]:vr = PseudoVMV_V_X_M1 [[DEF]], [[COPY]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %1(s32)
+ %0:vrb(<vscale x 2 x s32>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 2 x s32>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv4i32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4i32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M2_:%[0-9]+]]:vrm2 = PseudoVMV_V_X_M2 [[DEF]], [[COPY]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVMV_V_X_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %1:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %1(s32)
+ %0:vrb(<vscale x 4 x s32>) = G_SPLAT_VECTOR %2(s64)
+ $v8m2 = COPY %0(<vscale x 4 x s32>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv8i32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8i32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M4_:%[0-9]+]]:vrm4 = PseudoVMV_V_X_M4 [[DEF]], [[COPY]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVMV_V_X_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %1:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %1(s32)
+ %0:vrb(<vscale x 8 x s32>) = G_SPLAT_VECTOR %2(s64)
+ $v8m4 = COPY %0(<vscale x 8 x s32>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv16i32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv16i32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M8_:%[0-9]+]]:vrm8 = PseudoVMV_V_X_M8 [[DEF]], [[COPY]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVMV_V_X_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %1:gprb(s32) = G_CONSTANT i32 0
+ %2:gprb(s64) = G_ANYEXT %1(s32)
+ %0:vrb(<vscale x 16 x s32>) = G_SPLAT_VECTOR %2(s64)
+ $v8m8 = COPY %0(<vscale x 16 x s32>)
+ PseudoRET implicit $v8m8
+
+...
+---
+name: splat_zero_nxv1i64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1i64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M1_:%[0-9]+]]:vr = PseudoVMV_V_X_M1 [[DEF]], [[COPY]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:gprb(s64) = G_CONSTANT i64 0
+ %0:vrb(<vscale x 1 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8 = COPY %0(<vscale x 1 x s64>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2i64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2i64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M2_:%[0-9]+]]:vrm2 = PseudoVMV_V_X_M2 [[DEF]], [[COPY]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVMV_V_X_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %1:gprb(s64) = G_CONSTANT i64 0
+ %0:vrb(<vscale x 2 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8m2 = COPY %0(<vscale x 2 x s64>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv4i64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4i64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M4_:%[0-9]+]]:vrm4 = PseudoVMV_V_X_M4 [[DEF]], [[COPY]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVMV_V_X_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %1:gprb(s64) = G_CONSTANT i64 0
+ %0:vrb(<vscale x 4 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8m4 = COPY %0(<vscale x 4 x s64>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv8i64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8i64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M8_:%[0-9]+]]:vrm8 = PseudoVMV_V_X_M8 [[DEF]], [[COPY]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVMV_V_X_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %1:gprb(s64) = G_CONSTANT i64 0
+ %0:vrb(<vscale x 8 x s64>) = G_SPLAT_VECTOR %1(s64)
+ $v8m8 = COPY %0(<vscale x 8 x s64>)
+ PseudoRET implicit $v8m8
+
+...
+---
+name: splat_zero_nxv1f32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1f32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_W_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_MF2_:%[0-9]+]]:vr = PseudoVMV_V_X_MF2 [[DEF]], [[COPY1]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_MF2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
+ %3:gprb(s32) = COPY %1(s32)
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 1 x s32>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 1 x s32>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2f32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2f32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_W_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M1_:%[0-9]+]]:vr = PseudoVMV_V_X_M1 [[DEF]], [[COPY1]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
+ %3:gprb(s32) = COPY %1(s32)
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 2 x s32>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 2 x s32>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv4f32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv4f32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_W_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M2_:%[0-9]+]]:vrm2 = PseudoVMV_V_X_M2 [[DEF]], [[COPY1]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVMV_V_X_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
+ %3:gprb(s32) = COPY %1(s32)
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 4 x s32>) = G_SPLAT_VECTOR %2(s64)
+ $v8m2 = COPY %0(<vscale x 4 x s32>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxv8f32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8f32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_W_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M4_:%[0-9]+]]:vrm4 = PseudoVMV_V_X_M4 [[DEF]], [[COPY1]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVMV_V_X_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
+ %3:gprb(s32) = COPY %1(s32)
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 8 x s32>) = G_SPLAT_VECTOR %2(s64)
+ $v8m4 = COPY %0(<vscale x 8 x s32>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv16f32
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv16f32
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_W_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M8_:%[0-9]+]]:vrm8 = PseudoVMV_V_X_M8 [[DEF]], [[COPY1]], -1, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVMV_V_X_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
+ %3:gprb(s32) = COPY %1(s32)
+ %2:gprb(s64) = G_ANYEXT %3(s32)
+ %0:vrb(<vscale x 16 x s32>) = G_SPLAT_VECTOR %2(s64)
+ $v8m8 = COPY %0(<vscale x 16 x s32>)
+ PseudoRET implicit $v8m8
+
+...
+---
+name: splat_zero_nxv1f64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv1f64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_D_X:%[0-9]+]]:fpr64 = FMV_D_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_D_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M1_:%[0-9]+]]:vr = PseudoVMV_V_X_M1 [[DEF]], [[COPY1]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8 = COPY [[PseudoVMV_V_X_M1_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8
+ %1:fprb(s64) = G_FCONSTANT double 0.000000e+00
+ %2:gprb(s64) = COPY %1(s64)
+ %0:vrb(<vscale x 1 x s64>) = G_SPLAT_VECTOR %2(s64)
+ $v8 = COPY %0(<vscale x 1 x s64>)
+ PseudoRET implicit $v8
+
+...
+---
+name: splat_zero_nxv2f64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv2f64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_D_X:%[0-9]+]]:fpr64 = FMV_D_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_D_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm2 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M2_:%[0-9]+]]:vrm2 = PseudoVMV_V_X_M2 [[DEF]], [[COPY1]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m2 = COPY [[PseudoVMV_V_X_M2_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m2
+ %1:fprb(s64) = G_FCONSTANT double 0.000000e+00
+ %2:gprb(s64) = COPY %1(s64)
+ %0:vrb(<vscale x 2 x s64>) = G_SPLAT_VECTOR %2(s64)
+ $v8m2 = COPY %0(<vscale x 2 x s64>)
+ PseudoRET implicit $v8m2
+
+...
+---
+name: splat_zero_nxvf64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxvf64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_D_X:%[0-9]+]]:fpr64 = FMV_D_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_D_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm4 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M4_:%[0-9]+]]:vrm4 = PseudoVMV_V_X_M4 [[DEF]], [[COPY1]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m4 = COPY [[PseudoVMV_V_X_M4_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m4
+ %1:fprb(s64) = G_FCONSTANT double 0.000000e+00
+ %2:gprb(s64) = COPY %1(s64)
+ %0:vrb(<vscale x 4 x s64>) = G_SPLAT_VECTOR %2(s64)
+ $v8m4 = COPY %0(<vscale x 4 x s64>)
+ PseudoRET implicit $v8m4
+
+...
+---
+name: splat_zero_nxv8f64
+legalized: true
+regBankSelected: true
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: splat_zero_nxv8f64
+ ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $x0
+ ; CHECK-NEXT: [[FMV_D_X:%[0-9]+]]:fpr64 = FMV_D_X [[COPY]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[FMV_D_X]]
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vrm8 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[PseudoVMV_V_X_M8_:%[0-9]+]]:vrm8 = PseudoVMV_V_X_M8 [[DEF]], [[COPY1]], -1, 6 /* e64 */, 0 /* tu, mu */
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVMV_V_X_M8_]]
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %1:fprb(s64) = G_FCONSTANT double 0.000000e+00
+ %2:gprb(s64) = COPY %1(s64)
+ %0:vrb(<vscale x 8 x s64>) = G_SPLAT_VECTOR %2(s64)
+ $v8m8 = COPY %0(<vscale x 8 x s64>)
+ PseudoRET implicit $v8m8
+
+...
>From 6a91a29a6e5d165fce2a8c0afb7341176fc97aeb Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Fri, 4 Oct 2024 11:47:59 -0700
Subject: [PATCH 2/3] fixup! add end-to-end tests
---
.../RISCV/GlobalISel/rvv/splat-vector.ll | 427 +++++++++++++++++-
1 file changed, 424 insertions(+), 3 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rvv/splat-vector.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rvv/splat-vector.ll
index 4e58c4dcec2d85..1381c2f7a2bee3 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/rvv/splat-vector.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/rvv/splat-vector.ll
@@ -67,7 +67,428 @@ define <vscale x 64 x i1> @splat_zero_nxv64i1() {
ret <vscale x 64 x i1> zeroinitializer
}
+define <vscale x 1 x i8> @splat_zero_nxv1i8() {
+; CHECK-LABEL: splat_zero_nxv1i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, mf8, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 1 x i8> zeroinitializer
+}
+
+define <vscale x 2 x i8> @splat_zero_nxv2i8() {
+; CHECK-LABEL: splat_zero_nxv2i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, mf4, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 2 x i8> zeroinitializer
+}
+
+define <vscale x 4 x i8> @splat_zero_nxv4i8() {
+; CHECK-LABEL: splat_zero_nxv4i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, mf2, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 4 x i8> zeroinitializer
+}
+
+define <vscale x 8 x i8> @splat_zero_nxv8i8() {
+; CHECK-LABEL: splat_zero_nxv8i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 8 x i8> zeroinitializer
+}
+
+define <vscale x 16 x i8> @splat_zero_nxv16i8() {
+; CHECK-LABEL: splat_zero_nxv16i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, m2, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 16 x i8> zeroinitializer
+}
+
+define <vscale x 32 x i8> @splat_zero_nxv32i8() {
+; CHECK-LABEL: splat_zero_nxv32i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, m4, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 32 x i8> zeroinitializer
+}
+
+define <vscale x 64 x i8> @splat_zero_nxv64i8() {
+; CHECK-LABEL: splat_zero_nxv64i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, m8, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 64 x i8> zeroinitializer
+}
+
+define <vscale x 1 x i16> @splat_zero_nxv1i16() {
+; CHECK-LABEL: splat_zero_nxv1i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e16, mf4, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 1 x i16> zeroinitializer
+}
+
+define <vscale x 2 x i16> @splat_zero_nxv2i16() {
+; CHECK-LABEL: splat_zero_nxv2i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 2 x i16> zeroinitializer
+}
+
+define <vscale x 4 x i16> @splat_zero_nxv4i16() {
+; CHECK-LABEL: splat_zero_nxv4i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e16, m1, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 4 x i16> zeroinitializer
+}
+
+define <vscale x 8 x i16> @splat_zero_nxv8i16() {
+; CHECK-LABEL: splat_zero_nxv8i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e16, m2, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 8 x i16> zeroinitializer
+}
+
+define <vscale x 16 x i16> @splat_zero_nxv16i16() {
+; CHECK-LABEL: splat_zero_nxv16i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e16, m4, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 16 x i16> zeroinitializer
+}
+
+define <vscale x 32 x i16> @splat_zero_nxv32i16() {
+; CHECK-LABEL: splat_zero_nxv32i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e16, m8, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 32 x i16> zeroinitializer
+}
+
+define <vscale x 1 x i32> @splat_zero_nxv1i32() {
+; CHECK-LABEL: splat_zero_nxv1i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 1 x i32> zeroinitializer
+}
+
+define <vscale x 2 x i32> @splat_zero_nxv2i32() {
+; CHECK-LABEL: splat_zero_nxv2i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 2 x i32> zeroinitializer
+}
+
+define <vscale x 4 x i32> @splat_zero_nxv4i32() {
+; CHECK-LABEL: splat_zero_nxv4i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 4 x i32> zeroinitializer
+}
+
+define <vscale x 8 x i32> @splat_zero_nxv8i32() {
+; CHECK-LABEL: splat_zero_nxv8i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 8 x i32> zeroinitializer
+}
+
+define <vscale x 16 x i32> @splat_zero_nxv16i32() {
+; CHECK-LABEL: splat_zero_nxv16i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e32, m8, ta, ma
+; CHECK-NEXT: vmv.v.x v8, zero
+; CHECK-NEXT: ret
+ ret <vscale x 16 x i32> zeroinitializer
+}
+
+define <vscale x 1 x i64> @splat_zero_nxv1i64() {
+; RV32-LABEL: splat_zero_nxv1i64:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -16
+; RV32-NEXT: .cfi_def_cfa_offset 16
+; RV32-NEXT: sw zero, 8(sp)
+; RV32-NEXT: sw zero, 12(sp)
+; RV32-NEXT: fld fa5, 8(sp)
+; RV32-NEXT: vsetvli a0, zero, e64, m1, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv1i64:
+; RV64: # %bb.0:
+; RV64-NEXT: vsetvli a0, zero, e64, m1, ta, ma
+; RV64-NEXT: vmv.v.x v8, zero
+; RV64-NEXT: ret
+ ret <vscale x 1 x i64> zeroinitializer
+}
+
+define <vscale x 2 x i64> @splat_zero_nxv2i64() {
+; RV32-LABEL: splat_zero_nxv2i64:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -16
+; RV32-NEXT: .cfi_def_cfa_offset 16
+; RV32-NEXT: sw zero, 8(sp)
+; RV32-NEXT: sw zero, 12(sp)
+; RV32-NEXT: fld fa5, 8(sp)
+; RV32-NEXT: vsetvli a0, zero, e64, m2, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv2i64:
+; RV64: # %bb.0:
+; RV64-NEXT: vsetvli a0, zero, e64, m2, ta, ma
+; RV64-NEXT: vmv.v.x v8, zero
+; RV64-NEXT: ret
+ ret <vscale x 2 x i64> zeroinitializer
+}
+
+define <vscale x 4 x i64> @splat_zero_nxv4i64() {
+; RV32-LABEL: splat_zero_nxv4i64:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -16
+; RV32-NEXT: .cfi_def_cfa_offset 16
+; RV32-NEXT: sw zero, 8(sp)
+; RV32-NEXT: sw zero, 12(sp)
+; RV32-NEXT: fld fa5, 8(sp)
+; RV32-NEXT: vsetvli a0, zero, e64, m4, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv4i64:
+; RV64: # %bb.0:
+; RV64-NEXT: vsetvli a0, zero, e64, m4, ta, ma
+; RV64-NEXT: vmv.v.x v8, zero
+; RV64-NEXT: ret
+ ret <vscale x 4 x i64> zeroinitializer
+}
+
+define <vscale x 8 x i64> @splat_zero_nxv8i64() {
+; RV32-LABEL: splat_zero_nxv8i64:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -16
+; RV32-NEXT: .cfi_def_cfa_offset 16
+; RV32-NEXT: sw zero, 8(sp)
+; RV32-NEXT: sw zero, 12(sp)
+; RV32-NEXT: fld fa5, 8(sp)
+; RV32-NEXT: vsetvli a0, zero, e64, m8, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv8i64:
+; RV64: # %bb.0:
+; RV64-NEXT: vsetvli a0, zero, e64, m8, ta, ma
+; RV64-NEXT: vmv.v.x v8, zero
+; RV64-NEXT: ret
+ ret <vscale x 8 x i64> zeroinitializer
+}
+
+define <vscale x 1 x float> @splat_zero_nxv1f32() {
+; RV32-LABEL: splat_zero_nxv1f32:
+; RV32: # %bb.0:
+; RV32-NEXT: fmv.w.x fa5, zero
+; RV32-NEXT: vsetvli a0, zero, e32, mf2, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv1f32:
+; RV64: # %bb.0:
+; RV64-NEXT: fmv.w.x fa5, zero
+; RV64-NEXT: fmv.x.w a0, fa5
+; RV64-NEXT: vsetvli a1, zero, e32, mf2, ta, ma
+; RV64-NEXT: vmv.v.x v8, a0
+; RV64-NEXT: ret
+ ret <vscale x 1 x float> zeroinitializer
+}
+
+define <vscale x 2 x float> @splat_zero_nxv2f32() {
+; RV32-LABEL: splat_zero_nxv2f32:
+; RV32: # %bb.0:
+; RV32-NEXT: fmv.w.x fa5, zero
+; RV32-NEXT: vsetvli a0, zero, e32, m1, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv2f32:
+; RV64: # %bb.0:
+; RV64-NEXT: fmv.w.x fa5, zero
+; RV64-NEXT: fmv.x.w a0, fa5
+; RV64-NEXT: vsetvli a1, zero, e32, m1, ta, ma
+; RV64-NEXT: vmv.v.x v8, a0
+; RV64-NEXT: ret
+ ret <vscale x 2 x float> zeroinitializer
+}
+
+define <vscale x 4 x float> @splat_zero_nxv4f32() {
+; RV32-LABEL: splat_zero_nxv4f32:
+; RV32: # %bb.0:
+; RV32-NEXT: fmv.w.x fa5, zero
+; RV32-NEXT: vsetvli a0, zero, e32, m2, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv4f32:
+; RV64: # %bb.0:
+; RV64-NEXT: fmv.w.x fa5, zero
+; RV64-NEXT: fmv.x.w a0, fa5
+; RV64-NEXT: vsetvli a1, zero, e32, m2, ta, ma
+; RV64-NEXT: vmv.v.x v8, a0
+; RV64-NEXT: ret
+ ret <vscale x 4 x float> zeroinitializer
+}
+
+define <vscale x 8 x float> @splat_zero_nxv8f32() {
+; RV32-LABEL: splat_zero_nxv8f32:
+; RV32: # %bb.0:
+; RV32-NEXT: fmv.w.x fa5, zero
+; RV32-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv8f32:
+; RV64: # %bb.0:
+; RV64-NEXT: fmv.w.x fa5, zero
+; RV64-NEXT: fmv.x.w a0, fa5
+; RV64-NEXT: vsetvli a1, zero, e32, m4, ta, ma
+; RV64-NEXT: vmv.v.x v8, a0
+; RV64-NEXT: ret
+ ret <vscale x 8 x float> zeroinitializer
+}
+
+define <vscale x 16 x float> @splat_zero_nxv16f32() {
+; RV32-LABEL: splat_zero_nxv16f32:
+; RV32: # %bb.0:
+; RV32-NEXT: fmv.w.x fa5, zero
+; RV32-NEXT: vsetvli a0, zero, e32, m8, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv16f32:
+; RV64: # %bb.0:
+; RV64-NEXT: fmv.w.x fa5, zero
+; RV64-NEXT: fmv.x.w a0, fa5
+; RV64-NEXT: vsetvli a1, zero, e32, m8, ta, ma
+; RV64-NEXT: vmv.v.x v8, a0
+; RV64-NEXT: ret
+ ret <vscale x 16 x float> zeroinitializer
+}
+
+define <vscale x 1 x double> @splat_zero_nxv1f64() {
+; RV32-LABEL: splat_zero_nxv1f64:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -16
+; RV32-NEXT: .cfi_def_cfa_offset 16
+; RV32-NEXT: sw zero, 8(sp)
+; RV32-NEXT: sw zero, 12(sp)
+; RV32-NEXT: fld fa5, 8(sp)
+; RV32-NEXT: vsetvli a0, zero, e64, m1, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv1f64:
+; RV64: # %bb.0:
+; RV64-NEXT: fmv.d.x fa5, zero
+; RV64-NEXT: vsetvli a0, zero, e64, m1, ta, ma
+; RV64-NEXT: vfmv.v.f v8, fa5
+; RV64-NEXT: ret
+ ret <vscale x 1 x double> zeroinitializer
+}
+
+define <vscale x 2 x double> @splat_zero_nxv2f64() {
+; RV32-LABEL: splat_zero_nxv2f64:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -16
+; RV32-NEXT: .cfi_def_cfa_offset 16
+; RV32-NEXT: sw zero, 8(sp)
+; RV32-NEXT: sw zero, 12(sp)
+; RV32-NEXT: fld fa5, 8(sp)
+; RV32-NEXT: vsetvli a0, zero, e64, m2, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv2f64:
+; RV64: # %bb.0:
+; RV64-NEXT: fmv.d.x fa5, zero
+; RV64-NEXT: vsetvli a0, zero, e64, m2, ta, ma
+; RV64-NEXT: vfmv.v.f v8, fa5
+; RV64-NEXT: ret
+ ret <vscale x 2 x double> zeroinitializer
+}
+
+define <vscale x 4 x double> @splat_zero_nxv4f64() {
+; RV32-LABEL: splat_zero_nxv4f64:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -16
+; RV32-NEXT: .cfi_def_cfa_offset 16
+; RV32-NEXT: sw zero, 8(sp)
+; RV32-NEXT: sw zero, 12(sp)
+; RV32-NEXT: fld fa5, 8(sp)
+; RV32-NEXT: vsetvli a0, zero, e64, m4, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv4f64:
+; RV64: # %bb.0:
+; RV64-NEXT: fmv.d.x fa5, zero
+; RV64-NEXT: vsetvli a0, zero, e64, m4, ta, ma
+; RV64-NEXT: vfmv.v.f v8, fa5
+; RV64-NEXT: ret
+ ret <vscale x 4 x double> zeroinitializer
+}
+
+define <vscale x 8 x double> @splat_zero_nxv8f64() {
+; RV32-LABEL: splat_zero_nxv8f64:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -16
+; RV32-NEXT: .cfi_def_cfa_offset 16
+; RV32-NEXT: sw zero, 8(sp)
+; RV32-NEXT: sw zero, 12(sp)
+; RV32-NEXT: fld fa5, 8(sp)
+; RV32-NEXT: vsetvli a0, zero, e64, m8, ta, ma
+; RV32-NEXT: vfmv.v.f v8, fa5
+; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: ret
+;
+; RV64-LABEL: splat_zero_nxv8f64:
+; RV64: # %bb.0:
+; RV64-NEXT: fmv.d.x fa5, zero
+; RV64-NEXT: vsetvli a0, zero, e64, m8, ta, ma
+; RV64-NEXT: vfmv.v.f v8, fa5
+; RV64-NEXT: ret
+ ret <vscale x 8 x double> zeroinitializer
+}
+
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; RV32: {{.*}}
-; RV64: {{.*}}
>From 5d7793293fd2e17ac7b03cd6d4626de93ee5f7dd Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Fri, 4 Oct 2024 11:54:45 -0700
Subject: [PATCH 3/3] fixup! only do this when we start with G_SPLAT_VECTOR
---
llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index eb3152ad768890..630f0aa0f1141a 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -530,8 +530,9 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
MachineFunction &MF = *MBB.getParent();
MachineIRBuilder MIB(MI);
- preISelLower(MI, MIB);
const unsigned Opc = MI.getOpcode();
+ bool OpcWasGSplatVector = Opc == TargetOpcode::G_SPLAT_VECTOR;
+ preISelLower(MI, MIB);
if (!MI.isPreISelOpcode() || Opc == TargetOpcode::G_PHI) {
if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) {
@@ -573,7 +574,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
// the MI is lowered, since renderVLOp needs to see the G_CONSTANT. It would
// be nice if the InstructionSelector selected these instructions without
// needing to call select on them explicitly.
- if (Opc == RISCV::G_VMV_V_X_VL || Opc == RISCV::G_VFMV_V_F_VL) {
+ if (OpcWasGSplatVector) {
MachineInstr *Passthru = MRI->getVRegDef(MI.getOperand(1).getReg());
MachineInstr *VL = MRI->getVRegDef(MI.getOperand(3).getReg());
if (selectImpl(MI, *CoverageInfo))
More information about the llvm-commits
mailing list