[llvm] 14d9c0c - [AsmMatcher] Report a near-miss when all candidates mismatch multiple operands (#206390)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 30 18:58:13 PDT 2026


Author: Mark Zhuang
Date: 2026-07-01T09:58:09+08:00
New Revision: 14d9c0c469be442f16bafaff3299b7585e944ea5

URL: https://github.com/llvm/llvm-project/commit/14d9c0c469be442f16bafaff3299b7585e944ea5
DIFF: https://github.com/llvm/llvm-project/commit/14d9c0c469be442f16bafaff3299b7585e944ea5.diff

LOG: [AsmMatcher] Report a near-miss when all candidates mismatch multiple operands (#206390)

In the ReportMultipleNearMisses path, an opcode that mismatches more
than one operand is dropped, and its first near-miss is dropped with it. If
every opcode is dropped this way, the parser only reports a generic
"invalid instruction".

Now keep the first near-miss of each such opcode, and use it only when
no other opcode gives a near-miss.

Assisted-by: claude-opus

Added: 
    

Modified: 
    llvm/test/MC/ARM/basic-arm-instructions-v8.1a.s
    llvm/test/MC/ARM/bfloat16-a32-errors2.s
    llvm/test/MC/ARM/cde-integer.s
    llvm/test/MC/ARM/diagnostics.s
    llvm/test/MC/ARM/invalid-neon-v8.s
    llvm/test/MC/ARM/ldrd-strd-gnu-arm-bad-regs.s
    llvm/test/MC/ARM/ldrd-strd-gnu-bad-inst.s
    llvm/test/MC/ARM/ldrd-strd-gnu-sp.s
    llvm/test/MC/ARM/ldrd-strd-gnu-thumb-bad-regs.s
    llvm/test/MC/ARM/mve-load-store.s
    llvm/test/MC/ARM/mve-misc.s
    llvm/test/MC/ARM/mve-scalar-shift.s
    llvm/test/MC/ARM/thumb-diagnostics.s
    llvm/test/MC/ARM/thumb2-diagnostics.s
    llvm/test/MC/ARM/thumb2-dsp-diag.s
    llvm/test/MC/ARM/thumbv7m.s
    llvm/test/MC/ARM/thumbv8m.s
    llvm/test/MC/ARM/vmrs_vmsr.s
    llvm/utils/TableGen/AsmMatcherEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/MC/ARM/basic-arm-instructions-v8.1a.s b/llvm/test/MC/ARM/basic-arm-instructions-v8.1a.s
index ad766135e33f2..f21a2ac054f08 100644
--- a/llvm/test/MC/ARM/basic-arm-instructions-v8.1a.s
+++ b/llvm/test/MC/ARM/basic-arm-instructions-v8.1a.s
@@ -27,16 +27,16 @@
 //CHECK-ERROR: error: invalid operand for instruction
 //CHECK-ERROR:   vqrdmlsh.f64  d3, d5, d5
 //CHECK-ERROR:           ^
-//CHECK-V8: error: invalid instruction
+//CHECK-V8: error: invalid operand for instruction
 //CHECK-V8:   vqrdmlah.i8   q0, q1, q2
 //CHECK-V8:   ^
-//CHECK-V8: error: invalid instruction
+//CHECK-V8: error: invalid operand for instruction
 //CHECK-V8:   vqrdmlah.u16  d0, d1, d2
 //CHECK-V8:   ^
-//CHECK-V8: error: invalid instruction
+//CHECK-V8: error: invalid operand for instruction
 //CHECK-V8:   vqrdmlsh.f32  q3, q4, q5
 //CHECK-V8:   ^
-//CHECK-V8: error: invalid instruction
+//CHECK-V8: error: invalid operand for instruction
 //CHECK-V8:  vqrdmlsh.f64  d3, d5, d5
 //CHECK-V8:  ^
 

diff  --git a/llvm/test/MC/ARM/bfloat16-a32-errors2.s b/llvm/test/MC/ARM/bfloat16-a32-errors2.s
index 85f1dd8cc5ce0..26de5f813313a 100644
--- a/llvm/test/MC/ARM/bfloat16-a32-errors2.s
+++ b/llvm/test/MC/ARM/bfloat16-a32-errors2.s
@@ -25,16 +25,16 @@ vfmab.bf16 q0, d0, d0[0]
 vfmab.bf16 d0, q0, d0[0]
 vfmab.bf16 q0, d0, d0[9]
 
-//CHECK:error: invalid instruction
+//CHECK:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmat.bf16 d0, d0, d0
 //CHECK-NEXT:^
-//CHECK-NEXT:error: invalid instruction
+//CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmat.bf16 d0, d0, q0
 //CHECK-NEXT:^
-//CHECK-NEXT:error: invalid instruction
+//CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmat.bf16 d0, q0, d0
 //CHECK-NEXT:^
-//CHECK-NEXT:error: invalid instruction
+//CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmat.bf16 q0, d0, d0
 //CHECK-NEXT:^
 //CHECK-NEXT:error: invalid instruction, any one of the following would fix this:
@@ -76,19 +76,19 @@ vfmab.bf16 q0, d0, d0[9]
 //CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmat.bf16 d0, q0, d0[0]
 //CHECK-NEXT:            ^
-//CHECK-NEXT:error: invalid instruction
+//CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmat.bf16 q0, d0, d0[9]
 //CHECK-NEXT:^
-//CHECK-NEXT:error: invalid instruction
+//CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmab.bf16 d0, d0, d0
 //CHECK-NEXT:^
-//CHECK-NEXT:error: invalid instruction
+//CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmab.bf16 d0, d0, q0
 //CHECK-NEXT:^
-//CHECK-NEXT:error: invalid instruction
+//CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmab.bf16 d0, q0, d0
 //CHECK-NEXT:^
-//CHECK-NEXT:error: invalid instruction
+//CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmab.bf16 q0, d0, d0
 //CHECK-NEXT:^
 //CHECK-NEXT:error: invalid instruction, any one of the following would fix this:
@@ -130,5 +130,5 @@ vfmab.bf16 q0, d0, d0[9]
 //CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmab.bf16 d0, q0, d0[0]
 //CHECK-NEXT:            ^
-//CHECK-NEXT:error: invalid instruction
+//CHECK-NEXT:error: operand must be a register in range [q0, q15]
 //CHECK-NEXT:vfmab.bf16 q0, d0, d0[9]

diff  --git a/llvm/test/MC/ARM/cde-integer.s b/llvm/test/MC/ARM/cde-integer.s
index 54c0598e62543..8fd92d59514ea 100644
--- a/llvm/test/MC/ARM/cde-integer.s
+++ b/llvm/test/MC/ARM/cde-integer.s
@@ -114,11 +114,11 @@ cx1d  p1, r1, #1234
 cx1d  p1, r2, r4, #1234
 // ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an even-numbered register in the range [r0, r10]
 cx1da  p0, r1, #1234
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,8191]
 cx1   p0, r0, r0, #1234
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,8191]
 cx1d   p0, r0, r1, r2, #1234
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,8191]
 cx1a   p0, r0, r2, #1234
 
 // CHECK-LABEL: test_cx2:
