[llvm] 5b9e1a5 - [X86][AsmParser] Improve rel8 validation (#126073)

via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 6 12:45:20 PST 2025


Author: Evgenii Kudriashov
Date: 2025-03-06T21:45:16+01:00
New Revision: 5b9e1a57580c2589b84b2c37474795656574b7e1

URL: https://github.com/llvm/llvm-project/commit/5b9e1a57580c2589b84b2c37474795656574b7e1
DIFF: https://github.com/llvm/llvm-project/commit/5b9e1a57580c2589b84b2c37474795656574b7e1.diff

LOG: [X86][AsmParser] Improve rel8 validation (#126073)

* Check the size of immediate operand of rel8
* Rename AbsMem16 related names to AbsMemMode16 to disambiguate mem size
and mode checks.

Added: 
    

Modified: 
    llvm/lib/Target/X86/AsmParser/X86Operand.h
    llvm/lib/Target/X86/X86InstrControl.td
    llvm/lib/Target/X86/X86InstrOperands.td
    llvm/test/MC/X86/I386-32.s
    llvm/test/MC/X86/I386-64.s
    llvm/test/MC/X86/intel-syntax.s
    llvm/test/MC/X86/validate-inst-intel.s
    llvm/utils/TableGen/X86RecognizableInstr.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h
index d715fd1903802..1fa82a16860c8 100644
--- a/llvm/lib/Target/X86/AsmParser/X86Operand.h
+++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h
@@ -416,10 +416,16 @@ 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 (auto *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
+      return isImmSExti64i8Value(CE->getValue());
+    return true;
   }
 
+  bool isAbsMem8() const { return isAbsMem() && isMem8() && isDispImm8(); }
+
   bool isMemUseUpRegs() const override { return UseUpRegs; }
 
   bool isSrcIdx() const {

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 cefe4d7092478..53a6b7c4c4c92 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/I386-32.s b/llvm/test/MC/X86/I386-32.s
index 0915300d3f7b2..0b835d4b1de15 100644
--- a/llvm/test/MC/X86/I386-32.s
+++ b/llvm/test/MC/X86/I386-32.s
@@ -176,6 +176,10 @@ iretl
 // CHECK: encoding: [0x66,0xcf]          
 iretw 
 
+// CHECK: jcxz 64
+// CHECK: encoding: [0x67,0xe3,A]
+jcxz 64
+
 // CHECK: jecxz 64 
 // CHECK: encoding: [0xe3,A]         
 jecxz 64 

diff  --git a/llvm/test/MC/X86/I386-64.s b/llvm/test/MC/X86/I386-64.s
index b4f2c79d499fe..4e8ab348a644c 100644
--- a/llvm/test/MC/X86/I386-64.s
+++ b/llvm/test/MC/X86/I386-64.s
@@ -257,6 +257,14 @@ iretq
 // CHECK: encoding: [0x66,0xcf]          
 iretw 
 
+// CHECK: jecxz 64
+// CHECK: encoding: [0x67,0xe3,A]
+jecxz 64
+
+// CHECK: jrcxz 64
+// CHECK: encoding: [0xe3,A]
+jrcxz 64
+
 // CHECK: lodsl %gs:(%rsi), %eax 
 // CHECK: encoding: [0x65,0xad]        
 lodsl %gs:(%rsi), %eax 

diff  --git a/llvm/test/MC/X86/intel-syntax.s b/llvm/test/MC/X86/intel-syntax.s
index c622832d24bea..13616a00b249e 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
@@ -72,6 +75,8 @@ main:
   jnc short _foo
 // CHECK: jecxz _foo
   jecxz short _foo
+// CHECK: jrcxz _nop_label+1
+  jrcxz _nop_label+1
 // CHECK: jp _foo
   jpe short _foo
 
@@ -825,8 +830,10 @@ fucomip st, st(2)
 // CHECK: fcompi  %st(2)
 // CHECK: fucompi  %st(2)
 
+loop byte ptr [64]
 loopz _foo
 loopnz _foo
+// CHECK: loop 64
 // CHECK: loope _foo
 // CHECK: loopne _foo
 

diff  --git a/llvm/test/MC/X86/validate-inst-intel.s b/llvm/test/MC/X86/validate-inst-intel.s
index 466b906fee731..abf84ca96ef45 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 WORD PTR [SYM+4]
+# CHECK: error: invalid operand for instruction
+# CHECK:	loop WORD 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 003c8266c4785..dbfb926b16ff7 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)
@@ -1409,6 +1410,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)


        


More information about the llvm-commits mailing list