From c69547136582e1e3155c903202583aea6490faf0 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 29 Apr 2015 16:46:01 +0000 Subject: [PATCH] [X86] Avoid mangling frameescape labels x86 Windows uses the '_' prefix for all global symbols, and this was mistakenly being applied to frameescape labels, which are not externally visible global symbols. They use the private global prefix 'L'. The *right* way to fix this is probably to stop masquerading this label as an ExternalSymbol and create a new SDNode type. These labels are not "external", and we know they will be resolved by assembly time. Having a custom SDNode type would allow us to do better X86 address mode matching, so it's probably worth doing eventually. llvm-svn: 236123 --- llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 6 +++++- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 2 ++ llvm/lib/Target/X86/X86MCInstLower.cpp | 6 +++++- llvm/test/CodeGen/X86/frameescape.ll | 6 +++--- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index d4698bf492ad..85b00068252d 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -213,7 +213,11 @@ namespace X86II { /// the offset from beginning of section. /// /// This is the TLS offset for the COFF/Windows TLS mechanism. - MO_SECREL + MO_SECREL, + + /// MO_NOPREFIX - On a symbol operand this indicates that the symbol should + /// not be mangled with a prefix. + MO_NOPREFIX, }; enum : uint64_t { diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 0219430f812a..fa71e3a599f5 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -1009,7 +1009,9 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, if (!AM.hasSymbolicDisplacement()) if (const auto *ESNode = dyn_cast(N.getOperand(0))) if (ESNode->getOpcode() == ISD::TargetExternalSymbol) { + // Use the symbol and don't prefix it. AM.ES = ESNode->getSymbol(); + AM.SymbolFlags = X86II::MO_NOPREFIX; return false; } break; diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index 7eabff628ff8..9ad03ae383be 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -154,7 +154,10 @@ GetSymbolFromOperand(const MachineOperand &MO) const { const GlobalValue *GV = MO.getGlobal(); AsmPrinter.getNameWithPrefix(Name, GV); } else if (MO.isSymbol()) { - getMang()->getNameWithPrefix(Name, MO.getSymbolName()); + if (MO.getTargetFlags() == X86II::MO_NOPREFIX) + Name += MO.getSymbolName(); + else + getMang()->getNameWithPrefix(Name, MO.getSymbolName()); } else if (MO.isMBB()) { Name += MO.getMBB()->getSymbol()->getName(); } @@ -231,6 +234,7 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, case X86II::MO_DARWIN_NONLAZY: case X86II::MO_DLLIMPORT: case X86II::MO_DARWIN_STUB: + case X86II::MO_NOPREFIX: break; case X86II::MO_TLVP: RefKind = MCSymbolRefExpr::VK_TLVP; break; diff --git a/llvm/test/CodeGen/X86/frameescape.ll b/llvm/test/CodeGen/X86/frameescape.ll index 3a624ae863de..098b6162e821 100644 --- a/llvm/test/CodeGen/X86/frameescape.ll +++ b/llvm/test/CodeGen/X86/frameescape.ll @@ -37,15 +37,15 @@ define void @print_framealloc_from_fp(i8* %fp) { ; X86: pushl %esi ; X86: subl $8, %esp ; X86: movl 16(%esp), %esi -; X86: movl _Lalloc_func$frame_escape_0(%esi), %eax +; X86: movl Lalloc_func$frame_escape_0(%esi), %eax ; X86: movl %eax, 4(%esp) ; X86: movl $_str, (%esp) ; X86: calll _printf -; X86: movl _Lalloc_func$frame_escape_1(%esi), %eax +; X86: movl Lalloc_func$frame_escape_1(%esi), %eax ; X86: movl %eax, 4(%esp) ; X86: movl $_str, (%esp) ; X86: calll _printf -; X86: movl $42, _Lalloc_func$frame_escape_1(%esi) +; X86: movl $42, Lalloc_func$frame_escape_1(%esi) ; X86: addl $8, %esp ; X86: popl %esi ; X86: retl