[llvm] af6b1f7 - [AsmParser] Match mandatory operands following optional operands.
Ivan Kosarev via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 10 04:48:22 PST 2022
Author: Ivan Kosarev
Date: 2022-11-10T12:48:11Z
New Revision: af6b1f797f946c560f8a7b0e647f51e23d4c666f
URL: https://github.com/llvm/llvm-project/commit/af6b1f797f946c560f8a7b0e647f51e23d4c666f
DIFF: https://github.com/llvm/llvm-project/commit/af6b1f797f946c560f8a7b0e647f51e23d4c666f.diff
LOG: [AsmParser] Match mandatory operands following optional operands.
Currently, the asm parser stops matching instruction operands as soon as the first optional operand is encountered. This leads to the need for custom checks on missing mandatory operands that come after optional operands.
The patch changes the parser to always match all optional and mandatory instruction operands, thus making the custom checks unnecessary. This is particularly useful for the AMDGPU backend where we have numerous optional instruction modifiers.
Reviewed By: dp
Differential Revision: https://reviews.llvm.org/D137549
Added:
Modified:
llvm/test/MC/AMDGPU/gfx10_err_pos.s
llvm/test/MC/AMDGPU/gfx9-asm-err.s
llvm/test/MC/AMDGPU/gfx9_err_pos.s
llvm/test/MC/AMDGPU/mubuf.s
llvm/test/MC/SystemZ/asm-match.s
llvm/test/MC/X86/x86_64-asm-match.s
llvm/utils/TableGen/AsmMatcherEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/test/MC/AMDGPU/gfx10_err_pos.s b/llvm/test/MC/AMDGPU/gfx10_err_pos.s
index 3fee1c0a780f9..38440d442ca37 100644
--- a/llvm/test/MC/AMDGPU/gfx10_err_pos.s
+++ b/llvm/test/MC/AMDGPU/gfx10_err_pos.s
@@ -1,10 +1,10 @@
// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx1010 -mattr=+WavefrontSize32,-WavefrontSize64 %s 2>&1 | FileCheck %s --implicit-check-not=error: --strict-whitespace
//==============================================================================
-// dim modifier is required on this GPU
+// operands are not valid for this GPU or mode
image_atomic_add v252, v2, s[8:15]
-// CHECK: error: dim modifier is required on this GPU
+// CHECK: error: operands are not valid for this GPU or mode
// CHECK-NEXT:{{^}}image_atomic_add v252, v2, s[8:15]
// CHECK-NEXT:{{^}}^
@@ -966,19 +966,6 @@ s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP, 0)
// CHECK-NEXT:{{^}}s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP, 0)
// CHECK-NEXT:{{^}} ^
-//==============================================================================
-// missing dst operand or lds modifier
-
-buffer_load_dword off, s[8:11], s3
-// CHECK: error: missing dst operand or lds modifier
-// CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3
-// CHECK-NEXT:{{^}}^
-
-buffer_load_dword off, s[8:11], s3 offset:1
-// CHECK: error: missing dst operand or lds modifier
-// CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 offset:1
-// CHECK-NEXT:{{^}}^
-
//==============================================================================
// missing message operation
@@ -1191,6 +1178,16 @@ v_add_f32_e64 v0, v1
// CHECK-NEXT:{{^}}v_add_f32_e64 v0, v1
// CHECK-NEXT:{{^}}^
+buffer_load_dword off, s[8:11], s3
+// CHECK: error: too few operands for instruction
+// CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3
+// CHECK-NEXT:{{^}}^
+
+buffer_load_dword off, s[8:11], s3 offset:1
+// CHECK: error: too few operands for instruction
+// CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 offset:1
+// CHECK-NEXT:{{^}}^
+
//==============================================================================
// too large value for expcnt
diff --git a/llvm/test/MC/AMDGPU/gfx9-asm-err.s b/llvm/test/MC/AMDGPU/gfx9-asm-err.s
index 4842dbe576313..b483ec5faa676 100644
--- a/llvm/test/MC/AMDGPU/gfx9-asm-err.s
+++ b/llvm/test/MC/AMDGPU/gfx9-asm-err.s
@@ -37,7 +37,7 @@ global_load_lds_dword v[2:3], off
// GFX9ERR: error: instruction not supported on this GPU
global_load_dword v[2:3], off
-// GFX9ERR: error: missing dst operand or lds modifier
+// GFX9ERR: error: too few operands for instruction
scratch_load_dword v2, off, offset:256
-// GFX9ERR: error: missing dst operand or lds modifier
+// GFX9ERR: error: too few operands for instruction
diff --git a/llvm/test/MC/AMDGPU/gfx9_err_pos.s b/llvm/test/MC/AMDGPU/gfx9_err_pos.s
index b9ad41e6f3a56..76ef5d2a2a1c1 100644
--- a/llvm/test/MC/AMDGPU/gfx9_err_pos.s
+++ b/llvm/test/MC/AMDGPU/gfx9_err_pos.s
@@ -179,15 +179,15 @@ v_add_i16 v5, 0.5, v2
// CHECK-NEXT:{{^}} ^
//==============================================================================
-// missing dst operand or lds modifier
+// too few operands for instruction
buffer_load_dword off, s[8:11], s3
-// CHECK: error: missing dst operand or lds modifier
+// CHECK: error: too few operands for instruction
// CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3
// CHECK-NEXT:{{^}}^
buffer_load_dword off, s[8:11], s3 offset:1
-// CHECK: error: missing dst operand or lds modifier
+// CHECK: error: too few operands for instruction
// CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 offset:1
// CHECK-NEXT:{{^}}^
diff --git a/llvm/test/MC/AMDGPU/mubuf.s b/llvm/test/MC/AMDGPU/mubuf.s
index 7caecda3107ee..e267b1c937767 100644
--- a/llvm/test/MC/AMDGPU/mubuf.s
+++ b/llvm/test/MC/AMDGPU/mubuf.s
@@ -862,7 +862,7 @@ buffer_store_lds_dword s[4:7], s8 offset:4 tfe lds
// NOVI: error: invalid operand for instruction
buffer_load_dword off, s[8:11], s3
-// NOSICIVI: error: missing dst operand or lds modifier
+// NOSICIVI: error: too few operands for instruction
buffer_load_dword off, s[8:11], s3 offset:1
-// NOSICIVI: error: missing dst operand or lds modifier
+// NOSICIVI: error: too few operands for instruction
diff --git a/llvm/test/MC/SystemZ/asm-match.s b/llvm/test/MC/SystemZ/asm-match.s
index 843d3ae6cac07..0353f27583a9e 100644
--- a/llvm/test/MC/SystemZ/asm-match.s
+++ b/llvm/test/MC/SystemZ/asm-match.s
@@ -8,53 +8,63 @@
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r3): match success using generic matcher
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 2 (Reg:r0): match success using generic matcher
// CHECK: Matching formal operand class MCK_BDAddr32Disp20 against actual operand at index 3 (Mem:3): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 1 encodings with mnemonic 'llill'
// CHECK: Trying to match opcode LLILL
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r0): match success using generic matcher
// CHECK: Matching formal operand class MCK_U16Imm against actual operand at index 2 (Imm:0): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 1 encodings with mnemonic 'lgr'
// CHECK: Trying to match opcode LGR
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r1): match success using generic matcher
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 2 (Reg:r0): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 1 encodings with mnemonic 'lg'
// CHECK: Trying to match opcode LG
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r1): match success using generic matcher
// CHECK: Matching formal operand class MCK_BDXAddr64Disp20 against actual operand at index 2 (Mem:16(r2)): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 1 encodings with mnemonic 'lg'
// CHECK: Trying to match opcode LG
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r1): match success using generic matcher
// CHECK: Matching formal operand class MCK_BDXAddr64Disp20 against actual operand at index 2 (Mem:16(r2,r3)): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 1 encodings with mnemonic 'stmg'
// CHECK: Trying to match opcode STMG
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r13): match success using generic matcher
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 2 (Reg:r15): match success using generic matcher
// CHECK: Matching formal operand class MCK_BDAddr64Disp20 against actual operand at index 3 (Mem:104(r15)): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 1 encodings with mnemonic 'mvc'
// CHECK: Trying to match opcode MVC
// CHECK: Matching formal operand class MCK_BDLAddr64Disp12Len8 against actual operand at index 1 (Mem:184(8,r15)): match success using generic matcher
// CHECK: Matching formal operand class MCK_BDAddr64Disp12 against actual operand at index 2 (Mem:8(r2)): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 1 encodings with mnemonic 'mvck'
// CHECK: Trying to match opcode MVCK
// CHECK: Matching formal operand class MCK_BDRAddr64Disp12 against actual operand at index 1 (Mem:0(r0,r1)): match success using generic matcher
// CHECK: Matching formal operand class MCK_BDAddr64Disp12 against actual operand at index 2 (Mem:4095(r15)): match success using generic matcher
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 3 (Reg:r2): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 1 encodings with mnemonic 'j'
// CHECK: Trying to match opcode J
// CHECK: Matching formal operand class MCK_PCRel16 against actual operand at index 1 (Imm:.Ltmp0+2): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 2: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 2: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 1 encodings with mnemonic 'brasl'
// CHECK: Trying to match opcode BRASL
// CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r14): match success using generic matcher
// CHECK: Matching formal operand class MCK_PCRelTLS32 against actual operand at index 2 (ImmTLS:fun): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: .text
// CHECK: sllg %r3, %r0, 3
// CHECK: llill %r0, 0
diff --git a/llvm/test/MC/X86/x86_64-asm-match.s b/llvm/test/MC/X86/x86_64-asm-match.s
index 74f92118f3c9e..f436fd2ded336 100644
--- a/llvm/test/MC/X86/x86_64-asm-match.s
+++ b/llvm/test/MC/X86/x86_64-asm-match.s
@@ -9,13 +9,15 @@
// CHECK: Trying to match opcode PSHUFBrm
// CHECK: Matching formal operand class MCK_Mem128 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rip,Scale=1,Disp=CPI1_0): match success using generic matcher
// CHECK: Matching formal operand class MCK_FR16 against actual operand at index 2 (Reg:xmm1): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 2 encodings with mnemonic 'sha1rnds4'
// CHECK: Trying to match opcode SHA1RNDS4rri
// CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (Imm:1): match success using generic matcher
// CHECK: Matching formal operand class MCK_FR16 against actual operand at index 2 (Reg:xmm1): match success using generic matcher
// CHECK: Matching formal operand class MCK_FR16 against actual operand at index 3 (Reg:xmm2): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 4 encodings with mnemonic 'pinsrw'
// CHECK: Trying to match opcode MMX_PINSRWrr
// CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (Imm:3): match success using generic matcher
@@ -25,14 +27,16 @@
// CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (Imm:3): match success using generic matcher
// CHECK: Matching formal operand class MCK_GR32orGR64 against actual operand at index 2 (Reg:ecx): match success using generic matcher
// CHECK: Matching formal operand class MCK_FR16 against actual operand at index 3 (Reg:xmm5): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 2 encodings with mnemonic 'crc32l'
// CHECK: Trying to match opcode CRC32r32r32
// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=3735928559,SegReg=gs): Opcode result: multiple operand mismatches, ignoring this opcode
// CHECK: Trying to match opcode CRC32r32m32
// CHECK: Matching formal operand class MCK_Mem32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=3735928559,SegReg=gs): match success using generic matcher
// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 2 (Reg:ecx): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 4 encodings with mnemonic 'punpcklbw'
// CHECK: Trying to match opcode MMX_PUNPCKLBWrr
// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 1 (Reg:mm0): match success using generic matcher
@@ -40,7 +44,8 @@
// CHECK: Trying to match opcode MMX_PUNPCKLBWrm
// CHECK: Matching formal operand class MCK_VR64 against actual operand at index 1 (Reg:mm0): match success using generic matcher
// CHECK: Matching formal operand class MCK_Mem32 against actual operand at index 2 (Memory: ModeSize=64,Size=32,BaseReg=rsp,Scale=1): match success using generic matcher
-// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode
+// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
+// CHECK: Opcode result: complete match, selecting this opcode
pshufb CPI1_0(%rip), %xmm1
sha1rnds4 $1, %xmm1, %xmm2
diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index 852ef5a8c3b3d..d90b6799773aa 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -3666,7 +3666,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " else\n";
OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \": \");\n";
OS << " if (ActualIdx >= Operands.size()) {\n";
- OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"actual operand index out of range \");\n";
+ OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"actual operand "
+ "index out of range\\n\");\n";
if (ReportMultipleNearMisses) {
OS << " bool ThisOperandValid = (Formal == " <<"InvalidMatchClass) || "
"isSubclass(Formal, OptionalMatchClass);\n";
@@ -3690,12 +3691,21 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " }\n";
OS << " continue;\n";
} else {
- OS << " OperandsValid = (Formal == InvalidMatchClass) || isSubclass(Formal, OptionalMatchClass);\n";
- OS << " if (!OperandsValid) ErrorInfo = ActualIdx;\n";
+ OS << " if (Formal == InvalidMatchClass) {\n";
if (HasOptionalOperands) {
- OS << " OptionalOperandsMask.set(FormalIdx, " << MaxNumOperands
+ OS << " OptionalOperandsMask.set(FormalIdx, " << MaxNumOperands
<< ");\n";
}
+ OS << " break;\n";
+ OS << " }\n";
+ OS << " if (isSubclass(Formal, OptionalMatchClass)) {\n";
+ if (HasOptionalOperands) {
+ OS << " OptionalOperandsMask.set(FormalIdx);\n";
+ }
+ OS << " continue;\n";
+ OS << " }\n";
+ OS << " OperandsValid = false;\n";
+ OS << " ErrorInfo = ActualIdx;\n";
OS << " break;\n";
}
OS << " }\n";
More information about the llvm-commits
mailing list