[llvm] [RISCV][GISEL] instruction-select for G_SPLAT_VECTOR (PR #111193)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 4 11:38:57 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Michael Maitland (michaelmaitland)

<details>
<summary>Changes</summary>

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.

---

Patch is 49.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/111193.diff


4 Files Affected:

- (modified) llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp (+39) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrGISel.td (+16) 
- (added) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/splatvector-rv32.mir (+600) 
- (added) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/splatvector-rv64.mir (+611) 


``````````diff
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:   ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/111193


More information about the llvm-commits mailing list