Skip to content

Commit a5d09f4

Browse files
author
Thorsten Schütt
authored
[GlobalISel] Add G_STEP_VECTOR instruction (#115598)
aka llvm.stepvector Intrinsic
1 parent a4e507d commit a5d09f4

File tree

10 files changed

+127
-0
lines changed

10 files changed

+127
-0
lines changed

llvm/docs/GlobalISel/GenericOpcode.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,24 @@ The type of the operand must be equal to or larger than the vector element
753753
type. If the operand is larger than the vector element type, the scalar is
754754
implicitly truncated to the vector element type.
755755

756+
G_STEP_VECTOR
757+
^^^^^^^^^^^^^
758+
759+
Create a scalable vector where all lanes are linear sequences starting at 0
760+
with a given unsigned step.
761+
762+
The type of the operand must be equal to the vector element type. Arithmetic
763+
is performed modulo the bitwidth of the element. The step must be > 0.
764+
Otherwise the vector is zero.
765+
766+
.. code-block::
767+
768+
%0:_(<vscale x 2 x s64>) = G_STEP_VECTOR i64 4
769+
770+
%1:_(<vscale x s32>) = G_STEP_VECTOR i32 4
771+
772+
0, 1*Step, 2*Step, 3*Step, 4*Step, ...
773+
756774
G_VECTOR_COMPRESS
757775
^^^^^^^^^^^^^^^^^
758776

llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,18 @@ class GVScale : public GenericMachineInstr {
906906
};
907907
};
908908

