-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[AArch64] Verify consecutive vector registers in tbl, tbx #120262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AArch64] Verify consecutive vector registers in tbl, tbx #120262
Conversation
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-aarch64 Author: Guy David (guy-david) ChangesTable lookup instructions expect the vectors that define the table itself to be consecutive (wraparound allowed). Full diff: https://github.com/llvm/llvm-project/pull/120262.diff 4 Files Affected:
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
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
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-
ea5fe7c
to
7e210b6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
a41b23d
to
7e210b6
Compare
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-
🍒 [AArch64] Verify consecutive vector registers in tbl, tbx (llvm#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-