Skip to content

Commit f42c203

Browse files
woruyumahesh-attarde
authored andcommitted
[X86][MC][AsmParser] Reject H-byte regs with VEX/EVEX-encoded 8-bit RR (NDD) (llvm#160039)
### Summary This PR resolves llvm#158585.
1 parent 72f6e96 commit f42c203

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4018,9 +4018,14 @@ bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
40184018
return Error(Ops[0]->getStartLoc(), "all tmm registers must be distinct");
40194019
}
40204020

4021-
// Check that we aren't mixing AH/BH/CH/DH with REX prefix. We only need to
4022-
// check this with the legacy encoding, VEX/EVEX/XOP don't use REX.
4023-
if ((TSFlags & X86II::EncodingMask) == 0) {
4021+
// High 8-bit regs (AH/BH/CH/DH) are incompatible with encodings that imply
4022+
// extended prefixes:
4023+
// * Legacy path that would emit a REX (e.g. uses r8..r15 or sil/dil/bpl/spl)
4024+
// * EVEX
4025+
// * REX2
4026+
// VEX/XOP don't use REX; they are excluded from the legacy check.
4027+
const unsigned Enc = TSFlags & X86II::EncodingMask;
4028+
if (Enc != X86II::VEX && Enc != X86II::XOP) {
40244029
MCRegister HReg;
40254030
bool UsesRex = TSFlags & X86II::REX_W;
40264031
unsigned NumOps = Inst.getNumOperands();
@@ -4036,11 +4041,13 @@ bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
40364041
UsesRex = true;
40374042
}
40384043

4039-
if (UsesRex && HReg) {
4044+
if (HReg &&
4045+
(Enc == X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4046+
ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
40404047
StringRef RegName = X86IntelInstPrinter::getRegisterName(HReg);
40414048
return Error(Ops[0]->getStartLoc(),
4042-
"can't encode '" + RegName + "' in an instruction requiring "
4043-
"REX prefix");
4049+
"can't encode '" + RegName.str() +
4050+
"' in an instruction requiring EVEX/REX2/REX prefix");
40444051
}
40454052
}
40464053

llvm/test/MC/X86/encoder-fail.s

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,38 @@
11
// RUN: not llvm-mc -triple x86_64-unknown-unknown --show-encoding %s 2>&1 | FileCheck %s
2+
// RUN: not llvm-mc -triple x86_64-unknown-unknown --show-encoding -x86-asm-syntax=intel %s 2>&1 | FileCheck %s --check-prefix=CHECK-INTEL
23

3-
// CHECK: error: can't encode 'dh' in an instruction requiring REX prefix
4+
// CHECK: error: can't encode 'dh' in an instruction requiring EVEX/REX2/REX prefix
45
movzx %dh, %rsi
56

6-
// CHECK: error: can't encode 'ah' in an instruction requiring REX prefix
7+
// CHECK: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
78
movzx %ah, %r8d
89

9-
// CHECK: error: can't encode 'bh' in an instruction requiring REX prefix
10+
// CHECK: error: can't encode 'bh' in an instruction requiring EVEX/REX2/REX prefix
1011
add %bh, %sil
1112

12-
// CHECK: error: can't encode 'ch' in an instruction requiring REX prefix
13+
// CHECK: error: can't encode 'ch' in an instruction requiring EVEX/REX2/REX prefix
1314
mov %ch, (%r8)
1415

15-
// CHECK: error: can't encode 'dh' in an instruction requiring REX prefix
16+
// CHECK: error: can't encode 'dh' in an instruction requiring EVEX/REX2/REX prefix
1617
mov %dh, (%rax,%r8)
18+
19+
// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
20+
add ah, ah, ah
21+
22+
// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
23+
and ah, byte ptr [-13426159], ah
24+
25+
// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
26+
ccmpa {dfv=of,cf} byte ptr [r8 + 4*rax + 291], ah
27+
28+
// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
29+
ccmpae {dfv=of,cf} byte ptr [r8 + 4*rax + 291], ah
30+
31+
// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
32+
sar ah, byte ptr [-13426159]
33+
34+
// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
35+
{rex2} add ah, al
36+
37+
// CHECK-INTEL: error: can't encode 'ah' in an instruction requiring EVEX/REX2/REX prefix
38+
{rex} add ah, al

0 commit comments

Comments
 (0)