@@ -142,11 +142,11 @@ cx2d  p0, r12, r7, #123
 cx2da  p0, r7, r7, #123
 // ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an even-numbered register in the range [r0, r10]
 cx2da  p1, apsr_nzcv, r7, #123
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,511]
 cx2   p0, r0, r0, r7, #1
 // ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be a consecutive register
 cx2d   p0, r0, r0, r7, #1
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,511]
 cx2a   p0, r0, r2, r7, #1
 // ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be a consecutive register
 cx2da   p0, r0, r2, r7, #1
@@ -172,48 +172,48 @@ cx3     p0, r1, r5, r7, #64
 cx3da   p1, r14, r2, r3, #12
 // ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be a register in the range [r0, r12], r14 or apsr_nzcv
 cx3a    p0, r15, r2, r3, #12
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,511]
 cx2   p0, r0, r0, r7, r3, #1
 // ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be a consecutive register
 cx2d   p0, r0, r0, r7, r3, #1
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,63]
 cx3a    p0, r1, r2, r5, r7, #63
 // ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be a consecutive register
 cx3da   p0, r8, apsr_nzcv, r2, r3, #12
 
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx1    p0, s0, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx1    p0, d0, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx1    p0, q0, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx1a   p0, s0, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx1a   p0, d0, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx1a   p0, q0, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx2    p0, s0, s1, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx2    p0, d0, d1, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx2    p0, q0, q1, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx2a   p0, s0, s1, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx2a   p0, d0, d1, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx2    p0, q0, q1, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx3    p0, s0, s1, s2, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx3    p0, d0, d1, d2, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx3    p0, q0, q1, q2, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx3a   p0, s0, s1, s2, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx3a   p0, d0, d1, d2, #0
-// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
 vcx3a   p0, q0, q1, q2, #0

