[llvm] [X86][MC] Report error when the instruction length exceeds 15 bytes (PR #83708)

Shengchen Kan via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 4 00:03:50 PST 2024


https://github.com/KanRobert updated https://github.com/llvm/llvm-project/pull/83708

>From 30893c5d1b65e8168584d0cdc6f41fcf61ea51f2 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Sun, 3 Mar 2024 14:00:42 +0800
Subject: [PATCH 1/4] [X86][MC] Report error when the instruction length
 exceeds 15 bytes

The instruction-size limit of 15 bytes still applies to APX
instructions.

Note that it is possible for an EVEX-encoded legacy instruction to reach
the 15-byte instruction length limit: 4
bytes of EVEX prefix + 1 byte of opcode + 1 byte of ModRM + 1 byte of
SIB + 4 bytes of displacement + 4 bytes of immediate = 15 bytes in total, e.g.

```
addq    $184, -96, %rax   # encoding:
[0x62,0xf4,0xfc,0x18,0x81,0x04,0x25,0xa0,0xff,0xff,0xff,0xb8,0x00,0x00,0x00]
```

If we added a segment prefix like fs, the length would be 16.

In such a case, no additional (ASIZE or segment override) prefix can be
used.

To help users find this issue earlier, we change the internal compiler
error to error in this patch.
---
 .../X86/MCTargetDesc/X86MCCodeEmitter.cpp     |  5 ++--
 llvm/test/MC/X86/apx/long-instruction-err.s   | 25 +++++++++++++++++++
 2 files changed, 28 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/MC/X86/apx/long-instruction-err.s

diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index fdb11d1a408bb6..fd96a173af27e0 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -1924,8 +1924,9 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI,
   if ((TSFlags & X86II::OpMapMask) == X86II::ThreeDNow)
     emitByte(X86II::getBaseOpcodeFor(TSFlags), CB);
 
-  assert(CB.size() - StartByte <= 15 &&
-         "The size of instruction must be no longer than 15.");
+  if (CB.size() - StartByte > 15)
+    Ctx.reportError(MI.getLoc(),
+                    "The size of instruction must be no longer than 15.");
 #ifndef NDEBUG
   // FIXME: Verify.
   if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) {
diff --git a/llvm/test/MC/X86/apx/long-instruction-err.s b/llvm/test/MC/X86/apx/long-instruction-err.s
new file mode 100644
index 00000000000000..a2210ecad81709
--- /dev/null
+++ b/llvm/test/MC/X86/apx/long-instruction-err.s
@@ -0,0 +1,25 @@
+# RUN: not llvm-mc -triple x86_64 -show-encoding %s 2>&1 | FileCheck %s
+
+# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: addq    $1234, %cs:-96, %rax
+addq    $1234, %cs:-96, %rax
+
+# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: subq    $1234, %fs:257(%rbx, %rcx), %rax
+subq    $1234, %fs:257(%rbx, %rcx), %rax
+
+# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: orq     $1234, 257(%ebx, %ecx), %rax
+orq     $1234, 257(%ebx, %ecx), %rax
+
+# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: xorq    $1234, %gs:257(%ebx), %rax
+xorq    $1234, %gs:257(%ebx), %rax
+
+# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: {nf} andq    $1234, %cs:-96
+{nf} andq    $1234, %cs:-96
+
+# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: {evex} adcq    $1234, %cs:-96
+{evex} adcq    $1234, %cs:-96

>From f3070ee30b4d5638283d79ac3cd50ea872d24679 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Mon, 4 Mar 2024 10:44:33 +0800
Subject: [PATCH 2/4] address review comment: refine err message

---
 llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index fd96a173af27e0..ba88b413890de1 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -1926,7 +1926,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI,
 
   if (CB.size() - StartByte > 15)
     Ctx.reportError(MI.getLoc(),
-                    "The size of instruction must be no longer than 15.");
+                    "the size of instruction must be no longer than 15");
 #ifndef NDEBUG
   // FIXME: Verify.
   if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) {

>From 35c15f51987de99847cd621c601d052eb838fcb9 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Mon, 4 Mar 2024 11:13:03 +0800
Subject: [PATCH 3/4] update test after err message is changed

---
 llvm/test/MC/X86/apx/long-instruction-err.s | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/test/MC/X86/apx/long-instruction-err.s b/llvm/test/MC/X86/apx/long-instruction-err.s
index a2210ecad81709..4fb2b8beb1baf0 100644
--- a/llvm/test/MC/X86/apx/long-instruction-err.s
+++ b/llvm/test/MC/X86/apx/long-instruction-err.s
@@ -1,25 +1,25 @@
 # RUN: not llvm-mc -triple x86_64 -show-encoding %s 2>&1 | FileCheck %s
 
-# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: error: the size of instruction must be no longer than 15
 # CHECK: addq    $1234, %cs:-96, %rax
 addq    $1234, %cs:-96, %rax
 
-# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: error: the size of instruction must be no longer than 15
 # CHECK: subq    $1234, %fs:257(%rbx, %rcx), %rax
 subq    $1234, %fs:257(%rbx, %rcx), %rax
 
-# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: error: the size of instruction must be no longer than 15
 # CHECK: orq     $1234, 257(%ebx, %ecx), %rax
 orq     $1234, 257(%ebx, %ecx), %rax
 
-# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: error: the size of instruction must be no longer than 15
 # CHECK: xorq    $1234, %gs:257(%ebx), %rax
 xorq    $1234, %gs:257(%ebx), %rax
 
-# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: error: the size of instruction must be no longer than 15
 # CHECK: {nf} andq    $1234, %cs:-96
 {nf} andq    $1234, %cs:-96
 
-# CHECK: error: The size of instruction must be no longer than 15.
+# CHECK: error: the size of instruction must be no longer than 15
 # CHECK: {evex} adcq    $1234, %cs:-96
 {evex} adcq    $1234, %cs:-96

>From e55d73b469c2b24bbb4e2c462d1ad98a226d98c7 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Mon, 4 Mar 2024 16:02:40 +0800
Subject: [PATCH 4/4] Address review comments: align with binutils and test
 file/line information

---
 .../lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp |  3 +--
 llvm/test/MC/X86/apx/long-instruction-err.s          | 12 ++++++------
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index ba88b413890de1..1fa676eeb79b0f 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -1925,8 +1925,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI,
     emitByte(X86II::getBaseOpcodeFor(TSFlags), CB);
 
   if (CB.size() - StartByte > 15)
-    Ctx.reportError(MI.getLoc(),
-                    "the size of instruction must be no longer than 15");
+    Ctx.reportError(MI.getLoc(), "instruction length exceeds the limit of 15");
 #ifndef NDEBUG
   // FIXME: Verify.
   if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) {
diff --git a/llvm/test/MC/X86/apx/long-instruction-err.s b/llvm/test/MC/X86/apx/long-instruction-err.s
index 4fb2b8beb1baf0..966c6d893521a2 100644
--- a/llvm/test/MC/X86/apx/long-instruction-err.s
+++ b/llvm/test/MC/X86/apx/long-instruction-err.s
@@ -1,25 +1,25 @@
 # RUN: not llvm-mc -triple x86_64 -show-encoding %s 2>&1 | FileCheck %s
 
-# CHECK: error: the size of instruction must be no longer than 15
+# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
 # CHECK: addq    $1234, %cs:-96, %rax
 addq    $1234, %cs:-96, %rax
 
-# CHECK: error: the size of instruction must be no longer than 15
+# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
 # CHECK: subq    $1234, %fs:257(%rbx, %rcx), %rax
 subq    $1234, %fs:257(%rbx, %rcx), %rax
 
-# CHECK: error: the size of instruction must be no longer than 15
+# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
 # CHECK: orq     $1234, 257(%ebx, %ecx), %rax
 orq     $1234, 257(%ebx, %ecx), %rax
 
-# CHECK: error: the size of instruction must be no longer than 15
+# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
 # CHECK: xorq    $1234, %gs:257(%ebx), %rax
 xorq    $1234, %gs:257(%ebx), %rax
 
-# CHECK: error: the size of instruction must be no longer than 15
+# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
 # CHECK: {nf} andq    $1234, %cs:-96
 {nf} andq    $1234, %cs:-96
 
-# CHECK: error: the size of instruction must be no longer than 15
+# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
 # CHECK: {evex} adcq    $1234, %cs:-96
 {evex} adcq    $1234, %cs:-96



More information about the llvm-commits mailing list