[llvm] [X86][AsmParser] Improve rel8 validation (PR #126073)
Evgenii Kudriashov via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 26 11:15:10 PST 2025
https://github.com/e-kud updated https://github.com/llvm/llvm-project/pull/126073
>From 24d86a429164c782049cc3917149df4fa07e93f2 Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Thu, 6 Feb 2025 05:08:09 -0800
Subject: [PATCH 1/3] [X86][AsmParser] Improve rel8 validation
* Check that input of rel8 operand is either a symbol or 8 bit immediate
* Rename AbsMem16 related names to AbsMemMode16 to disambiguate mem size
and mode checks.
---
llvm/lib/Target/X86/AsmParser/X86Operand.h | 13 +++++--
llvm/lib/Target/X86/X86InstrControl.td | 15 ++++----
llvm/lib/Target/X86/X86InstrOperands.td | 15 ++++++--
llvm/test/MC/X86/validate-inst-intel.s | 36 ++++++++++++++++++++
llvm/utils/TableGen/X86RecognizableInstr.cpp | 2 ++
5 files changed, 70 insertions(+), 11 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h
index d715fd1903802..953ae76b2a63a 100644
--- a/llvm/lib/Target/X86/AsmParser/X86Operand.h
+++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h
@@ -416,8 +416,17 @@ struct X86Operand final : public MCParsedAsmOperand {
return isImm();
}
- bool isAbsMem16() const {
- return isAbsMem() && Mem.ModeSize == 16;
+ bool isAbsMemMode16() const { return isAbsMem() && Mem.ModeSize == 16; }
+
+ bool isDispImm8() const {
+ if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
+ return isImmSExti64i8Value(CE->getValue());
+ return false;
+ }
+
+ bool isAbsMem8() const {
+ return isAbsMem() && isMem8() &&
+ (isa<MCSymbolRefExpr>(getMemDisp()) || isDispImm8());
}
bool isMemUseUpRegs() const override { return UseUpRegs; }
diff --git a/llvm/lib/Target/X86/X86InstrControl.td b/llvm/lib/Target/X86/X86InstrControl.td
index 62cc758cc594b..4907105e6b8cc 100644
--- a/llvm/lib/Target/X86/X86InstrControl.td
+++ b/llvm/lib/Target/X86/X86InstrControl.td
@@ -94,14 +94,14 @@ let isBranch = 1, isTerminator = 1, hasSideEffects = 0, SchedRW = [WriteJump] in
// 32-bit mode, the address size prefix is jcxz and the unprefixed version is
// jecxz.
let Uses = [CX] in
- def JCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
+ def JCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins i8imm_brtarget:$dst),
"jcxz\t$dst", []>, AdSize16, Requires<[Not64BitMode]>;
let Uses = [ECX] in
- def JECXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
+ def JECXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins i8imm_brtarget:$dst),
"jecxz\t$dst", []>, AdSize32;
let Uses = [RCX] in
- def JRCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
+ def JRCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins i8imm_brtarget:$dst),
"jrcxz\t$dst", []>, AdSize64, Requires<[In64BitMode]>;
}
@@ -193,9 +193,12 @@ def JMPABS64i : Ii64<0xA1, RawFrm, (outs), (ins i64imm:$dst), "jmpabs\t$dst", []
// Loop instructions
let isBranch = 1, isTerminator = 1, SchedRW = [WriteJump] in {
-def LOOP : Ii8PCRel<0xE2, RawFrm, (outs), (ins brtarget8:$dst), "loop\t$dst", []>;
-def LOOPE : Ii8PCRel<0xE1, RawFrm, (outs), (ins brtarget8:$dst), "loope\t$dst", []>;
-def LOOPNE : Ii8PCRel<0xE0, RawFrm, (outs), (ins brtarget8:$dst), "loopne\t$dst", []>;
+ def LOOP : Ii8PCRel<0xE2, RawFrm, (outs), (ins i8imm_brtarget:$dst),
+ "loop\t$dst", []>;
+ def LOOPE : Ii8PCRel<0xE1, RawFrm, (outs), (ins i8imm_brtarget:$dst),
+ "loope\t$dst", []>;
+ def LOOPNE : Ii8PCRel<0xE0, RawFrm, (outs), (ins i8imm_brtarget:$dst),
+ "loopne\t$dst", []>;
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/X86/X86InstrOperands.td b/llvm/lib/Target/X86/X86InstrOperands.td
index 4f427d6d9d72e..266d1dbe60624 100644
--- a/llvm/lib/Target/X86/X86InstrOperands.td
+++ b/llvm/lib/Target/X86/X86InstrOperands.td
@@ -142,8 +142,14 @@ def i64mem_TC : X86MemOperand<"printqwordmem", X86Mem64AsmOperand, 64> {
}
// Special parser to detect 16-bit mode to select 16-bit displacement.
-def X86AbsMem16AsmOperand : AsmOperandClass {
- let Name = "AbsMem16";
+def X86AbsMemMode16AsmOperand : AsmOperandClass {
+ let Name = "AbsMemMode16";
+ let RenderMethod = "addAbsMemOperands";
+ let SuperClasses = [X86AbsMemAsmOperand];
+}
+
+def X86AbsMem8AsmOperand : AsmOperandClass {
+ let Name = "AbsMem8";
let RenderMethod = "addAbsMemOperands";
let SuperClasses = [X86AbsMemAsmOperand];
}
@@ -157,6 +163,9 @@ class BranchTargetOperand<ValueType ty> : Operand<ty> {
def i32imm_brtarget : BranchTargetOperand<i32>;
def i16imm_brtarget : BranchTargetOperand<i16>;
+def i8imm_brtarget : BranchTargetOperand<i8> {
+ let ParserMatchClass = X86AbsMem8AsmOperand;
+}
// 64-bits but only 32 bits are significant, and those bits are treated as being
// pc relative.
@@ -165,7 +174,7 @@ def i64i32imm_brtarget : BranchTargetOperand<i64>;
def brtarget : BranchTargetOperand<OtherVT>;
def brtarget8 : BranchTargetOperand<OtherVT>;
def brtarget16 : BranchTargetOperand<OtherVT> {
- let ParserMatchClass = X86AbsMem16AsmOperand;
+ let ParserMatchClass = X86AbsMemMode16AsmOperand;
}
def brtarget32 : BranchTargetOperand<OtherVT>;
diff --git a/llvm/test/MC/X86/validate-inst-intel.s b/llvm/test/MC/X86/validate-inst-intel.s
index 466b906fee731..1b134e9891860 100644
--- a/llvm/test/MC/X86/validate-inst-intel.s
+++ b/llvm/test/MC/X86/validate-inst-intel.s
@@ -13,3 +13,39 @@
# CHECK: int -129
# CHECK: ^
+ .text
+ loop BYTE PTR [SYM+4]
+# CHECK: error: invalid operand for instruction
+# CHECK: loop BYTE PTR [SYM+4]
+# CHECK: ^
+
+ .text
+ loope BYTE PTR [128]
+# CHECK: error: invalid operand for instruction
+# CHECK: loope BYTE PTR [128]
+# CHECK: ^
+
+ .text
+ loopne BYTE PTR [-129]
+# CHECK: error: invalid operand for instruction
+# CHECK: loopne BYTE PTR [-129]
+# CHECK: ^
+
+ .text
+ jrcxz XMMWORD PTR [0]
+# CHECK: error: invalid operand for instruction
+# CHECK: jrcxz XMMWORD PTR [0]
+# CHECK: ^
+
+ .text
+ jecxz BYTE PTR[-444]
+# CHECK: error: invalid operand for instruction
+# CHECK: jecxz BYTE PTR[-444]
+# CHECK: ^
+
+ .text
+ jcxz BYTE PTR[444]
+# CHECK: error: invalid operand for instruction
+# CHECK: jcxz BYTE PTR[444]
+# CHECK: ^
+
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index 607a6bd27c21f..c296f0e0b16fd 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -1087,6 +1087,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("i512mem_GR32", TYPE_M)
TYPE("i512mem_GR64", TYPE_M)
TYPE("i64i32imm_brtarget", TYPE_REL)
+ TYPE("i8imm_brtarget", TYPE_REL)
TYPE("i16imm_brtarget", TYPE_REL)
TYPE("i32imm_brtarget", TYPE_REL)
TYPE("ccode", TYPE_IMM)
@@ -1405,6 +1406,7 @@ RecognizableInstr::relocationEncodingFromString(const std::string &s,
ENCODING("i64i32imm_brtarget", ENCODING_ID)
ENCODING("i16imm_brtarget", ENCODING_IW)
ENCODING("i32imm_brtarget", ENCODING_ID)
+ ENCODING("i8imm_brtarget", ENCODING_IB)
ENCODING("brtarget32", ENCODING_ID)
ENCODING("brtarget16", ENCODING_IW)
ENCODING("brtarget8", ENCODING_IB)
>From d60fbb3c51195dda637cffbcbbed69069d7de3db Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Wed, 26 Feb 2025 08:35:50 -0800
Subject: [PATCH 2/3] Allow label+offset combination for relocation
---
llvm/lib/Target/X86/AsmParser/X86Operand.h | 5 ++---
llvm/test/MC/X86/intel-syntax.s | 6 ++++++
llvm/test/MC/X86/validate-inst-intel.s | 4 ++--
3 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h
index 953ae76b2a63a..9e1a7e020c5c2 100644
--- a/llvm/lib/Target/X86/AsmParser/X86Operand.h
+++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h
@@ -421,12 +421,11 @@ struct X86Operand final : public MCParsedAsmOperand {
bool isDispImm8() const {
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
return isImmSExti64i8Value(CE->getValue());
- return false;
+ return true;
}
bool isAbsMem8() const {
- return isAbsMem() && isMem8() &&
- (isa<MCSymbolRefExpr>(getMemDisp()) || isDispImm8());
+ return isAbsMem() && isMem8() && isDispImm8();
}
bool isMemUseUpRegs() const override { return UseUpRegs; }
diff --git a/llvm/test/MC/X86/intel-syntax.s b/llvm/test/MC/X86/intel-syntax.s
index c622832d24bea..386f42fa53d3b 100644
--- a/llvm/test/MC/X86/intel-syntax.s
+++ b/llvm/test/MC/X86/intel-syntax.s
@@ -2,6 +2,9 @@
// RUN: FileCheck < %t %s
// RUN: FileCheck --check-prefix=CHECK-STDERR < %t.err %s
+_nop_label:
+ nop
+
_test:
xor EAX, EAX
ret
@@ -825,6 +828,9 @@ fucomip st, st(2)
// CHECK: fcompi %st(2)
// CHECK: fucompi %st(2)
+jrcxz _nop_label
+jecxz _nop_label + 1
+
loopz _foo
loopnz _foo
// CHECK: loope _foo
diff --git a/llvm/test/MC/X86/validate-inst-intel.s b/llvm/test/MC/X86/validate-inst-intel.s
index 1b134e9891860..abf84ca96ef45 100644
--- a/llvm/test/MC/X86/validate-inst-intel.s
+++ b/llvm/test/MC/X86/validate-inst-intel.s
@@ -14,9 +14,9 @@
# CHECK: ^
.text
- loop BYTE PTR [SYM+4]
+ loop WORD PTR [SYM+4]
# CHECK: error: invalid operand for instruction
-# CHECK: loop BYTE PTR [SYM+4]
+# CHECK: loop WORD PTR [SYM+4]
# CHECK: ^
.text
>From 886f28ada77f4eecb026776c61c2916a61834883 Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Wed, 26 Feb 2025 11:11:41 -0800
Subject: [PATCH 3/3] Formatting
---
llvm/lib/Target/X86/AsmParser/X86Operand.h | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h
index 9e1a7e020c5c2..1fa82a16860c8 100644
--- a/llvm/lib/Target/X86/AsmParser/X86Operand.h
+++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h
@@ -419,14 +419,12 @@ struct X86Operand final : public MCParsedAsmOperand {
bool isAbsMemMode16() const { return isAbsMem() && Mem.ModeSize == 16; }
bool isDispImm8() const {
- if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
+ if (auto *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
return isImmSExti64i8Value(CE->getValue());
return true;
}
- bool isAbsMem8() const {
- return isAbsMem() && isMem8() && isDispImm8();
- }
+ bool isAbsMem8() const { return isAbsMem() && isMem8() && isDispImm8(); }
bool isMemUseUpRegs() const override { return UseUpRegs; }
More information about the llvm-commits
mailing list