[llvm] [AArch64] Verify consecutive vector registers in tbl, tbx (PR #120262)
Guy David via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 17 08:24:53 PST 2024
https://github.com/guy-david created https://github.com/llvm/llvm-project/pull/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-
>From ea5fe7caf7be22bf27aff13eb3a4c8a25849a741 Mon Sep 17 00:00:00 2001
From: Guy David <guyda96 at gmail.com>
Date: Tue, 17 Dec 2024 18:10:55 +0200
Subject: [PATCH] [AArch64] Verify consecutive vector registers in tbl, tbx
---
.../lib/Target/AArch64/AArch64InstrFormats.td | 32 +++++++++----------
.../lib/Target/AArch64/AArch64RegisterInfo.td | 13 +++++++-
.../AArch64/AsmParser/AArch64AsmParser.cpp | 8 +++--
llvm/test/MC/AArch64/neon-diagnostics.s | 8 +++++
4 files changed, 41 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 56ff7b0d3a280d..47c4c6c39565f4 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -8528,28 +8528,28 @@ multiclass SIMDTableLookup<bit op, string asm> {
def : SIMDTableLookupAlias<asm # ".8b",
!cast<Instruction>(NAME#"v8i8One"),
- V64, VecListOne128>;
+ V64, VecListOneConsecutive128>;
def : SIMDTableLookupAlias<asm # ".8b",
!cast<Instruction>(NAME#"v8i8Two"),
- V64, VecListTwo128>;
+ V64, VecListTwoConsecutive128>;
def : SIMDTableLookupAlias<asm # ".8b",
!cast<Instruction>(NAME#"v8i8Three"),
- V64, VecListThree128>;
+ V64, VecListThreeConsecutive128>;
def : SIMDTableLookupAlias<asm # ".8b",
!cast<Instruction>(NAME#"v8i8Four"),
- V64, VecListFour128>;
+ V64, VecListFourConsecutive128>;
def : SIMDTableLookupAlias<asm # ".16b",
!cast<Instruction>(NAME#"v16i8One"),
- V128, VecListOne128>;
+ V128, VecListOneConsecutive128>;
def : SIMDTableLookupAlias<asm # ".16b",
!cast<Instruction>(NAME#"v16i8Two"),
- V128, VecListTwo128>;
+ V128, VecListTwoConsecutive128>;
def : SIMDTableLookupAlias<asm # ".16b",
!cast<Instruction>(NAME#"v16i8Three"),
- V128, VecListThree128>;
+ V128, VecListThreeConsecutive128>;
def : SIMDTableLookupAlias<asm # ".16b",
!cast<Instruction>(NAME#"v16i8Four"),
- V128, VecListFour128>;
+ V128, VecListFourConsecutive128>;
}
multiclass SIMDTableLookupTied<bit op, string asm> {
@@ -8572,28 +8572,28 @@ multiclass SIMDTableLookupTied<bit op, string asm> {
def : SIMDTableLookupAlias<asm # ".8b",
!cast<Instruction>(NAME#"v8i8One"),
- V64, VecListOne128>;
+ V64, VecListOneConsecutive128>;
def : SIMDTableLookupAlias<asm # ".8b",
!cast<Instruction>(NAME#"v8i8Two"),
- V64, VecListTwo128>;
+ V64, VecListTwoConsecutive128>;
def : SIMDTableLookupAlias<asm # ".8b",
!cast<Instruction>(NAME#"v8i8Three"),
- V64, VecListThree128>;
+ V64, VecListThreeConsecutive128>;
def : SIMDTableLookupAlias<asm # ".8b",
!cast<Instruction>(NAME#"v8i8Four"),
- V64, VecListFour128>;
+ V64, VecListFourConsecutive128>;
def : SIMDTableLookupAlias<asm # ".16b",
!cast<Instruction>(NAME#"v16i8One"),
- V128, VecListOne128>;
+ V128, VecListOneConsecutive128>;
def : SIMDTableLookupAlias<asm # ".16b",
!cast<Instruction>(NAME#"v16i8Two"),
- V128, VecListTwo128>;
+ V128, VecListTwoConsecutive128>;
def : SIMDTableLookupAlias<asm # ".16b",
!cast<Instruction>(NAME#"v16i8Three"),
- V128, VecListThree128>;
+ V128, VecListThreeConsecutive128>;
def : SIMDTableLookupAlias<asm # ".16b",
!cast<Instruction>(NAME#"v16i8Four"),
- V128, VecListFour128>;
+ V128, VecListFourConsecutive128>;
}
//----------------------------------------------------------------------------
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index 4fec120391f016..dd4f2549929f84 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -646,7 +646,7 @@ class TypedVecListRegOperand<RegisterClass Reg, int lanes, string eltsize>
# eltsize # "'>">;
multiclass VectorList<int count, RegisterClass Reg64, RegisterClass Reg128> {
- // With implicit types (probably on instruction instead). E.g. { v0, v1 }
+ // With implicit types (probably on instruction instead). E.g. { v0, v1 } or {v0, v2, v4}.
def _64AsmOperand : AsmOperandClass {
let Name = NAME # "64";
let PredicateMethod = "isImplicitlyTypedVectorList<RegKind::NeonVector, " # count # ">";
@@ -667,6 +667,17 @@ multiclass VectorList<int count, RegisterClass Reg64, RegisterClass Reg128> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_128AsmOperand");
}
+ // With implicit types (probably on instruction instead), consecutive registers. E.g. { v0, v1, v2 }
+ def _Consecutive128AsmOperand : AsmOperandClass {
+ let Name = NAME # "Consecutive128";
+ let PredicateMethod = "isImplicitlyTypedVectorList<RegKind::NeonVector, " # count # ", true>";
+ let RenderMethod = "addVectorListOperands<AArch64Operand::VecListIdx_QReg, " # count # ", true>";
+ }
+
+ def "Consecutive128" : RegisterOperand<Reg128, "printImplicitlyTypedVectorList"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_Consecutive128AsmOperand");
+ }
+
// 64-bit register lists with explicit type.
// { v0.8b, v1.8b }
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 93c85ba62f90e2..5cda34dd4dde7e 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -1445,11 +1445,12 @@ class AArch64Operand : public MCParsedAsmOperand {
/// Is this a vector list with the type implicit (presumably attached to the
/// instruction itself)?
- template <RegKind VectorKind, unsigned NumRegs>
+ template <RegKind VectorKind, unsigned NumRegs, bool IsConsecutive = false>
bool isImplicitlyTypedVectorList() const {
return Kind == k_VectorList && VectorList.Count == NumRegs &&
VectorList.NumElements == 0 &&
- VectorList.RegisterKind == VectorKind;
+ VectorList.RegisterKind == VectorKind &&
+ (!IsConsecutive || (VectorList.Stride == 1));
}
template <RegKind VectorKind, unsigned NumRegs, unsigned NumElements,
@@ -1864,9 +1865,10 @@ class AArch64Operand : public MCParsedAsmOperand {
VecListIdx_PReg = 3,
};
- template <VecListIndexType RegTy, unsigned NumRegs>
+ template <VecListIndexType RegTy, unsigned NumRegs, bool IsConsecutive = false>
void addVectorListOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
+ assert((!IsConsecutive || (getVectorListStride() == 1)) && "Expected consecutive registers");
static const unsigned FirstRegs[][5] = {
/* DReg */ { AArch64::Q0,
AArch64::D0, AArch64::D0_D1,
diff --git a/llvm/test/MC/AArch64/neon-diagnostics.s b/llvm/test/MC/AArch64/neon-diagnostics.s
index 6863a89bbe189e..8449ebbdef7ef6 100644
--- a/llvm/test/MC/AArch64/neon-diagnostics.s
+++ b/llvm/test/MC/AArch64/neon-diagnostics.s
@@ -6914,6 +6914,7 @@
tbl v0.8b, {v1.8b, v2.8b, v3.8b}, v2.8b
tbl v0.8b, {v1.8b, v2.8b, v3.8b, v4.8b}, v2.8b
tbl v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b
+ tbl.8b v0, {v2, v4, v6, v8}, v10
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: tbl v0.8b, {v1.8b}, v2.8b
@@ -6930,12 +6931,16 @@
// CHECK-ERROR: error: invalid number of vectors
// CHECK-ERROR: tbl v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b
// CHECK-ERROR: ^
+// CHECK-ERROR: error: invalid operand for instruction
+// CHECK-ERROR: tbl.8b v0, {v2, v4, v6, v8}, v10
+// CHECK-ERROR: ^
tbx v0.8b, {v1.8b}, v2.8b
tbx v0.8b, {v1.8b, v2.8b}, v2.8b
tbx v0.8b, {v1.8b, v2.8b, v3.8b}, v2.8b
tbx v0.8b, {v1.8b, v2.8b, v3.8b, v4.8b}, v2.8b
tbx v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b
+ tbx.8b v0, {v2, v4, v6, v8}, v10
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: tbx v0.8b, {v1.8b}, v2.8b
@@ -6952,6 +6957,9 @@
// CHECK-ERROR: error: invalid number of vectors
// CHECK-ERROR: tbx v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b
// CHECK-ERROR: ^
+// CHECK-ERROR: error: invalid operand for instruction
+// CHECK-ERROR: tbx.8b v0, {v2, v4, v6, v8}, v10
+// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Floating-point Convert To Lower Precision Narrow, Rounding To
More information about the llvm-commits
mailing list