diff  --git a/llvm/test/MC/ARM/diagnostics.s b/llvm/test/MC/ARM/diagnostics.s
index 29feee99cf351..4763a65d7f564 100644
--- a/llvm/test/MC/ARM/diagnostics.s
+++ b/llvm/test/MC/ARM/diagnostics.s
@@ -136,10 +136,10 @@
 @ CHECK-ERRORS-V7: error: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: error: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: error: operand must be an immediate in the range [0,7]
-@ CHECK-ERRORS-V8: error: invalid instruction
-@ CHECK-ERRORS-V8: error: invalid instruction
-@ CHECK-ERRORS-V8: error: invalid instruction
-@ CHECK-ERRORS-V8: error: invalid instruction
+@ CHECK-ERRORS-V8: error: invalid operand for instruction
+@ CHECK-ERRORS-V8: error: invalid operand for instruction
+@ CHECK-ERRORS-V8: error: invalid operand for instruction
+@ CHECK-ERRORS-V8: error: invalid operand for instruction
 
         @ Out of range immediates for DBG
         dbg #-1
@@ -164,11 +164,11 @@
 @ CHECK-ERRORS: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
-@ CHECK-ERRORS-V8: invalid instruction
+@ CHECK-ERRORS-V8: too many operands for instruction
 @ CHECK-ERRORS-V8: too many operands for instruction
 @ CHECK-ERRORS: operand must be an immediate in the range [0,15]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,15]
-@ CHECK-ERRORS-V8: invalid instruction
+@ CHECK-ERRORS-V8: invalid operand for instruction
 
         @ p10 and p11 are reserved for NEON
         mcr p10, #2, r5, c1, c1, #4
@@ -212,12 +212,12 @@
 @ CHECK-ERRORS: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
-@ CHECK-ERRORS-V8: invalid instruction
+@ CHECK-ERRORS-V8: too many operands for instruction
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V8: too many operands for instruction
 @ CHECK-ERRORS: operand must be an immediate in the range [0,15]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,15]
-@ CHECK-ERRORS-V8: invalid instruction
+@ CHECK-ERRORS-V8: invalid operand for instruction
 
         @ Shifter operand validation for PKH instructions.
         pkhbt r2, r2, r3, lsl #-1

diff  --git a/llvm/test/MC/ARM/invalid-neon-v8.s b/llvm/test/MC/ARM/invalid-neon-v8.s
index ff0873995956f..582912b995541 100644
--- a/llvm/test/MC/ARM/invalid-neon-v8.s
+++ b/llvm/test/MC/ARM/invalid-neon-v8.s
@@ -12,7 +12,7 @@ vcvta.s32.f32 s1, s2
 vcvtp.u32.f32 s1, d2
 @ CHECK: error: operand must be a register in range [d0, d31]
 vcvtp.f32.u32 d1, q2
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operand for instruction
 vcvtplo.f32.u32 s1, s2
 @ CHECK: error: instruction 'vcvtp' is not predicable, but condition code specified
 
@@ -50,7 +50,7 @@ sha1heq.32  q0, q1
 @ CHECK: error: instruction 'sha1h' is not predicable, but condition code specified
 
 sha1c.32  s0, d1, q2
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [q0, q15]
 sha1m.32  q0, s1, q2
 @ CHECK: error: operand must be a register in range [q0, q15]
 sha1p.32  s0, q1, q2
