Skip to content

Commit cafaae8

Browse files
[GISEL] Add G_VSCALE instruction
1 parent 9405d5a commit cafaae8

File tree

8 files changed

+70
-0
lines changed

8 files changed

+70
-0
lines changed

llvm/docs/GlobalISel/GenericOpcode.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,17 @@ See the LLVM LangRef entry on '``llvm.lround.*'`` for details on behaviour.
607607
Vector Specific Operations
608608
--------------------------
609609

610+
G_VSCALE
611+
^^^^^^^^
612+
613+
Puts the value of the runtime ``vscale`` multiplied by the value in the source
614+
operand into the destination register. This can be useful in determining the
615+
actual runtime number of elements in a vector.
616+
617+
.. code-block::
618+
619+
%0:_(s32) = G_VSCALE 4
620+
610621
G_CONCAT_VECTORS
611622
^^^^^^^^^^^^^^^^
612623

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,18 @@ class MachineIRBuilder {
11241124
MachineInstrBuilder buildInsert(const DstOp &Res, const SrcOp &Src,
11251125
const SrcOp &Op, unsigned Index);
11261126

1127+
/// Build and insert \p Res = G_VSCALE \p MinElts
1128+
///
1129+
/// G_VSCALE puts the value of the runtime vscale multiplied by \p MinElts
1130+
/// into \p Res.
1131+
///
1132+
/// \pre setBasicBlock or setMI must have been called.
1133+
/// \pre \p Res must be a generic virtual register with scalar type.
1134+
/// \pre \p Src must be a generic virtual register with scalar type.
1135+
///
1136+
/// \return a MachineInstrBuilder for the newly created instruction.
1137+
MachineInstrBuilder buildVScale(const DstOp &Res, unsigned MinElts);
1138+
11271139
/// Build and insert a G_INTRINSIC instruction.
11281140
///
11291141
/// There are four different opcodes based on combinations of whether the

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,9 @@ HANDLE_TARGET_OPCODE(G_BR)
727727
/// Generic branch to jump table entry.
728728
HANDLE_TARGET_OPCODE(G_BRJT)
729729

730+
/// Generic vscale.
731+
HANDLE_TARGET_OPCODE(G_VSCALE)
732+
730733
/// Generic insertelement.
731734
HANDLE_TARGET_OPCODE(G_INSERT_VECTOR_ELT)
732735

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,15 @@ def G_MERGE_VALUES : GenericInstruction {
12891289
let variadicOpsType = type1;
12901290
}
12911291

1292+
// Generic vscale.
1293+
// Puts the value of the runtime vscale multiplied by the value in the source
1294+
// operand into the destination register.
1295+
def G_VSCALE : GenericInstruction {
1296+
let OutOperandList = (outs type0:$dst);
1297+
let InOperandList = (ins untyped_imm_0:$src);
1298+
let hasSideEffects = false;
1299+
}
1300+
12921301
/// Create a vector from multiple scalar registers. No implicit
12931302
/// conversion is performed (i.e. the result element type must be the
12941303
/// same as all source operands)

llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,11 @@ MachineInstrBuilder MachineIRBuilder::buildInsert(const DstOp &Res,
793793
return buildInstr(TargetOpcode::G_INSERT, Res, {Src, Op, uint64_t(Index)});
794794
}
795795

796+
MachineInstrBuilder MachineIRBuilder::buildVScale(const DstOp &Res,
797+
unsigned MinElts) {
798+
return buildInstr(TargetOpcode::G_VSCALE, {Res}, {uint64_t(MinElts)});
799+
}
800+
796801
static unsigned getIntrinsicOpcode(bool HasSideEffects, bool IsConvergent) {
797802
if (HasSideEffects && IsConvergent)
798803
return TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS;

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,17 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
16031603
report("G_BSWAP size must be a multiple of 16 bits", MI);
16041604
break;
16051605
}
1606+
case TargetOpcode::G_VSCALE: {
1607+
if (!MI->getOperand(1).isImm()) {
1608+
report("G_VSCALE operand #1 must be an immediate", MI);
1609+
break;
1610+
}
1611+
if (MI->getOperand(1).getImm() == 0) {
1612+
report("G_VSCALE immediate cannot be zero", MI);
1613+
break;
1614+
}
1615+
break;
1616+
}
16061617
case TargetOpcode::G_SHUFFLE_VECTOR: {
16071618
const MachineOperand &MaskOp = MI->getOperand(3);
16081619
if (!MaskOp.isShuffleMask()) {

llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,9 @@
616616
# DEBUG-NEXT: G_BRJT (opcode {{[0-9]+}}): 2 type indices
617617
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
618618
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
619+
# DEBUG-NEXT: G_VSCALE (opcode {{[0-9]+}}): 1 type index, 1 imm index
620+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
621+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
619622
# DEBUG-NEXT: G_INSERT_VECTOR_ELT (opcode {{[0-9]+}}): 3 type indices, 0 imm indices
620623
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
621624
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# RUN: not --crash llc -verify-machineinstrs -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
2+
# REQUIRES: aarch64-registered-target
3+
4+
---
5+
name: g_vscale
6+
body: |
7+
bb.0:
8+
9+
%1:_(s32) = G_CONSTANT 4
10+
11+
; CHECK: G_VSCALE operand #1 must be an immediate
12+
%2:_(s32) = G_VSCALE %1
13+
14+
; CHECK: G_VSCALE immediate cannot be zero
15+
%3:_(s32) = G_VSCALE 0
16+
...

0 commit comments

Comments
 (0)