[llvm] 7b2b375 - [X86][MC][AsmParser] Reject H-byte regs with VEX/EVEX-encoded 8-bit RR (NDD) (#160039)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 25 01:15:55 PDT 2025


Author: woruyu
Date: 2025-09-25T16:15:51+08:00
New Revision: 7b2b3756954d60a0da9712d4b1c6ad72b0f7219c

URL: https://github.com/llvm/llvm-project/commit/7b2b3756954d60a0da9712d4b1c6ad72b0f7219c
DIFF: https://github.com/llvm/llvm-project/commit/7b2b3756954d60a0da9712d4b1c6ad72b0f7219c.diff

LOG: [X86][MC][AsmParser] Reject H-byte regs with VEX/EVEX-encoded 8-bit RR (NDD) (#160039)

### Summary
This PR resolves https://github.com/llvm/llvm-project/issues/158585.

Added: 
    

Modified: 
    llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/test/MC/X86/encoder-fail.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index ce5e92135f706..253b737ce2290 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -4018,9 +4018,14 @@ bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
       return Error(Ops[0]->getStartLoc(), "all tmm registers must be distinct");
   }
 
-  // Check that we aren't mixing AH/BH/CH/DH with REX prefix. We only need to
-  // check this with the legacy encoding, VEX/EVEX/XOP don't use REX.
-  if ((TSFlags & X86II::EncodingMask) == 0) {
+  // High 8-bit regs (AH/BH/CH/DH) are incompatible with encodings that imply
+  // extended prefixes:
+  //  * Legacy path that would emit a REX (e.g. uses r8..r15 or sil/dil/bpl/spl)
+  //  * EVEX
+  //  * REX2
+  // VEX/XOP don't use REX; they are excluded from the legacy check.
+  const unsigned Enc = TSFlags & X86II::EncodingMask;
+  if (Enc != X86II::VEX && Enc != X86II::XOP) {
     MCRegister HReg;
     bool UsesRex = TSFlags & X86II::REX_W;
     unsigned NumOps = Inst.getNumOperands();
@@ -4036,11 +4041,13 @@ bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
         UsesRex = true;
     }
 
-    if (UsesRex && HReg) {
+    if (HReg &&
+        (Enc == X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
+         ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
       StringRef RegName = X86IntelInstPrinter::getRegisterName(HReg);
       return Error(Ops[0]->getStartLoc(),
-                   "can't encode '" + RegName + "' in an instruction requiring "
-                   "REX prefix");
+                   "can't encode '" + RegName.str() +
+                       "' in an instruction requiring EVEX/REX2/REX prefix");
     }
   }
 

diff  --git a/llvm/test/MC/X86/encoder-fail.s b/llvm/test/MC/X86/encoder-fail.s
index a8b9f48c8fb70..f5718e14d138f 100644
--- a/llvm/test/MC/X86/encoder-fail.s
+++ b/llvm/test/MC/X86/encoder-fail.s
@@ -1,16 +1,38 @@
 // RUN: not llvm-mc -triple x86_64-unknown-unknown --show-encoding %s 2>&1 | FileCheck %s
+// RUN: not llvm-mc -triple x86_64-unknown-unknown --show-encoding -x86-asm-syntax=intel %s 2>&1 | FileCheck %s --check-prefix=CHECK-INTEL
 
-// CHECK: error: can't encode 'dh' in an instruction requiring REX prefix
+// CHECK: error: can't encode 'dh' in an instruction requiring EVEX/REX2/REX prefix
 movzx %dh, %rsi
 
-// CHECK: error: can't encode 'ah' in an instruction requiring REX prefix
+// CHECK: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
 movzx %ah, %r8d
 
-// CHECK: error: can't encode 'bh' in an instruction requiring REX prefix
+// CHECK: error: can't encode 'bh' in an instruction requiring EVEX/REX2/REX prefix
 add %bh, %sil
 
-// CHECK: error: can't encode 'ch' in an instruction requiring REX prefix
+// CHECK: error: can't encode 'ch' in an instruction requiring EVEX/REX2/REX prefix
 mov %ch, (%r8)
 
-// CHECK: error: can't encode 'dh' in an instruction requiring REX prefix
+// CHECK: error: can't encode 'dh' in an instruction requiring EVEX/REX2/REX prefix
 mov %dh, (%rax,%r8)
+
+// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
+add ah, ah, ah
+
+// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
+and ah, byte ptr [-13426159], ah
+
+// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
+ccmpa {dfv=of,cf} byte ptr [r8 + 4*rax + 291], ah
+
+// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
+ccmpae {dfv=of,cf} byte ptr [r8 + 4*rax + 291], ah
+
+// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
+sar ah, byte ptr [-13426159]
+
+// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
+{rex2} add ah, al
+
+// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
+{rex} add ah, al


        


More information about the llvm-commits mailing list