Skip to content

Commit 5e22597

Browse files
authored
[AArch64] Verify consecutive vector registers in tbl, tbx (#120262)
Table lookup instructions expect the vectors that define the table itself to be consecutive (wraparound allowed). Relevant documentation: https://developer.arm.com/documentation/100069/0606/SIMD-Vector-Instructions/TBL--vector-
1 parent 5bb6503 commit 5e22597

File tree

4 files changed

+59
-20
lines changed

4 files changed

+59
-20
lines changed

llvm/lib/Target/AArch64/AArch64InstrFormats.td

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8528,28 +8528,28 @@ multiclass SIMDTableLookup<bit op, string asm> {
85288528

85298529
def : SIMDTableLookupAlias<asm # ".8b",
85308530
!cast<Instruction>(NAME#"v8i8One"),
8531-
V64, VecListOne128>;
8531+
V64, VecListOneConsecutive128>;
85328532
def : SIMDTableLookupAlias<asm # ".8b",
85338533
!cast<Instruction>(NAME#"v8i8Two"),
8534-
V64, VecListTwo128>;
8534+
V64, VecListTwoConsecutive128>;
85358535
def : SIMDTableLookupAlias<asm # ".8b",
85368536
!cast<Instruction>(NAME#"v8i8Three"),
8537-
V64, VecListThree128>;
8537+
V64, VecListThreeConsecutive128>;
85388538
def : SIMDTableLookupAlias<asm # ".8b",
85398539
!cast<Instruction>(NAME#"v8i8Four"),
8540-
V64, VecListFour128>;
8540+
V64, VecListFourConsecutive128>;
85418541
def : SIMDTableLookupAlias<asm # ".16b",
85428542
!cast<Instruction>(NAME#"v16i8One"),
8543-
V128, VecListOne128>;
8543+
V128, VecListOneConsecutive128>;
85448544
def : SIMDTableLookupAlias<asm # ".16b",
85458545
!cast<Instruction>(NAME#"v16i8Two"),
8546-
V128, VecListTwo128>;
8546+
V128, VecListTwoConsecutive128>;
85478547
def : SIMDTableLookupAlias<asm # ".16b",
85488548
!cast<Instruction>(NAME#"v16i8Three"),
8549-
V128, VecListThree128>;
8549+
V128, VecListThreeConsecutive128>;
85508550
def : SIMDTableLookupAlias<asm # ".16b",
85518551
!cast<Instruction>(NAME#"v16i8Four"),
8552-
V128, VecListFour128>;
8552+
V128, VecListFourConsecutive128>;
85538553
}
85548554

85558555
multiclass SIMDTableLookupTied<bit op, string asm> {
@@ -8572,28 +8572,28 @@ multiclass SIMDTableLookupTied<bit op, string asm> {
85728572

85738573
def : SIMDTableLookupAlias<asm # ".8b",
85748574
!cast<Instruction>(NAME#"v8i8One"),
8575-
V64, VecListOne128>;
8575+
V64, VecListOneConsecutive128>;
85768576
def : SIMDTableLookupAlias<asm # ".8b",
85778577
!cast<Instruction>(NAME#"v8i8Two"),
8578-
V64, VecListTwo128>;
8578+
V64, VecListTwoConsecutive128>;
85798579
def : SIMDTableLookupAlias<asm # ".8b",
85808580
!cast<Instruction>(NAME#"v8i8Three"),
8581-
V64, VecListThree128>;
8581+
V64, VecListThreeConsecutive128>;
85828582
def : SIMDTableLookupAlias<asm # ".8b",
85838583
!cast<Instruction>(NAME#"v8i8Four"),
8584-
V64, VecListFour128>;
8584+
V64, VecListFourConsecutive128>;
85858585
def : SIMDTableLookupAlias<asm # ".16b",
85868586
!cast<Instruction>(NAME#"v16i8One"),
8587-
V128, VecListOne128>;
8587+
V128, VecListOneConsecutive128>;
85888588
def : SIMDTableLookupAlias<asm # ".16b",
85898589
!cast<Instruction>(NAME#"v16i8Two"),
8590-
V128, VecListTwo128>;
8590+
V128, VecListTwoConsecutive128>;
85918591
def : SIMDTableLookupAlias<asm # ".16b",
85928592
!cast<Instruction>(NAME#"v16i8Three"),
8593-
V128, VecListThree128>;
8593+
V128, VecListThreeConsecutive128>;
85948594
def : SIMDTableLookupAlias<asm # ".16b",
85958595
!cast<Instruction>(NAME#"v16i8Four"),
8596-
V128, VecListFour128>;
8596+
V128, VecListFourConsecutive128>;
85978597
}
85988598

85998599
//----------------------------------------------------------------------------

llvm/lib/Target/AArch64/AArch64RegisterInfo.td

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ class TypedVecListRegOperand<RegisterClass Reg, int lanes, string eltsize>
646646
# eltsize # "'>">;
647647

648648
multiclass VectorList<int count, RegisterClass Reg64, RegisterClass Reg128> {
649-
// With implicit types (probably on instruction instead). E.g. { v0, v1 }
649+
// With implicit types (probably on instruction instead). E.g. { v0, v1 } or {v0, v2, v4}.
650650
def _64AsmOperand : AsmOperandClass {
651651
let Name = NAME # "64";
652652
let PredicateMethod = "isImplicitlyTypedVectorList<RegKind::NeonVector, " # count # ">";
@@ -667,6 +667,17 @@ multiclass VectorList<int count, RegisterClass Reg64, RegisterClass Reg128> {
667667
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_128AsmOperand");
668668
}
669669

670+
// With implicit types (probably on instruction instead), consecutive registers. E.g. { v0, v1, v2 }
671+
def _Consecutive128AsmOperand : AsmOperandClass {
672+
let Name = NAME # "Consecutive128";
673+
let PredicateMethod = "isImplicitlyTypedVectorList<RegKind::NeonVector, " # count # ", true>";
674+
let RenderMethod = "addVectorListOperands<AArch64Operand::VecListIdx_QReg, " # count # ", true>";
675+
}
676+
677+
def "Consecutive128" : RegisterOperand<Reg128, "printImplicitlyTypedVectorList"> {
678+
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_Consecutive128AsmOperand");
679+
}
680+
670681
// 64-bit register lists with explicit type.
671682

672683
// { v0.8b, v1.8b }

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,11 +1447,12 @@ class AArch64Operand : public MCParsedAsmOperand {
14471447

14481448
/// Is this a vector list with the type implicit (presumably attached to the
14491449
/// instruction itself)?
1450-
template <RegKind VectorKind, unsigned NumRegs>
1450+
template <RegKind VectorKind, unsigned NumRegs, bool IsConsecutive = false>
14511451
bool isImplicitlyTypedVectorList() const {
14521452
return Kind == k_VectorList && VectorList.Count == NumRegs &&
14531453
VectorList.NumElements == 0 &&
1454-
VectorList.RegisterKind == VectorKind;
1454+
VectorList.RegisterKind == VectorKind &&
1455+
(!IsConsecutive || (VectorList.Stride == 1));
14551456
}
14561457

14571458
template <RegKind VectorKind, unsigned NumRegs, unsigned NumElements,
@@ -1866,9 +1867,12 @@ class AArch64Operand : public MCParsedAsmOperand {
18661867
VecListIdx_PReg = 3,
18671868
};
18681869

1869-
template <VecListIndexType RegTy, unsigned NumRegs>
1870+
template <VecListIndexType RegTy, unsigned NumRegs,
1871+
bool IsConsecutive = false>
18701872
void addVectorListOperands(MCInst &Inst, unsigned N) const {
18711873
assert(N == 1 && "Invalid number of operands!");
1874+
assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1875+
"Expected consecutive registers");
18721876
static const unsigned FirstRegs[][5] = {
18731877
/* DReg */ { AArch64::Q0,
18741878
AArch64::D0, AArch64::D0_D1,

llvm/test/MC/AArch64/neon-diagnostics.s

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6914,6 +6914,9 @@
69146914
tbl v0.8b, {v1.8b, v2.8b, v3.8b}, v2.8b
69156915
tbl v0.8b, {v1.8b, v2.8b, v3.8b, v4.8b}, v2.8b
69166916
tbl v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b
6917+
tbl v0.8b, {v2.16b, v4.16b, v6.16b, v8.16b}, v10.8b
6918+
tbl.8b v0, {v2, v4, v6, v8}, v10
6919+
tbl.16b v0, {v2, v4, v6, v8}, v10
69176920

69186921
// CHECK-ERROR: error: invalid operand for instruction
69196922
// CHECK-ERROR: tbl v0.8b, {v1.8b}, v2.8b
@@ -6930,12 +6933,24 @@
69306933
// CHECK-ERROR: error: invalid number of vectors
69316934
// CHECK-ERROR: tbl v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b
69326935
// CHECK-ERROR: ^
6936+
// CHECK-ERROR: error: invalid operand for instruction
6937+
// CHECK-ERROR: tbl v0.8b, {v2.16b, v4.16b, v6.16b, v8.16b}, v10.8b
6938+
// CHECK-ERROR: ^
6939+
// CHECK-ERROR: error: invalid operand for instruction
6940+
// CHECK-ERROR: tbl.8b v0, {v2, v4, v6, v8}, v10
6941+
// CHECK-ERROR: ^
6942+
// CHECK-ERROR: error: invalid operand for instruction
6943+
// CHECK-ERROR: tbl.16b v0, {v2, v4, v6, v8}, v10
6944+
// CHECK-ERROR: ^
69336945

69346946
tbx v0.8b, {v1.8b}, v2.8b
69356947
tbx v0.8b, {v1.8b, v2.8b}, v2.8b
69366948
tbx v0.8b, {v1.8b, v2.8b, v3.8b}, v2.8b
69376949
tbx v0.8b, {v1.8b, v2.8b, v3.8b, v4.8b}, v2.8b
69386950
tbx v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b
6951+
tbx v0.8b, {v2.16b, v4.16b, v6.16b, v8.16b}, v10.8b
6952+
tbx.8b v0, {v2, v4, v6, v8}, v10
6953+
tbx.16b v0, {v2, v4, v6, v8}, v10
69396954

69406955
// CHECK-ERROR: error: invalid operand for instruction
69416956
// CHECK-ERROR: tbx v0.8b, {v1.8b}, v2.8b
@@ -6952,6 +6967,15 @@
69526967
// CHECK-ERROR: error: invalid number of vectors
69536968
// CHECK-ERROR: tbx v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b
69546969
// CHECK-ERROR: ^
6970+
// CHECK-ERROR: error: invalid operand for instruction
6971+
// CHECK-ERROR: tbx v0.8b, {v2.16b, v4.16b, v6.16b, v8.16b}, v10.8b
6972+
// CHECK-ERROR: ^
6973+
// CHECK-ERROR: error: invalid operand for instruction
6974+
// CHECK-ERROR: tbx.8b v0, {v2, v4, v6, v8}, v10
6975+
// CHECK-ERROR: ^
6976+
// CHECK-ERROR: error: invalid operand for instruction
6977+
// CHECK-ERROR: tbx.16b v0, {v2, v4, v6, v8}, v10
6978+
// CHECK-ERROR: ^
69556979

69566980
//----------------------------------------------------------------------
69576981
// Scalar Floating-point Convert To Lower Precision Narrow, Rounding To

0 commit comments

Comments
 (0)