[GISEL] Add G_VSCALE instruction (#84542)

This commit is contained in:
Michael Maitland
2024-03-12 20:22:49 -04:00
committed by GitHub
parent e2468bf16a
commit 2f400a2fd7
8 changed files with 92 additions and 0 deletions

View File

@@ -607,6 +607,17 @@ See the LLVM LangRef entry on '``llvm.lround.*'`` for details on behaviour.
Vector Specific Operations
--------------------------
G_VSCALE
^^^^^^^^
Puts the value of the runtime ``vscale`` multiplied by the value in the source
operand into the destination register. This can be useful in determining the
actual runtime number of elements in a vector.
.. code-block::
%0:_(s32) = G_VSCALE 4
G_INSERT_SUBVECTOR
^^^^^^^^^^^^^^^^^^

View File

@@ -1143,6 +1143,28 @@ public:
MachineInstrBuilder buildInsert(const DstOp &Res, const SrcOp &Src,
const SrcOp &Op, unsigned Index);
/// Build and insert \p Res = G_VSCALE \p MinElts
///
/// G_VSCALE puts the value of the runtime vscale multiplied by \p MinElts
/// into \p Res.
///
/// \pre setBasicBlock or setMI must have been called.
/// \pre \p Res must be a generic virtual register with scalar type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildVScale(const DstOp &Res, unsigned MinElts);
/// Build and insert \p Res = G_VSCALE \p MinElts
///
/// G_VSCALE puts the value of the runtime vscale multiplied by \p MinElts
/// into \p Res.
///
/// \pre setBasicBlock or setMI must have been called.
/// \pre \p Res must be a generic virtual register with scalar type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildVScale(const DstOp &Res, const ConstantInt &MinElts);
/// Build and insert a G_INTRINSIC instruction.
///
/// There are four different opcodes based on combinations of whether the

View File

@@ -727,6 +727,9 @@ HANDLE_TARGET_OPCODE(G_BR)
/// Generic branch to jump table entry.
HANDLE_TARGET_OPCODE(G_BRJT)
/// Generic vscale.
HANDLE_TARGET_OPCODE(G_VSCALE)
/// Generic insert subvector.
HANDLE_TARGET_OPCODE(G_INSERT_SUBVECTOR)

View File

@@ -1289,6 +1289,15 @@ def G_MERGE_VALUES : GenericInstruction {
let variadicOpsType = type1;
}
// Generic vscale.
// Puts the value of the runtime vscale multiplied by the value in the source
// operand into the destination register.
def G_VSCALE : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$src);
let hasSideEffects = false;
}
/// Create a vector from multiple scalar registers. No implicit
/// conversion is performed (i.e. the result element type must be the
/// same as all source operands)

View File

@@ -793,6 +793,24 @@ MachineInstrBuilder MachineIRBuilder::buildInsert(const DstOp &Res,
return buildInstr(TargetOpcode::G_INSERT, Res, {Src, Op, uint64_t(Index)});
}
MachineInstrBuilder MachineIRBuilder::buildVScale(const DstOp &Res,
unsigned MinElts) {
auto IntN = IntegerType::get(getMF().getFunction().getContext(),
Res.getLLTTy(*getMRI()).getScalarSizeInBits());
ConstantInt *CI = ConstantInt::get(IntN, MinElts);
return buildVScale(Res, *CI);
}
MachineInstrBuilder MachineIRBuilder::buildVScale(const DstOp &Res,
const ConstantInt &MinElts) {
auto VScale = buildInstr(TargetOpcode::G_VSCALE);
VScale->setDebugLoc(DebugLoc());
Res.addDefToMIB(*getMRI(), VScale);
VScale.addCImm(&MinElts);
return VScale;
}
static unsigned getIntrinsicOpcode(bool HasSideEffects, bool IsConvergent) {
if (HasSideEffects && IsConvergent)
return TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS;

View File

@@ -1613,6 +1613,17 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
report("G_BSWAP size must be a multiple of 16 bits", MI);
break;
}
case TargetOpcode::G_VSCALE: {
if (!MI->getOperand(1).isCImm()) {
report("G_VSCALE operand must be cimm", MI);
break;
}
if (MI->getOperand(1).getCImm()->isZero()) {
report("G_VSCALE immediate cannot be zero", MI);
break;
}
break;
}
case TargetOpcode::G_INSERT_SUBVECTOR: {
const MachineOperand &Src0Op = MI->getOperand(1);
if (!Src0Op.isReg()) {

View File

@@ -616,6 +616,9 @@
# DEBUG-NEXT: G_BRJT (opcode {{[0-9]+}}): 2 type indices
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
# DEBUG-NEXT: G_VSCALE (opcode {{[0-9]+}}): 1 type index, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: G_INSERT_SUBVECTOR (opcode {{[0-9]+}}): 2 type indices, 1 imm index
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined

View File

@@ -0,0 +1,15 @@
# RUN: not --crash llc -verify-machineinstrs -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
---
name: g_vscale
body: |
bb.0:
%1:_(s32) = G_CONSTANT i32 4
; CHECK: G_VSCALE operand must be cimm
%2:_(s32) = G_VSCALE %1
; CHECK: G_VSCALE immediate cannot be zero
%3:_(s32) = G_VSCALE i32 0
...