Index: include/llvm/CodeGen/ISDOpcodes.h =================================================================== --- include/llvm/CodeGen/ISDOpcodes.h +++ include/llvm/CodeGen/ISDOpcodes.h @@ -60,7 +60,7 @@ BasicBlock, VALUETYPE, CONDCODE, Register, RegisterMask, Constant, ConstantFP, GlobalAddress, GlobalTLSAddress, FrameIndex, - JumpTable, ConstantPool, ExternalSymbol, BlockAddress, + JumpTable, ConstantPool, ExternalSymbol, BlockAddress, Symbol, /// The address of the GOT GLOBAL_OFFSET_TABLE, @@ -123,6 +123,7 @@ TargetConstantPool, TargetExternalSymbol, TargetBlockAddress, + TargetSymbol, /// TargetIndex - Like a constant pool entry, but with completely /// target-dependent semantics. Holds target flags, a 32-bit index, and a Index: include/llvm/CodeGen/MachineInstrBuilder.h =================================================================== --- include/llvm/CodeGen/MachineInstrBuilder.h +++ include/llvm/CodeGen/MachineInstrBuilder.h @@ -185,8 +185,8 @@ return *this; } - const MachineInstrBuilder &addSym(MCSymbol *Sym) const { - MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym)); + const MachineInstrBuilder &addSym(MCSymbol *Sym, unsigned char TF = 0) const { + MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym, TF)); return *this; } Index: include/llvm/CodeGen/MachineOperand.h =================================================================== --- include/llvm/CodeGen/MachineOperand.h +++ include/llvm/CodeGen/MachineOperand.h @@ -454,7 +454,8 @@ /// returns 0 for ExternalSymbol operands. int64_t getOffset() const { assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() || - isBlockAddress()) && "Wrong MachineOperand accessor"); + isMCSymbol() || isBlockAddress()) && + "Wrong MachineOperand accessor"); return int64_t(uint64_t(Contents.OffsetedInfo.OffsetHi) << 32) | SmallContents.OffsetLo; } @@ -513,7 +514,8 @@ void setOffset(int64_t Offset) { assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() || - isBlockAddress()) && "Wrong MachineOperand accessor"); + isMCSymbol() || isBlockAddress()) && + "Wrong MachineOperand accessor"); SmallContents.OffsetLo = unsigned(Offset); Contents.OffsetedInfo.OffsetHi = int(Offset >> 32); } @@ -703,9 +705,12 @@ return Op; } - static MachineOperand CreateMCSymbol(MCSymbol *Sym) { + static MachineOperand CreateMCSymbol(MCSymbol *Sym, + unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_MCSymbol); Op.Contents.Sym = Sym; + Op.setOffset(0); + Op.setTargetFlags(TargetFlags); return Op; } Index: include/llvm/CodeGen/SelectionDAG.h =================================================================== --- include/llvm/CodeGen/SelectionDAG.h +++ include/llvm/CodeGen/SelectionDAG.h @@ -491,6 +491,9 @@ SDValue getExternalSymbol(const char *Sym, SDLoc dl, EVT VT); SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags = 0); + SDValue getMCSymbol(MCSymbol *Sym, EVT VT); + SDValue getTargetMCSymbol(MCSymbol *Sym, EVT VT, + unsigned char TargetFlags = 0); SDValue getValueType(EVT); SDValue getRegister(unsigned Reg, EVT VT); SDValue getRegisterMask(const uint32_t *RegMask); Index: include/llvm/CodeGen/SelectionDAGNodes.h =================================================================== --- include/llvm/CodeGen/SelectionDAGNodes.h +++ include/llvm/CodeGen/SelectionDAGNodes.h @@ -1806,6 +1806,26 @@ } }; +/// Represents any symbol or label from the MCContext. +class SymbolSDNode : public SDNode { + MCSymbol *Symbol; + unsigned char TargetFlags; + + friend class SelectionDAG; + SymbolSDNode(bool IsTarget, MCSymbol *Sym, unsigned char TF, EVT VT) + : SDNode(IsTarget ? ISD::TargetSymbol : ISD::Symbol, 0, DebugLoc(), + getSDVTList(VT)), + Symbol(Sym), TargetFlags(TF) {} + +public: + MCSymbol *getSymbol() const { return Symbol; } + unsigned char getTargetFlags() const { return TargetFlags; } + + static bool classof(const SDNode *N) { + return N->getOpcode() == ISD::Symbol || N->getOpcode() == ISD::TargetSymbol; + } +}; + class CondCodeSDNode : public SDNode { ISD::CondCode Condition; friend class SelectionDAG; Index: include/llvm/Target/TargetSelectionDAG.td =================================================================== --- include/llvm/Target/TargetSelectionDAG.td +++ include/llvm/Target/TargetSelectionDAG.td @@ -341,6 +341,10 @@ "ExternalSymbolSDNode">; def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [], "ExternalSymbolSDNode">; +def symbol : SDNode<"ISD::Symbol", SDTPtrLeaf, [], + "SymbolSDNode">; +def tsymbol : SDNode<"ISD::TargetSymbol", SDTPtrLeaf, [], + "SymbolSDNode">; def blockaddress : SDNode<"ISD::BlockAddress", SDTPtrLeaf, [], "BlockAddressSDNode">; def tblockaddress: SDNode<"ISD::TargetBlockAddress", SDTPtrLeaf, [], Index: lib/CodeGen/SelectionDAG/InstrEmitter.cpp =================================================================== --- lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -422,6 +422,8 @@ MIB.addConstantPoolIndex(Idx, Offset, CP->getTargetFlags()); } else if (ExternalSymbolSDNode *ES = dyn_cast(Op)) { MIB.addExternalSymbol(ES->getSymbol(), ES->getTargetFlags()); + } else if (SymbolSDNode *SN = dyn_cast(Op)) { + MIB.addSym(SN->getSymbol(), SN->getTargetFlags()); } else if (BlockAddressSDNode *BA = dyn_cast(Op)) { MIB.addBlockAddress(BA->getBlockAddress(), BA->getOffset(), Index: lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h =================================================================== --- lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h +++ lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h @@ -64,6 +64,7 @@ if (isa(Node)) return true; if (isa(Node)) return true; if (isa(Node)) return true; + if (isa(Node)) return true; if (isa(Node)) return true; if (Node->getOpcode() == ISD::EntryToken || isa(Node)) return true; Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1449,6 +1449,36 @@ return SDValue(N, 0); } +SDValue SelectionDAG::getMCSymbol(MCSymbol *Sym, EVT VT) { + FoldingSetNodeID ID; + AddNodeIDNode(ID, ISD::Symbol, getVTList(VT), None); + ID.AddPointer(Sym); + void *IP = nullptr; + if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) + return SDValue(E, 0); + + SDNode *N = new (NodeAllocator) SymbolSDNode(false, Sym, 0, VT); + CSEMap.InsertNode(N, IP); + InsertNode(N); + return SDValue(N, 0); +} + +SDValue SelectionDAG::getTargetMCSymbol(MCSymbol *Sym, EVT VT, + unsigned char TargetFlags) { + FoldingSetNodeID ID; + AddNodeIDNode(ID, ISD::TargetSymbol, getVTList(VT), None); + ID.AddPointer(Sym); + ID.AddInteger(TargetFlags); + void *IP = nullptr; + if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) + return SDValue(E, 0); + + SDNode *N = new (NodeAllocator) SymbolSDNode(true, Sym, TargetFlags, VT); + CSEMap.InsertNode(N, IP); + InsertNode(N); + return SDValue(N, 0); +} + SDValue SelectionDAG::getCondCode(ISD::CondCode Cond) { if ((unsigned)Cond >= CondCodeNodes.size()) CondCodeNodes.resize(Cond+1); Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4903,12 +4903,7 @@ MCSymbol *FrameAllocSym = MF.getMMI().getContext().getOrCreateFrameAllocSymbol( GlobalValue::getRealLinkageName(Fn->getName()), IdxVal); - - // Create a TargetExternalSymbol for the label to avoid any target lowering - // that would make this PC relative. - StringRef Name = FrameAllocSym->getName(); - assert(Name.data()[Name.size()] == '\0' && "not null terminated"); - SDValue OffsetSym = DAG.getTargetExternalSymbol(Name.data(), PtrVT); + SDValue OffsetSym = DAG.getTargetMCSymbol(FrameAllocSym, PtrVT); SDValue OffsetVal = DAG.getNode(ISD::FRAME_ALLOC_RECOVER, sdl, PtrVT, OffsetSym); Index: lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/DebugInfo.h" #include "llvm/IR/Function.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Debug.h" #include "llvm/Support/GraphWriter.h" #include "llvm/Support/raw_ostream.h" @@ -105,6 +106,7 @@ case ISD::ConstantPool: return "ConstantPool"; case ISD::TargetIndex: return "TargetIndex"; case ISD::ExternalSymbol: return "ExternalSymbol"; + case ISD::Symbol: return "Symbol"; case ISD::BlockAddress: return "BlockAddress"; case ISD::INTRINSIC_WO_CHAIN: case ISD::INTRINSIC_VOID: @@ -130,6 +132,7 @@ case ISD::TargetJumpTable: return "TargetJumpTable"; case ISD::TargetConstantPool: return "TargetConstantPool"; case ISD::TargetExternalSymbol: return "TargetExternalSymbol"; + case ISD::TargetSymbol: return "TargetSymbol"; case ISD::TargetBlockAddress: return "TargetBlockAddress"; case ISD::CopyToReg: return "CopyToReg"; @@ -451,6 +454,10 @@ OS << "'" << ES->getSymbol() << "'"; if (unsigned int TF = ES->getTargetFlags()) OS << " [TF=" << TF << ']'; + } else if (const auto *S = dyn_cast(this)) { + OS << " '" << S->getSymbol()->getName() << "'"; + if (unsigned int TF = S->getTargetFlags()) + OS << " [TF=" << TF << ']'; } else if (const SrcValueSDNode *M = dyn_cast(this)) { if (M->getValue()) OS << "<" << M->getValue() << ">"; Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2553,6 +2553,7 @@ case ISD::TargetConstantPool: case ISD::TargetFrameIndex: case ISD::TargetExternalSymbol: + case ISD::TargetSymbol: case ISD::TargetBlockAddress: case ISD::TargetJumpTable: case ISD::TargetGlobalTLSAddress: Index: lib/Target/X86/X86ISelDAGToDAG.cpp =================================================================== --- lib/Target/X86/X86ISelDAGToDAG.cpp +++ lib/Target/X86/X86ISelDAGToDAG.cpp @@ -28,6 +28,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Type.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" @@ -67,19 +68,19 @@ const Constant *CP; const BlockAddress *BlockAddr; const char *ES; + MCSymbol *Sym; int JT; unsigned Align; // CP alignment. unsigned char SymbolFlags; // X86II::MO_* X86ISelAddressMode() - : BaseType(RegBase), Base_FrameIndex(0), Scale(1), IndexReg(), Disp(0), - Segment(), GV(nullptr), CP(nullptr), BlockAddr(nullptr), ES(nullptr), - JT(-1), Align(0), SymbolFlags(X86II::MO_NO_FLAG) { - } + : BaseType(RegBase), Base_FrameIndex(0), Scale(1), IndexReg(), Disp(0), + Segment(), GV(nullptr), CP(nullptr), BlockAddr(nullptr), ES(nullptr), + Sym(nullptr), JT(-1), Align(0), SymbolFlags(X86II::MO_NO_FLAG) {} bool hasSymbolicDisplacement() const { return GV != nullptr || CP != nullptr || ES != nullptr || - JT != -1 || BlockAddr != nullptr; + Sym != nullptr || JT != -1 || BlockAddr != nullptr; } bool hasBaseOrIndexReg() const { @@ -134,6 +135,11 @@ dbgs() << ES; else dbgs() << "nul"; + dbgs() << " Sym "; + if (Sym) + Sym->dump(); + else + dbgs() << "nul"; dbgs() << " JT" << JT << " Align" << Align << '\n'; } #endif @@ -258,6 +264,9 @@ else if (AM.ES) { assert(!AM.Disp && "Non-zero displacement is ignored with ES."); Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags); + } else if (AM.Sym) { + assert(!AM.Disp && "Non-zero displacement is ignored with MCSymbol."); + Disp = CurDAG->getTargetMCSymbol(AM.Sym, MVT::i32, AM.SymbolFlags); } else if (AM.JT != -1) { assert(!AM.Disp && "Non-zero displacement is ignored with JT."); Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags); @@ -604,7 +613,7 @@ bool X86DAGToDAGISel::FoldOffsetIntoAddress(uint64_t Offset, X86ISelAddressMode &AM) { // Cannot combine ExternalSymbol displacements with integer offsets. - if (Offset != 0 && AM.ES) + if (Offset != 0 && (AM.ES || AM.Sym || AM.JT != -1)) return true; int64_t Val = AM.Disp + Offset; CodeModel::Model M = TM.getCodeModel(); @@ -654,10 +663,10 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) { // If the addressing mode already has a symbol as the displacement, we can // never match another symbol. + SDValue N0 = N.getOperand(0); if (AM.hasSymbolicDisplacement()) return true; - SDValue N0 = N.getOperand(0); CodeModel::Model M = TM.getCodeModel(); // Handle X86-64 rip-relative addresses. We check this before checking direct @@ -690,6 +699,9 @@ } else if (ExternalSymbolSDNode *S = dyn_cast(N0)) { AM.ES = S->getSymbol(); AM.SymbolFlags = S->getTargetFlags(); + } else if (SymbolSDNode *S = dyn_cast(N0)) { + AM.Sym = S->getSymbol(); + AM.SymbolFlags = S->getTargetFlags(); } else if (JumpTableSDNode *J = dyn_cast(N0)) { AM.JT = J->getIndex(); AM.SymbolFlags = J->getTargetFlags(); @@ -728,6 +740,9 @@ } else if (ExternalSymbolSDNode *S = dyn_cast(N0)) { AM.ES = S->getSymbol(); AM.SymbolFlags = S->getTargetFlags(); + } else if (SymbolSDNode *S = dyn_cast(N0)) { + AM.Sym = S->getSymbol(); + AM.SymbolFlags = S->getTargetFlags(); } else if (JumpTableSDNode *J = dyn_cast(N0)) { AM.JT = J->getIndex(); AM.SymbolFlags = J->getTargetFlags(); @@ -989,6 +1004,7 @@ DEBUG({ dbgs() << "MatchAddress: "; AM.dump(); + N.dump(); }); // Limit recursion. if (Depth > 5) @@ -998,10 +1014,10 @@ // into it. Instead of handling this in every case, we handle it here. // RIP relative addressing: %rip + 32-bit displacement! if (AM.isRIPRelative()) { - // FIXME: JumpTable and ExternalSymbol address currently don't like - // displacements. It isn't very important, but this should be fixed for - // consistency. - if (!AM.ES && AM.JT != -1) return true; + // FIXME: JumpTable, ExternalSymbol address, and Symbol currently don't like + // displacements. This should be fixed eventually for consistency. + if (!AM.ES && !AM.Sym && AM.JT != -1) + return true; if (ConstantSDNode *Cst = dyn_cast(N)) if (!FoldOffsetIntoAddress(Cst->getSExtValue(), AM)) @@ -1013,13 +1029,11 @@ default: break; case ISD::FRAME_ALLOC_RECOVER: { if (!AM.hasSymbolicDisplacement() && AM.Disp == 0) - 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; - } + if (const auto *SymNode = dyn_cast(N.getOperand(0))) { + AM.Sym = SymNode->getSymbol(); + AM.SymbolFlags = SymNode->getTargetFlags(); + return false; + } break; } case ISD::Constant: { @@ -1473,6 +1487,7 @@ N->getOpcode() != ISD::TargetJumpTable && N->getOpcode() != ISD::TargetGlobalAddress && N->getOpcode() != ISD::TargetExternalSymbol && + N->getOpcode() != ISD::TargetSymbol && N->getOpcode() != ISD::TargetBlockAddress) return false; Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -438,12 +438,14 @@ if (Subtarget->is64Bit()) setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom); setOperationAction(ISD::ExternalSymbol , MVT::i32 , Custom); + setOperationAction(ISD::Symbol , MVT::i32 , Custom); setOperationAction(ISD::BlockAddress , MVT::i32 , Custom); if (Subtarget->is64Bit()) { setOperationAction(ISD::ConstantPool , MVT::i64 , Custom); setOperationAction(ISD::JumpTable , MVT::i64 , Custom); setOperationAction(ISD::GlobalAddress , MVT::i64 , Custom); setOperationAction(ISD::ExternalSymbol, MVT::i64 , Custom); + setOperationAction(ISD::Symbol , MVT::i64 , Custom); setOperationAction(ISD::BlockAddress , MVT::i64 , Custom); } // 64-bit addm sub, shl, sra, srl (iff 32-bit x86) @@ -2907,6 +2909,8 @@ if (G && !G->getGlobal()->hasHiddenVisibility() && !G->getGlobal()->hasProtectedVisibility()) Callee = LowerGlobalAddress(Callee, DAG); + else if (isa(Callee)) + Callee = LowerExternalSymbol(Callee, DAG); else if (isa(Callee)) Callee = LowerExternalSymbol(Callee, DAG); } @@ -10982,8 +10986,6 @@ SDValue X86TargetLowering::LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const { - const char *Sym = cast(Op)->getSymbol(); - // In PIC mode (unless we're in RIPRel PIC mode) we add an offset to the // global base reg. unsigned char OpFlag = 0; @@ -11003,7 +11005,15 @@ OpFlag = X86II::MO_DARWIN_NONLAZY; } - SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy(), OpFlag); + SDValue Result; + if (auto *ESNode = dyn_cast(Op)) { + Result = DAG.getTargetExternalSymbol(ESNode->getSymbol(), getPointerTy(), + OpFlag); + } else { + auto *SymNode = cast(Op); + Result = + DAG.getTargetMCSymbol(SymNode->getSymbol(), getPointerTy(), OpFlag); + } SDLoc DL(Op); Result = DAG.getNode(WrapperKind, DL, getPointerTy(), Result); @@ -17495,6 +17505,7 @@ case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); + case ISD::Symbol: return LowerExternalSymbol(Op, DAG); case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); case ISD::SHL_PARTS: case ISD::SRA_PARTS: Index: lib/Target/X86/X86InstrCompiler.td =================================================================== --- lib/Target/X86/X86InstrCompiler.td +++ lib/Target/X86/X86InstrCompiler.td @@ -865,6 +865,7 @@ def : Pat<(i32 (X86Wrapper tglobaltlsaddr:$dst)),(MOV32ri tglobaltlsaddr:$dst)>; def : Pat<(i32 (X86Wrapper tglobaladdr :$dst)), (MOV32ri tglobaladdr :$dst)>; def : Pat<(i32 (X86Wrapper texternalsym:$dst)), (MOV32ri texternalsym:$dst)>; +def : Pat<(i32 (X86Wrapper tsymbol:$dst)), (MOV32ri tsymbol:$dst)>; def : Pat<(i32 (X86Wrapper tblockaddress:$dst)), (MOV32ri tblockaddress:$dst)>; def : Pat<(add GR32:$src1, (X86Wrapper tconstpool:$src2)), @@ -875,6 +876,8 @@ (ADD32ri GR32:$src1, tglobaladdr:$src2)>; def : Pat<(add GR32:$src1, (X86Wrapper texternalsym:$src2)), (ADD32ri GR32:$src1, texternalsym:$src2)>; +def : Pat<(add GR32:$src1, (X86Wrapper tsymbol:$src2)), + (ADD32ri GR32:$src1, tsymbol:$src2)>; def : Pat<(add GR32:$src1, (X86Wrapper tblockaddress:$src2)), (ADD32ri GR32:$src1, tblockaddress:$src2)>; @@ -882,6 +885,8 @@ (MOV32mi addr:$dst, tglobaladdr:$src)>; def : Pat<(store (i32 (X86Wrapper texternalsym:$src)), addr:$dst), (MOV32mi addr:$dst, texternalsym:$src)>; +def : Pat<(store (i32 (X86Wrapper tsymbol:$src)), addr:$dst), + (MOV32mi addr:$dst, tsymbol:$src)>; def : Pat<(store (i32 (X86Wrapper tblockaddress:$src)), addr:$dst), (MOV32mi addr:$dst, tblockaddress:$src)>; @@ -896,6 +901,8 @@ (MOV64ri tglobaladdr :$dst)>, Requires<[FarData]>; def : Pat<(i64 (X86Wrapper texternalsym:$dst)), (MOV64ri texternalsym:$dst)>, Requires<[FarData]>; +def : Pat<(i64 (X86Wrapper tsymbol:$dst)), + (MOV64ri tsymbol:$dst)>, Requires<[FarData]>; def : Pat<(i64 (X86Wrapper tblockaddress:$dst)), (MOV64ri tblockaddress:$dst)>, Requires<[FarData]>; @@ -910,6 +917,8 @@ (MOV64ri32 tglobaladdr :$dst)>, Requires<[KernelCode]>; def : Pat<(i64 (X86Wrapper texternalsym:$dst)), (MOV64ri32 texternalsym:$dst)>, Requires<[KernelCode]>; +def : Pat<(i64 (X86Wrapper tsymbol:$dst)), + (MOV64ri32 tsymbol:$dst)>, Requires<[KernelCode]>; def : Pat<(i64 (X86Wrapper tblockaddress:$dst)), (MOV64ri32 tblockaddress:$dst)>, Requires<[KernelCode]>; @@ -928,12 +937,15 @@ def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst), (MOV64mi32 addr:$dst, texternalsym:$src)>, Requires<[NearData, IsStatic]>; +def : Pat<(store (i64 (X86Wrapper tsymbol:$src)), addr:$dst), + (MOV64mi32 addr:$dst, tsymbol:$src)>, + Requires<[NearData, IsStatic]>; def : Pat<(store (i64 (X86Wrapper tblockaddress:$src)), addr:$dst), (MOV64mi32 addr:$dst, tblockaddress:$src)>, Requires<[NearData, IsStatic]>; -def : Pat<(i32 (X86RecoverFrameAlloc texternalsym:$dst)), (MOV32ri texternalsym:$dst)>; -def : Pat<(i64 (X86RecoverFrameAlloc texternalsym:$dst)), (MOV64ri texternalsym:$dst)>; +def : Pat<(i32 (X86RecoverFrameAlloc tsymbol:$dst)), (MOV32ri tsymbol:$dst)>; +def : Pat<(i64 (X86RecoverFrameAlloc tsymbol:$dst)), (MOV64ri tsymbol:$dst)>; // Calls @@ -952,6 +964,8 @@ (CALL64pcrel32 tglobaladdr:$dst)>; def : Pat<(X86call (i64 texternalsym:$dst)), (CALL64pcrel32 texternalsym:$dst)>; +def : Pat<(X86call (i64 tsymbol:$dst)), + (CALL64pcrel32 tsymbol:$dst)>; // Tailcall stuff. The TCRETURN instructions execute after the epilog, so they // can never use callee-saved registers. That is the purpose of the GR64_TC @@ -1013,6 +1027,8 @@ (CALLpcrel32 tglobaladdr:$dst)>; def : Pat<(X86call (i32 texternalsym:$dst)), (CALLpcrel32 texternalsym:$dst)>; +def : Pat<(X86call (i32 tsymbol:$dst)), + (CALLpcrel32 tsymbol:$dst)>; def : Pat<(X86call (i32 imm:$dst)), (CALLpcrel32 imm:$dst)>, Requires<[CallImmAddr]>; Index: lib/Target/X86/X86MCInstLower.cpp =================================================================== --- lib/Target/X86/X86MCInstLower.cpp +++ lib/Target/X86/X86MCInstLower.cpp @@ -422,6 +422,9 @@ case MachineOperand::MO_ExternalSymbol: MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO)); break; + case MachineOperand::MO_MCSymbol: + MCOp = LowerSymbolOperand(MO, MO.getMCSymbol()); + break; case MachineOperand::MO_JumpTableIndex: MCOp = LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex())); break; Index: test/CodeGen/X86/frameescape.ll =================================================================== --- test/CodeGen/X86/frameescape.ll +++ test/CodeGen/X86/frameescape.ll @@ -1,5 +1,5 @@ -; RUN: llc -mtriple=i686-windows-msvc < %s | FileCheck %s --check-prefix=X86 ; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s --check-prefix=X64 +; RUN: llc -mtriple=i686-windows-msvc < %s | FileCheck %s --check-prefix=X86 declare void @llvm.frameescape(...) declare i8* @llvm.frameaddress(i32) Index: utils/TableGen/CodeGenDAGPatterns.cpp =================================================================== --- utils/TableGen/CodeGenDAGPatterns.cpp +++ utils/TableGen/CodeGenDAGPatterns.cpp @@ -2143,6 +2143,7 @@ Operator->getName() != "texternalsym" && Operator->getName() != "tblockaddress" && Operator->getName() != "tglobaladdr" && + Operator->getName() != "tsymbol" && Operator->getName() != "bb" && Operator->getName() != "vt") error("Cannot use '" + Operator->getName() + "' in an output pattern!");