@@ -62,7 +62,7 @@ sha256h.32  q0, s1, q2
 sha256h2.32  q0, q1, s2
 @ CHECK: error: operand must be a register in range [q0, q15]
 sha256su1.32  s0, d1, q2
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [q0, q15]
 sha256su1lt.32  q0, d1, q2
 @ CHECK: error: instruction 'sha256su1' is not predicable, but condition code specified
 

diff  --git a/llvm/test/MC/ARM/ldrd-strd-gnu-arm-bad-regs.s b/llvm/test/MC/ARM/ldrd-strd-gnu-arm-bad-regs.s
index bb30bde49afa7..b5404a3cae0cd 100644
--- a/llvm/test/MC/ARM/ldrd-strd-gnu-arm-bad-regs.s
+++ b/llvm/test/MC/ARM/ldrd-strd-gnu-arm-bad-regs.s
@@ -2,18 +2,18 @@
 
 .text
 .arm
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [r0, r15]
 @ CHECK:         ldrd    r12, [r0, #512]
         ldrd    r12, [r0, #512]
 
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [r0, r15]
 @ CHECK:         strd    r12, [r0, #512]
         strd    r12, [r0, #512]
 
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [r0, r15]
 @ CHECK:         ldrd    r1, [r0, #512]
         ldrd    r1, [r0, #512]
 
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [r0, r15]
 @ CHECK:         strd    r1, [r0, #512]
         strd    r1, [r0, #512]

diff  --git a/llvm/test/MC/ARM/ldrd-strd-gnu-bad-inst.s b/llvm/test/MC/ARM/ldrd-strd-gnu-bad-inst.s
index e080538eeac31..0a976fa81387e 100644
--- a/llvm/test/MC/ARM/ldrd-strd-gnu-bad-inst.s
+++ b/llvm/test/MC/ARM/ldrd-strd-gnu-bad-inst.s
@@ -10,9 +10,9 @@
   strd r0
 @ CHECK: error: too few operands for instruction
   ldrd r0
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [r0, r15]
   strd s0, [r0]
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [r0, r15]
   ldrd s0, [r0]
   .arm
 @ CHECK: error: too few operands for instruction
@@ -23,7 +23,7 @@
   strd r0
 @ CHECK: error: too few operands for instruction
   ldrd r0
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [r0, r15]
   strd s0, [r0]
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [r0, r15]
   ldrd s0, [r0]

diff  --git a/llvm/test/MC/ARM/ldrd-strd-gnu-sp.s b/llvm/test/MC/ARM/ldrd-strd-gnu-sp.s
index 3d6db3bf422ef..c18e7d75840d0 100644
--- a/llvm/test/MC/ARM/ldrd-strd-gnu-sp.s
+++ b/llvm/test/MC/ARM/ldrd-strd-gnu-sp.s
@@ -8,20 +8,20 @@
 
   .arm
 
-// V7: error: invalid instruction
+// V7: error: operand must be a register in range [r0, r15]
 // V8: ldrd    r12, sp, [r0, #32]      @ encoding: [0xd0,0xc2,0xc0,0xe1]
         ldrd    r12, [r0, #32]
 
-// V7: error: invalid instruction
+// V7: error: operand must be a register in range [r0, r15]
 // V8: strd    r12, sp, [r0, #32]      @ encoding: [0xf0,0xc2,0xc0,0xe1]
         strd    r12, [r0, #32]
 
   .thumb
 
-// V7: error: invalid instruction
+// V7: error: operand must be a register in range [r0, r15]
 // V8: ldrd    r12, sp, [r0, #32]      @ encoding: [0xd0,0xe9,0x08,0xcd]
         ldrd    r12, [r0, #32]
 
-// V7: error: invalid instruction
+// V7: error: operand must be a register in range [r0, r15]
 // V8: strd    r12, sp, [r0, #32]      @ encoding: [0xc0,0xe9,0x08,0xcd]
         strd    r12, [r0, #32]

diff  --git a/llvm/test/MC/ARM/ldrd-strd-gnu-thumb-bad-regs.s b/llvm/test/MC/ARM/ldrd-strd-gnu-thumb-bad-regs.s
index 93e2db1cb0cb1..2d5dd5b76d81b 100644
--- a/llvm/test/MC/ARM/ldrd-strd-gnu-thumb-bad-regs.s
+++ b/llvm/test/MC/ARM/ldrd-strd-gnu-thumb-bad-regs.s
@@ -2,10 +2,10 @@
 
 .text
 .thumb
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [r0, r15]
 @ CHECK:         ldrd    r12, [r0, #512]
         ldrd    r12, [r0, #512]
 
-@ CHECK: error: invalid instruction
+@ CHECK: error: operand must be a register in range [r0, r15]
 @ CHECK:         strd    r12, [r0, #512]
         strd    r12, [r0, #512]

diff  --git a/llvm/test/MC/ARM/mve-load-store.s b/llvm/test/MC/ARM/mve-load-store.s
index 797ab1e22dd01..3fdd7fb763cf9 100644
--- a/llvm/test/MC/ARM/mve-load-store.s
+++ b/llvm/test/MC/ARM/mve-load-store.s
@@ -873,15 +873,15 @@ vstrb.16 q0, [r8]
 vldrh.u32 q0, [r8]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:14: error: invalid operand for instruction
 vstrw.32 q5, [sp, #-64]!
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:14: error: invalid operand for instruction
 vstrw.32 q5, [sp, #-3]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:14: error: invalid operand for instruction
 vstrw.32 q5, [sp, #512]
 
 # CHECK: vldrb.u8 q0, [r0, q1] @ encoding: [0x90,0xfc,0x02,0x0e]
@@ -1153,7 +1153,7 @@ vstrd.64 q0, [r0, q1, uxtw #3]
 vstrd.64 q0, [sp, q1, uxtw #3]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be a register in range [q0, q7]
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:10: error: operand must be a register in range [q0, q7]
 vstrw.32 q9, [sp, q1, uxtw #2]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
@@ -1161,23 +1161,23 @@ vstrw.32 q9, [sp, q1, uxtw #2]
 vstrh.16 q3, [pc, q1]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:14: error: invalid operand for instruction
 vstrd.64 q0, [r0, q1, uxtw #1]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:15: error: invalid operand for instruction
 vldrd.u64 q0, [r0, q1, uxtw #1]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:14: error: invalid operand for instruction
 vstrd.64 q0, [r0, q1, uxtw #2]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:15: error: invalid operand for instruction
 vldrd.u64 q0, [r0, q1, uxtw #2]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:15: error: invalid operand for instruction
 vldrw.u32 q0, [r0, q1, uxtw #1]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
@@ -1265,15 +1265,15 @@ vstrw.32 q7, [q1, #-508]
 vstrw.32 q7, [q1, #264]!
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be a register in range [q0, q7]
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:10: error: operand must be a register in range [q0, q7]
 vstrw.32 q8, [q1]!
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:14: error: invalid operand for instruction
 vstrw.32 q4, [q1, #3]!
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:15: error: invalid operand for instruction
 vldrw.u32 q7, [q1, #512]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: destination vector register and vector pointer register can't be identical
@@ -1377,19 +1377,19 @@ vstrd.64 q7, [q1, #624]
 vstrd.64 q7, [q1, #264]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be a register in range [q0, q7]
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:11: error: operand must be a register in range [q0, q7]
 vldrd.u64 q8, [q1]!
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:14: error: invalid operand for instruction
 vstrd.64 q7, [q1, #1024]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:14: error: invalid operand for instruction
 vstrd.64 q4, [q1, #3]
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:14: error: invalid operand for instruction
 vstrd.64 q4, [q1, #4]
 
 # CHECK: vldrb.u8 q0, [r0] @ encoding: [0x90,0xed,0x00,0x1e]

diff  --git a/llvm/test/MC/ARM/mve-misc.s b/llvm/test/MC/ARM/mve-misc.s
index 251a77b4710dc..055981530cf26 100644
--- a/llvm/test/MC/ARM/mve-misc.s
+++ b/llvm/test/MC/ARM/mve-misc.s
@@ -67,23 +67,23 @@ wlstp.8     lr, r10, #4086
 wlstp.8     lr, r11, #1442
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: loop end is out of range or not a positive multiple of 2
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:6: error: invalid operand for instruction
 wlstp.8     lr, r10, #1443
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: loop end is out of range or not a positive multiple of 2
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:6: error: invalid operand for instruction
 wlstp.8     lr, r10, #4096
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be a register in range [r0, r12] or r14
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:6: error: invalid operand for instruction
 wlstp.8     lr, sp, #1442
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be a register in range [r0, r12] or r14
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:6: error: invalid operand for instruction
 wlstp.16     lr, sp, #1442
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:6: error: invalid operand for instruction
 wlstp.32     r10, r11, #1442
 
 # CHECK: wlstp.8     lr, r1, .Lendloop  @ encoding: [0x01'A',0xf0'A',0x01'A',0xc0'A']
@@ -123,15 +123,15 @@ dlstp.32     lr, r7
 dlstp.64     lr, r2
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be a register in range [r0, r12] or r14
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:6: error: invalid operand for instruction
 dlstp.64     lr, sp
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:6: error: invalid operand for instruction
 dlstp.64     r10, r0
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be a register in range [r0, r12] or r14
-# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:6: error: invalid operand for instruction
 dlstp.64     lr, pc
 
 # CHECK: letp lr, #-2 @ encoding: [0x1f,0xf0,0x01,0xc8]

diff  --git a/llvm/test/MC/ARM/mve-scalar-shift.s b/llvm/test/MC/ARM/mve-scalar-shift.s
index 4d060ec3a7ceb..f942d5c18d58d 100644
--- a/llvm/test/MC/ARM/mve-scalar-shift.s
+++ b/llvm/test/MC/ARM/mve-scalar-shift.s
@@ -21,8 +21,8 @@ asrl    lr, r1, #27
 it eq
 asrleq    lr, r1, #27
 
-# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid instruction
-# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid instruction
+# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be an even-numbered register
+# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: operand must be an even-numbered register
 asrl    r3, r2, #33
 
 # ERROR: [[@LINE+3]]:{{[0-9]+}}: {{error|note}}: operand must be an immediate in the range [1,32]
@@ -31,7 +31,7 @@ asrl    r3, r2, #33
 asrl    r0, r1, #33
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be an odd-numbered register in range [r1,r11]
-# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an odd-numbered register in range [r1,r11]
 asrl    r0, r0, #32
 
 # CHECK: asrl    r0, r1, r4  @ encoding: [0x50,0xea,0x2d,0x41]
@@ -39,7 +39,7 @@ asrl    r0, r0, #32
 asrl    r0, r1, r4
 
 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be an odd-numbered register in range [r1,r11]
-# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an odd-numbered register in range [r1,r11]
 asrl    r0, r0, r4
 
 # The assembler will reject the above shifts when MVE is not supported,

diff  --git a/llvm/test/MC/ARM/thumb-diagnostics.s b/llvm/test/MC/ARM/thumb-diagnostics.s
index ead459a4c1100..f6a0e975ca08b 100644
--- a/llvm/test/MC/ARM/thumb-diagnostics.s
+++ b/llvm/test/MC/ARM/thumb-diagnostics.s
@@ -399,10 +399,10 @@
         stc2l p6, c2, [r7, #4]
         ldc2 p0, c8, [r1, #4]
         ldc2l p6, c2, [r7, #4]
-@ CHECK-ERRORS: error: invalid instruction
-@ CHECK-ERRORS: error: invalid instruction
-@ CHECK-ERRORS: error: invalid instruction
-@ CHECK-ERRORS: error: invalid instruction
+@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: invalid operand for instruction
 
 @------------------------------------------------------------------------------
 @ Generic error for too few operands

diff  --git a/llvm/test/MC/ARM/thumb2-diagnostics.s b/llvm/test/MC/ARM/thumb2-diagnostics.s
index 70878a13990e3..5b220aed6433f 100644
--- a/llvm/test/MC/ARM/thumb2-diagnostics.s
+++ b/llvm/test/MC/ARM/thumb2-diagnostics.s
@@ -43,11 +43,10 @@
 @ CHECK-ERRORS: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
-@ CHECK-ERRORS-V8: invalid instruction
 @ CHECK-ERRORS-V8: too many operands for instruction
 @ CHECK-ERRORS: operand must be an immediate in the range [0,15]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,15]
-@ CHECK-ERRORS-V8: invalid instruction
+@ CHECK-ERRORS-V8: invalid operand for instruction
 
         @ Out of range immediate for ROR.
         @ (Assembling this instruction to "mov r1, r1" might also be OK.)
@@ -135,7 +134,7 @@ foo2:
 @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
 @ CHECK-ERRORS: note: instruction requires: arm-mode
 @ CHECK-ERRORS: note: invalid operand for instruction
-@ CHECK-ERRORS: error: invalid instruction
+@ CHECK-ERRORS: error: invalid operand for instruction
 @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
 @ CHECK-ERRORS: note: invalid operand for instruction
 @ CHECK-ERRORS: note: instruction requires: arm-mode

diff  --git a/llvm/test/MC/ARM/thumb2-dsp-diag.s b/llvm/test/MC/ARM/thumb2-dsp-diag.s
index 611453e85182b..658211ae50ef2 100644
--- a/llvm/test/MC/ARM/thumb2-dsp-diag.s
+++ b/llvm/test/MC/ARM/thumb2-dsp-diag.s
@@ -10,7 +10,7 @@ sxtb16 r0, r0, ror #8
 @ CHECK-ERRORS: error: instruction requires: dsp
 @ CHECK-ERRORS: error: instruction requires: dsp
 @ CHECK-ERRORS: error: instruction requires: dsp
-@ CHECK-ERRORS: error: invalid instruction
+@ CHECK-ERRORS: error: operand must be a register in range [r0, r14]
 @ CHECK-7EM: sxtab	r0, r0, r0              @ encoding: [0x40,0xfa,0x80,0xf0]
 @ CHECK-7EM: sxtah	r0, r0, r0              @ encoding: [0x00,0xfa,0x80,0xf0]
 @ CHECK-7EM: sxtab16	r0, r0, r0              @ encoding: [0x20,0xfa,0x80,0xf0]
@@ -26,7 +26,7 @@ uxtb16 r0, r0, ror #8
 @ CHECK-ERRORS: error: instruction requires: dsp
 @ CHECK-ERRORS: error: instruction requires: dsp
 @ CHECK-ERRORS: error: instruction requires: dsp
-@ CHECK-ERRORS: error: invalid instruction
+@ CHECK-ERRORS: error: operand must be a register in range [r0, r14]
 @ CHECK-7EM: uxtab	r0, r0, r0              @ encoding: [0x50,0xfa,0x80,0xf0]
 @ CHECK-7EM: uxtah	r0, r0, r0              @ encoding: [0x10,0xfa,0x80,0xf0]
 @ CHECK-7EM: uxtab16	r0, r0, r0              @ encoding: [0x30,0xfa,0x80,0xf0]

diff  --git a/llvm/test/MC/ARM/thumbv7m.s b/llvm/test/MC/ARM/thumbv7m.s
index 3afd7467aaba1..f0b04b225a9e3 100644
--- a/llvm/test/MC/ARM/thumbv7m.s
+++ b/llvm/test/MC/ARM/thumbv7m.s
@@ -36,10 +36,10 @@
 @ CHECK-V6M-NEXT: mrs r0, basepri_max
 @ CHECK-V6M: error: invalid instruction
 @ CHECK-V6M-NEXT: mrs r0, faultmask
-@ CHECK-V6M: error: invalid instruction
+@ CHECK-V6M: error: invalid operand for instruction
 @ CHECK-V6M-NEXT: msr basepri, r0
-@ CHECK-V6M: error: invalid instruction
+@ CHECK-V6M: error: invalid operand for instruction
 @ CHECK-V6M-NEXT: msr basepri_max, r0
-@ CHECK-V6M: error: invalid instruction
+@ CHECK-V6M: error: invalid operand for instruction
 @ CHECK-V6M-NEXT: msr faultmask, r0
 

diff  --git a/llvm/test/MC/ARM/thumbv8m.s b/llvm/test/MC/ARM/thumbv8m.s
index f03dd03dae3a4..63c32dd8da591 100644
--- a/llvm/test/MC/ARM/thumbv8m.s
+++ b/llvm/test/MC/ARM/thumbv8m.s
@@ -274,12 +274,12 @@ tt pc, r0
 // UNDEF:     tt r0, pc
 tt r0, pc
 
-// UNDEF-BASELINE: error: invalid instruction
+// UNDEF-BASELINE: error: operand must be a register in range [r0, r14]
 // UNDEF-MAINLINE: error: operand must be a register in range [r0, r14]
 // UNDEF:     vlldm pc
 vlldm pc
 
-// UNDEF-BASELINE: error: invalid instruction
+// UNDEF-BASELINE: error: operand must be a register in range [r0, r14]
 // UNDEF-MAINLINE: error: operand must be a register in range [r0, r14]
 // UNDEF:     vlstm pc
 vlstm pc

diff  --git a/llvm/test/MC/ARM/vmrs_vmsr.s b/llvm/test/MC/ARM/vmrs_vmsr.s
index 9193ae1b12ed2..57f7e5e198685 100644
--- a/llvm/test/MC/ARM/vmrs_vmsr.s
+++ b/llvm/test/MC/ARM/vmrs_vmsr.s
@@ -113,7 +113,7 @@
 // ERROR-NOVFP: instruction requires: VFP2
 // ERROR-NOVFP: instruction requires: FPARMv8
 // ERROR-NOVFP: invalid instruction
-// ERROR-NOVFP: invalid instruction
+// ERROR-NOVFP: operand must be a register in range [r0, r14]
 
         vmsr  fpscr, APSR_nzcv
         vmsr  fpscr, r0
@@ -171,10 +171,10 @@
 // ERROR-V8M: invalid operand for instruction
 // ERROR-V8M: operand must be a register in range [r0, r14]
 
-// ERROR-NOVFP: invalid instruction
+// ERROR-NOVFP: invalid operand for instruction
 // ERROR-NOVFP: instruction requires: fp registers
 // ERROR-NOVFP: instruction requires: VFP2
 // ERROR-NOVFP: instruction requires: VFP2
 // ERROR-NOVFP: instruction requires: fp registers
 // ERROR-NOVFP: invalid instruction
-// ERROR-NOVFP: invalid instruction
+// ERROR-NOVFP: invalid operand for instruction

diff  --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index 4c61d64ec215a..7608e0f31b3f4 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -3784,6 +3784,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";
   OS << "    return Match_MnemonicFail;\n\n";
 
+  if (ReportMultipleNearMisses) {
+    OS << "  // First operand near-miss of each opcode that mismatched in\n";
+    OS << "  // more than one operand. Used only if no opcode yields a\n";
+    OS << "  // near-miss of its own (see below).\n";
+    OS << "  SmallVector<NearMissInfo, 4> MultiMismatchFallback;\n\n";
+  }
+
   OS << "  for (const MatchEntry *it = MnemonicRange.first, "
      << "*ie = MnemonicRange.second;\n";
   OS << "       it != ie; ++it) {\n";
@@ -3985,6 +3992,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "                                               \"operand mismatches, "
         "ignoring \"\n";
   OS << "                                               \"this opcode\\n\");\n";
+  if (ReportMultipleNearMisses) {
+    OS << "      // Too many invalid operands to report a single near-miss;\n";
+    OS << "      // keep the first one as a fallback in case no opcode\n";
+    OS << "      // matches more closely.\n";
+    OS << "      if (OperandNearMiss)\n";
+    OS << "        MultiMismatchFallback.push_back(OperandNearMiss);\n";
+  }
   OS << "      continue;\n";
   OS << "    }\n";
 
@@ -4212,7 +4226,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "  }\n\n";
 
   if (ReportMultipleNearMisses) {
-    OS << "  // No instruction variants matched exactly.\n";
+    OS << "  // No instruction variants matched exactly. If nothing produced\n";
+    OS << "  // a near-miss, fall back to the multi-mismatch list so we can\n";
+    OS << "  // still give a specific diagnostic rather than a generic\n";
+    OS << "  // \"invalid instruction\".\n";
+    OS << "  if (NearMisses && NearMisses->empty())\n";
+    OS << "    NearMisses->append(MultiMismatchFallback.begin(),\n";
+    OS << "                       MultiMismatchFallback.end());\n";
     OS << "  return Match_NearMisses;\n";
   } else {
     OS << "  // Okay, we had no match.  Try to return a useful error code.\n";


        


More information about the llvm-commits mailing list