[clang] 8cd90fd - [X86][MC] Fix parsing Intel syntax indirect branch with symbol only
Alvin Wong via cfe-commits
cfe-commits at lists.llvm.org
Mon May 8 09:08:06 PDT 2023
Author: Alvin Wong
Date: 2023-05-09T00:07:40+08:00
New Revision: 8cd90fd1a8233b2dcb96451eab7c6baea3180f54
URL: https://github.com/llvm/llvm-project/commit/8cd90fd1a8233b2dcb96451eab7c6baea3180f54
DIFF: https://github.com/llvm/llvm-project/commit/8cd90fd1a8233b2dcb96451eab7c6baea3180f54.diff
LOG: [X86][MC] Fix parsing Intel syntax indirect branch with symbol only
Clang on Windows targets often requires indirect calls through the
import address table (IAT), and also .refptr stubs for MinGW target.
On 32-bit this generates assembly in the form of
`call dword ptr [__imp__func]`, which MC had failed to handle correctly.
64-bit targets are not affected because rip-relative addressing is used.
Reported on: https://github.com/llvm/llvm-project/issues/62010
Depends on D149695, D149920
Differential Revision: https://reviews.llvm.org/D149579
Added:
llvm/test/MC/X86/intel-syntax-branch.s
Modified:
clang/test/CodeGen/ms-inline-asm-functions.c
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
Removed:
################################################################################
diff --git a/clang/test/CodeGen/ms-inline-asm-functions.c b/clang/test/CodeGen/ms-inline-asm-functions.c
index 26eaf144adf25..57abcc20ca85a 100644
--- a/clang/test/CodeGen/ms-inline-asm-functions.c
+++ b/clang/test/CodeGen/ms-inline-asm-functions.c
@@ -24,10 +24,9 @@ int foo(void) {
__asm call kimport;
// CHECK: calll *({{.*}})
- // Broken case: Call through a global function pointer.
+ // Call through a global function pointer.
__asm call kptr;
- // CHECK: calll _kptr
- // CHECK-FIXME: calll *_kptr
+ // CHECK: calll *_kptr
}
int bar(void) {
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 6799234df5352..2647117f02732 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -433,6 +433,7 @@ class X86AsmParser : public MCTargetAsmParser {
InlineAsmIdentifierInfo Info;
short BracCount = 0;
bool MemExpr = false;
+ bool BracketUsed = false;
bool OffsetOperator = false;
bool AttachToOperandIdx = false;
bool IsPIC = false;
@@ -455,6 +456,7 @@ class X86AsmParser : public MCTargetAsmParser {
void addImm(int64_t imm) { Imm += imm; }
short getBracCount() const { return BracCount; }
bool isMemExpr() const { return MemExpr; }
+ bool isBracketUsed() const { return BracketUsed; }
bool isOffsetOperator() const { return OffsetOperator; }
SMLoc getOffsetLoc() const { return OffsetOperatorLoc; }
unsigned getBaseReg() const { return BaseReg; }
@@ -955,6 +957,7 @@ class X86AsmParser : public MCTargetAsmParser {
break;
}
MemExpr = true;
+ BracketUsed = true;
BracCount++;
return false;
}
@@ -2628,9 +2631,9 @@ bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
unsigned DefaultBaseReg = X86::NoRegister;
bool MaybeDirectBranchDest = true;
+ bool IsUnconditionalBranch =
+ Name.equals_insensitive("jmp") || Name.equals_insensitive("call");
if (Parser.isParsingMasm()) {
- bool IsUnconditionalBranch =
- Name.equals_insensitive("jmp") || Name.equals_insensitive("call");
if (is64BitMode() && SM.getElementSize() > 0) {
DefaultBaseReg = X86::RIP;
}
@@ -2652,6 +2655,9 @@ bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
}
}
}
+ } else if (IsUnconditionalBranch) {
+ if (PtrInOperand || SM.isBracketUsed())
+ MaybeDirectBranchDest = false;
}
if ((BaseReg || IndexReg || RegNo || DefaultBaseReg != X86::NoRegister))
diff --git a/llvm/test/MC/X86/intel-syntax-branch.s b/llvm/test/MC/X86/intel-syntax-branch.s
new file mode 100644
index 0000000000000..22b91562ea51c
--- /dev/null
+++ b/llvm/test/MC/X86/intel-syntax-branch.s
@@ -0,0 +1,71 @@
+// RUN: llvm-mc -triple i686-unknown-unknown -x86-asm-syntax=intel %s | FileCheck %s --check-prefixes=CHECK-32,CHECK
+// RUN: llvm-mc -triple x86_64-unknown-unknown --defsym X64=1 -x86-asm-syntax=intel %s | FileCheck %s --check-prefixes=CHECK-64,CHECK
+
+// RUN: not llvm-mc -triple i686-unknown-unknown --defsym ERR=1 -x86-asm-syntax=intel %s 2>&1 | FileCheck %s --check-prefixes=ERR-32
+
+t0:
+call direct_branch
+jmp direct_branch
+// CHECK-LABEL: t0:
+// CHECK-64: callq direct_branch
+// CHECK-32: calll direct_branch
+// CHECK: jmp direct_branch
+
+t1:
+call [fn_ref]
+jmp [fn_ref]
+// CHECK-LABEL: t1:
+// CHECK-64: callq *fn_ref
+// CHECK-64: jmpq *fn_ref
+// CHECK-32: calll *fn_ref
+// CHECK-32: jmpl *fn_ref
+
+.ifdef X64
+
+ t2:
+ call qword ptr [fn_ref]
+ jmp qword ptr [fn_ref]
+ // CHECK-64-LABEL: t2:
+ // CHECK-64: callq *fn_ref
+ // CHECK-64: jmpq *fn_ref
+
+ t3:
+ call qword ptr [rip + fn_ref]
+ jmp qword ptr [rip + fn_ref]
+ // CHECK-64-LABEL: t3:
+ // CHECK-64: callq *fn_ref(%rip)
+ // CHECK-64: jmpq *fn_ref(%rip)
+
+.else
+
+ t4:
+ call dword ptr [fn_ref]
+ jmp dword ptr [fn_ref]
+ // CHECK-32-LABEL: t4:
+ // CHECK-32: calll *fn_ref
+ // CHECK-32: jmpl *fn_ref
+
+ t5:
+ call dword ptr fn_ref
+ jmp dword ptr fn_ref
+ // CHECK-32-LABEL: t5:
+ // CHECK-32: calll *fn_ref
+ // CHECK-32: jmpl *fn_ref
+
+ t6:
+ call dword ptr [offset fn_ref]
+ jmp dword ptr [offset fn_ref]
+ // CHECK-32-LABEL: t6:
+ // CHECK-32: calll *fn_ref
+ // CHECK-32: jmpl *fn_ref
+
+.ifdef ERR
+
+ call offset fn_ref
+ // ERR-32: {{.*}}.s:[[#@LINE-1]]:3: error: invalid operand for instruction
+ jmp offset fn_ref
+ // ERR-32: {{.*}}.s:[[#@LINE-1]]:3: error: invalid operand for instruction
+
+.endif
+
+.endif
More information about the cfe-commits
mailing list