[llvm] [RISCV][VLOPT] Add support for VID and VIOTA (PR #120331)
Michael Maitland via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 17 15:25:23 PST 2024
https://github.com/michaelmaitland created https://github.com/llvm/llvm-project/pull/120331
We already cover vid in `llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir`
>From 41e2997c8c1a9149a5ff9f0ed43719b78aa7acfa Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Tue, 17 Dec 2024 15:23:41 -0800
Subject: [PATCH] [RISCV][VLOPT] Add support for VID and VIOTA
---
llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp | 15 +++++
llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll | 40 ++++++++++++
.../test/CodeGen/RISCV/rvv/vl-opt-op-info.mir | 61 +++++++++++++++++++
3 files changed, 116 insertions(+)
diff --git a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
index a9e5bb6ecd9b8a..e8719d02cfa0aa 100644
--- a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
+++ b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
@@ -412,6 +412,8 @@ static OperandInfo getOperandInfo(const MachineOperand &MO,
// Vector Compress Instruction
// EMUL=LMUL. EEW=SEW.
case RISCV::VCOMPRESS_VM:
+ // Vector Element Index Instruction
+ case RISCV::VID_V:
return OperandInfo(MIVLMul, MILog2SEW);
// Vector Widening Integer Add/Subtract
@@ -527,6 +529,15 @@ static OperandInfo getOperandInfo(const MachineOperand &MO,
return OperandInfo(RISCVVType::getEMULEqualsEEWDivSEWTimesLMUL(0, MI), 0);
}
+ // Vector Iota Instruction
+ // EEW=SEW and EMUL=LMUL, except the mask operand has EEW=1 and EMUL=
+ // (EEW/SEW)*LMUL. Mask operand is not handled before this switch.
+ case RISCV::VIOTA_M: {
+ if (IsMODef || MO.getOperandNo() == 1)
+ return OperandInfo(MIVLMul, MILog2SEW);
+ return OperandInfo(RISCVVType::getEMULEqualsEEWDivSEWTimesLMUL(0, MI), 0);
+ }
+
// Vector Integer Compare Instructions
// Dest EEW=1 and EMUL=(EEW/SEW)*LMUL. Source EEW=SEW and EMUL=LMUL.
case RISCV::VMSEQ_VI:
@@ -738,6 +749,8 @@ static bool isSupportedInstr(const MachineInstr &MI) {
// vmsbf.m set-before-first mask bit
// vmsif.m set-including-first mask bit
// vmsof.m set-only-first mask bit
+ // Vector Iota Instruction
+ // Vector Element Index Instruction
case RISCV::VMAND_MM:
case RISCV::VMNAND_MM:
case RISCV::VMANDN_MM:
@@ -749,6 +762,8 @@ static bool isSupportedInstr(const MachineInstr &MI) {
case RISCV::VMSBF_M:
case RISCV::VMSIF_M:
case RISCV::VMSOF_M:
+ case RISCV::VIOTA_M:
+ case RISCV::VID_V:
return true;
}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll b/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll
index faa41ec61cd127..55a50a15c788c2 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll
@@ -2885,3 +2885,43 @@ define <vscale x 1 x i32> @vmsof_m(<vscale x 1 x i1> %a, <vscale x 1 x i32> %c,
%3 = call <vscale x 1 x i32> @llvm.riscv.vadd.mask.nxv1i32.nxv1i32(<vscale x 1 x i32> %c, <vscale x 1 x i32> %c, <vscale x 1 x i32> %c, <vscale x 1 x i1> %2, iXLen %vl, iXLen 0)
ret <vscale x 1 x i32> %3
}
+
+define <vscale x 4 x i32> @viota_m(<vscale x 4 x i1> %a, <vscale x 4 x i32> %c, iXLen %vl) {
+; NOVLOPT-LABEL: viota_m:
+; NOVLOPT: # %bb.0:
+; NOVLOPT-NEXT: vsetvli a1, zero, e32, m2, ta, ma
+; NOVLOPT-NEXT: viota.m v10, v0
+; NOVLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma
+; NOVLOPT-NEXT: vadd.vv v8, v10, v8
+; NOVLOPT-NEXT: ret
+;
+; VLOPT-LABEL: viota_m:
+; VLOPT: # %bb.0:
+; VLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma
+; VLOPT-NEXT: viota.m v10, v0
+; VLOPT-NEXT: vadd.vv v8, v10, v8
+; VLOPT-NEXT: ret
+ %1 = call <vscale x 4 x i32> @llvm.riscv.viota.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i1> %a, iXLen -1)
+ %2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %c, iXLen %vl)
+ ret <vscale x 4 x i32> %2
+}
+
+define <vscale x 4 x i32> @vid.v(<vscale x 4 x i32> %c, iXLen %vl) {
+; NOVLOPT-LABEL: vid.v:
+; NOVLOPT: # %bb.0:
+; NOVLOPT-NEXT: vsetvli a1, zero, e32, m2, ta, ma
+; NOVLOPT-NEXT: vid.v v10
+; NOVLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma
+; NOVLOPT-NEXT: vadd.vv v8, v10, v8
+; NOVLOPT-NEXT: ret
+;
+; VLOPT-LABEL: vid.v:
+; VLOPT: # %bb.0:
+; VLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma
+; VLOPT-NEXT: vid.v v10
+; VLOPT-NEXT: vadd.vv v8, v10, v8
+; VLOPT-NEXT: ret
+ %1 = call <vscale x 4 x i32> @llvm.riscv.vid.nxv4i32(<vscale x 4 x i32> poison, iXLen -1)
+ %2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %c, iXLen %vl)
+ ret <vscale x 4 x i32> %2
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir b/llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir
index 8587ec136afd83..4a287847b22a72 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir
@@ -892,3 +892,64 @@ body: |
%x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0
%y:vr = PseudoVMV_V_V_MF2 $noreg, %x, 1, 3 /* e8 */, 0
...
+---
+name: viota_m_dest
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: viota_m_dest
+ ; CHECK: early-clobber %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
+ %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, -1, 3 /* e8 */, 0
+ %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 3 /* e8 */, 0
+...
+---
+name: viota_m_dest_incompatible_eew
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: viota_m_dest_incompatible_eew
+ ; CHECK: early-clobber %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 4 /* e16 */, 0 /* tu, mu */
+ %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, -1, 3 /* e8 */, 0
+ %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 4 /* e16 */, 0
+...
+---
+name: viota_m_dest_incompatible_emul
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: viota_m_dest_incompatible_emul
+ ; CHECK: early-clobber %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, -1, 3 /* e8 */, 0 /* tu, mu */
+ ; CHECK-NEXT: %y:vr = PseudoVADD_VV_MF2 $noreg, %x, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
+ %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, -1, 3 /* e8 */, 0
+ %y:vr = PseudoVADD_VV_MF2 $noreg, %x, $noreg, 1, 3 /* e8 */, 0
+...
+---
+name: viota_m_mask
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: viota_m_mask
+ ; CHECK: %x:vr = PseudoVMSEQ_VV_M1 $noreg, $noreg, 1, 3 /* e8 */
+ ; CHECK-NEXT: early-clobber %y:vr = PseudoVIOTA_M_M1 $noreg, %x, 1, 3 /* e8 */, 0 /* tu, mu */
+ %x:vr = PseudoVMSEQ_VV_M1 $noreg, $noreg, -1, 3 /* e8 */
+ %y:vr = PseudoVIOTA_M_M1 $noreg, %x, 1, 3 /* e8 */, 0
+...
+---
+name: viota_m_mask_incompatible_eew
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: viota_m_mask_incompatible_eew
+ ; CHECK: %x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0 /* e8 */
+ ; CHECK-NEXT: early-clobber %y:vr = PseudoVIOTA_M_M1 $noreg, %x, 1, 4 /* e16 */, 0 /* tu, mu */
+ %x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0
+ %y:vr = PseudoVIOTA_M_M1 $noreg, %x, 1, 4 /* e16 */, 0
+...
+---
+name: viota_m_mask_incompatible_emul
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: viota_m_mask_incompatible_emul
+ ; CHECK: %x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0 /* e8 */
+ ; CHECK-NEXT: early-clobber %y:vr = PseudoVIOTA_M_MF2 $noreg, %x, 1, 3 /* e8 */, 0 /* tu, mu */
+ %x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0
+ %y:vr = PseudoVIOTA_M_MF2 $noreg, %x, 1, 3 /* e8 */, 0
+...
+
More information about the llvm-commits
mailing list