909+
/// Represents a step vector.
910+
class GStepVector : public GenericMachineInstr {
911+
public:
912+
uint64_t getStep() const {
913+
return getOperand(1).getCImm()->getValue().getZExtValue();
914+
}
915+
916+
static bool classof(const MachineInstr *MI) {
917+
return MI->getOpcode() == TargetOpcode::G_STEP_VECTOR;
918+
};
919+
};
920+
909921
/// Represents an integer subtraction.
910922
class GSub : public GIntBinOp {
911923
public:

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,17 @@ class MachineIRBuilder {
11721172
MachineInstrBuilder buildInsert(const DstOp &Res, const SrcOp &Src,
11731173
const SrcOp &Op, unsigned Index);
11741174

1175+
/// Build and insert \p Res = G_STEP_VECTOR \p Step
1176+
///
1177+
/// G_STEP_VECTOR returns a scalable vector of linear sequence of step \p Step
1178+
/// into \p Res.
1179+
///
1180+
/// \pre setBasicBlock or setMI must have been called.
1181+
/// \pre \p Res must be a generic virtual register with scalable vector type.
1182+
///
1183+
/// \return a MachineInstrBuilder for the newly created instruction.
1184+
MachineInstrBuilder buildStepVector(const DstOp &Res, unsigned Step);
1185+
11751186
/// Build and insert \p Res = G_VSCALE \p MinElts
11761187
///
11771188
/// G_VSCALE puts the value of the runtime vscale multiplied by \p MinElts

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,9 @@ HANDLE_TARGET_OPCODE(G_SHUFFLE_VECTOR)
776776
/// Generic splatvector.
777777
HANDLE_TARGET_OPCODE(G_SPLAT_VECTOR)
778778

779+
/// Generic stepvector.
780+
HANDLE_TARGET_OPCODE(G_STEP_VECTOR)
781+
779782
/// Generic masked compress.
780783
HANDLE_TARGET_OPCODE(G_VECTOR_COMPRESS)
781784

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,13 @@ def G_SPLAT_VECTOR: GenericInstruction {
15901590
let hasSideEffects = false;
15911591
}
15921592

1593+
// Generic stepvector.
1594+
def G_STEP_VECTOR: GenericInstruction {
1595+
let OutOperandList = (outs type0:$dst);
1596+
let InOperandList = (ins unknown:$step);
1597+
let hasSideEffects = false;
1598+
}
1599+
15931600
// Generic masked compress.
15941601
def G_VECTOR_COMPRESS: GenericInstruction {
15951602
let OutOperandList = (outs type0:$dst);

llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,17 @@ MachineInstrBuilder MachineIRBuilder::buildInsert(const DstOp &Res,
809809
return buildInstr(TargetOpcode::G_INSERT, Res, {Src, Op, uint64_t(Index)});
810810
}
811811

812+
MachineInstrBuilder MachineIRBuilder::buildStepVector(const DstOp &Res,
813+
unsigned Step) {
814+
ConstantInt *CI =
815+
ConstantInt::get(getMF().getFunction().getContext(), APInt(64, Step));
816+
auto StepVector = buildInstr(TargetOpcode::G_STEP_VECTOR);
817+
StepVector->setDebugLoc(DebugLoc());
818+
Res.addDefToMIB(*getMRI(), StepVector);
819+
StepVector.addCImm(CI);
820+
return StepVector;
821+
}
822+
812823
MachineInstrBuilder MachineIRBuilder::buildVScale(const DstOp &Res,
813824
unsigned MinElts) {
814825

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,6 +1731,36 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
17311731
}
17321732
break;
17331733
}
1734+
case TargetOpcode::G_STEP_VECTOR: {
1735+
if (!MI->getOperand(1).isCImm()) {
1736+
report("operand must be cimm", MI);
1737+
break;
1738+
}
1739+
1740+
if (!MI->getOperand(1).getCImm()->getValue().isStrictlyPositive()) {
1741+
report("step must be > 0", MI);
1742+
break;
1743+
}
1744+
1745+
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1746+
if (!DstTy.isScalableVector()) {
1747+
report("Destination type must be a scalable vector", MI);
1748+
break;
1749+
}
1750+
1751+
// <vscale x 2 x p0>
1752+
if (!DstTy.getElementType().isScalar()) {
1753+
report("Destination element type must be scalar", MI);
1754+
break;
1755+
}
1756+
1757+
if (MI->getOperand(1).getCImm()->getBitWidth() !=
1758+
DstTy.getElementType().getScalarSizeInBits()) {
1759+
report("step bitwidth differs from result type element bitwidth", MI);
1760+
break;
1761+
}
1762+
break;
1763+
}
17341764
case TargetOpcode::G_INSERT_SUBVECTOR: {
17351765
const MachineOperand &Src0Op = MI->getOperand(1);
17361766
if (!Src0Op.isReg()) {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,9 @@
665665
# DEBUG-NEXT: G_SPLAT_VECTOR (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
666666
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
667667
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
668+
# DEBUG-NEXT: G_STEP_VECTOR (opcode {{[0-9]+}}): 1 type index, 0 imm indices
669+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
670+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
668671
# DEBUG-NEXT: G_VECTOR_COMPRESS (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
669672
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
670673
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,9 @@
646646
# DEBUG-NEXT: G_SPLAT_VECTOR (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
647647
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
648648
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
649+
# DEBUG-NEXT: G_STEP_VECTOR (opcode {{[0-9]+}}): 1 type index, 0 imm indices
650+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
651+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
649652
# DEBUG-NEXT: G_VECTOR_COMPRESS (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
650653
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
651654
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# RUN: not --crash llc -verify-machineinstrs -mtriple=arm64 -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
2+
# REQUIRES: aarch64-registered-target
3+
4+
---
5+
name: g_step_vector
6+
body: |
7+
bb.0:
8+
9+
%0:_(s32) = G_CONSTANT i32 4
10+
11+
; CHECK: operand must be cimm
12+
%1:_(s32) = G_STEP_VECTOR %0
13+
14+
; CHECK: step must be > 0
15+
%2:_(s32) = G_STEP_VECTOR i32 -1
16+
17+
; CHECK: Destination type must be a scalable vector
18+
%3:_(<4 x s64>) = G_STEP_VECTOR i32 5
19+
20+
; CHECK: Destination element type must be scalar
21+
%4:_(<vscale x 4 x p0>) = G_STEP_VECTOR i32 9
22+
23+
; CHECK: step bitwidth differs from result type element bitwidth
24+
%6:_(<vscale x 2 x s33>) = G_STEP_VECTOR i32 56
25+
26+
%7:_(<vscale x 2 x s128>) = G_STEP_VECTOR i128 79
27+
28+
...
29+

0 commit comments

Comments
 (0)