diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 09f07d01caa..19df6e9671d 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -590,63 +590,19 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM, break; } - case ISD::TargetConstantPool: - if (AM.BaseType == X86ISelAddressMode::RegBase && - AM.Base.Reg.Val == 0 && - AM.CP == 0) { - ConstantPoolSDNode *CP = cast(N); - AM.CP = CP->getConstVal(); - AM.Align = CP->getAlignment(); - AM.Disp += CP->getOffset(); - return false; - } - break; - - case ISD::TargetGlobalAddress: - if (AM.BaseType == X86ISelAddressMode::RegBase && - AM.Base.Reg.Val == 0 && - AM.GV == 0) { - GlobalAddressSDNode *G = cast(N); - AM.GV = G->getGlobal(); - AM.Disp += G->getOffset(); - return false; - } - break; - - case ISD::TargetExternalSymbol: - if (isRoot && - AM.BaseType == X86ISelAddressMode::RegBase && - AM.Base.Reg.Val == 0) { - ExternalSymbolSDNode *S = cast(N.getOperand(0)); - AM.ES = S->getSymbol(); - return false; - } - break; - - case ISD::TargetJumpTable: - if (isRoot && - AM.BaseType == X86ISelAddressMode::RegBase && - AM.Base.Reg.Val == 0) { - JumpTableSDNode *J = cast(N.getOperand(0)); - AM.JT = J->getIndex(); - return false; - } - break; - case X86ISD::Wrapper: + case X86ISD::WrapperRIP: { + bool isRIP = N.getOpcode() == X86ISD::WrapperRIP; + // Under X86-64 non-small code model, GV (and friends) are 64-bits. + if (!isRIP && Subtarget->is64Bit() && TM.getCodeModel() != CodeModel::Small) + break; + // If value is available in a register both base and index components have // been picked, we can't fit the result available in the register in the // addressing mode. Duplicate GlobalAddress or ConstantPool as displacement. - - // Can't fit GV or CP in addressing mode for X86-64 medium or large code - // model since the displacement field is 32-bit. Ok for small code model. - - // For X86-64 PIC code, only allow GV / CP + displacement so we can use RIP - // relative addressing mode. - if (Subtarget->is64Bit() && TM.getCodeModel() != CodeModel::Small) - break; if (!Available || (AM.Base.Reg.Val && AM.IndexReg.Val)) { - bool isRIP = Subtarget->is64Bit(); + // For X86-64 PIC code, only allow GV / CP + displacement so we can use + // RIP relative addressing mode. if (isRIP && (AM.Base.Reg.Val || AM.Scale > 1 || AM.IndexReg.Val || AM.BaseType == X86ISelAddressMode::FrameIndexBase)) @@ -683,6 +639,7 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM, } } break; + } case ISD::FrameIndex: if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { @@ -1040,7 +997,8 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) { SDOperand N0 = N.getOperand(0); SDOperand N1 = N.getOperand(1); if (N.Val->getValueType(0) == PtrVT && - N0.getOpcode() == X86ISD::Wrapper && + (N0.getOpcode() == X86ISD::Wrapper + || N0.getOpcode() == X86ISD::WrapperRIP) && N1.getOpcode() == ISD::Constant) { unsigned Offset = (unsigned)cast(N1)->getValue(); SDOperand C(0, 0); diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 1e3530f21f6..375777a3290 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -3832,8 +3832,15 @@ X86TargetLowering::LowerConstantPool(SDOperand Op, SelectionDAG &DAG) { SDOperand Result = DAG.getTargetConstantPool(CP->getConstVal(), getPointerTy(), CP->getAlignment()); + // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode. + TargetMachine &tm = getTargetMachine(); + unsigned WrapperOpcode = (Subtarget->is64Bit() && + (tm.getCodeModel() == CodeModel::Small || + tm.getCodeModel() == CodeModel::Medium) && + tm.getRelocationModel() == Reloc::PIC_) + ? X86ISD::WrapperRIP : X86ISD::Wrapper; + Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result); if (Subtarget->isTargetDarwin()) { - Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result); // With PIC, the address is actually $g + Offset. if (!Subtarget->is64Bit() && getTargetMachine().getRelocationModel() == Reloc::PIC_) @@ -3848,8 +3855,15 @@ SDOperand X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) { GlobalValue *GV = cast(Op)->getGlobal(); SDOperand Result = DAG.getTargetGlobalAddress(GV, getPointerTy()); + // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode. + TargetMachine &tm = getTargetMachine(); + unsigned WrapperOpcode = (Subtarget->is64Bit() && + (tm.getCodeModel() == CodeModel::Small || + tm.getCodeModel() == CodeModel::Medium) && + tm.getRelocationModel() == Reloc::PIC_) + ? X86ISD::WrapperRIP : X86ISD::Wrapper; + Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result); if (Subtarget->isTargetDarwin()) { - Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result); // With PIC, the address is actually $g + Offset. if (!Subtarget->is64Bit() && getTargetMachine().getRelocationModel() == Reloc::PIC_) @@ -3865,7 +3879,6 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) { Subtarget->GVRequiresExtraLoad(GV, false)) Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0); } else if (Subtarget->GVRequiresExtraLoad(GV, false)) { - Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result); Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0); } @@ -3876,8 +3889,15 @@ SDOperand X86TargetLowering::LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG) { const char *Sym = cast(Op)->getSymbol(); SDOperand Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); + // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode. + TargetMachine &tm = getTargetMachine(); + unsigned WrapperOpcode = (Subtarget->is64Bit() && + (tm.getCodeModel() == CodeModel::Small || + tm.getCodeModel() == CodeModel::Medium) && + tm.getRelocationModel() == Reloc::PIC_) + ? X86ISD::WrapperRIP : X86ISD::Wrapper; + Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result); if (Subtarget->isTargetDarwin()) { - Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result); // With PIC, the address is actually $g + Offset. if (!Subtarget->is64Bit() && getTargetMachine().getRelocationModel() == Reloc::PIC_) @@ -4244,8 +4264,15 @@ SDOperand X86TargetLowering::LowerBRCOND(SDOperand Op, SelectionDAG &DAG) { SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) { JumpTableSDNode *JT = cast(Op); SDOperand Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy()); + // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode. + TargetMachine &tm = getTargetMachine(); + unsigned WrapperOpcode = (Subtarget->is64Bit() && + (tm.getCodeModel() == CodeModel::Small || + tm.getCodeModel() == CodeModel::Medium) && + tm.getRelocationModel() == Reloc::PIC_) + ? X86ISD::WrapperRIP : X86ISD::Wrapper; + Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result); if (Subtarget->isTargetDarwin()) { - Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result); // With PIC, the address is actually $g + Offset. if (!Subtarget->is64Bit() && getTargetMachine().getRelocationModel() == Reloc::PIC_) @@ -4978,6 +5005,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { case X86ISD::LOAD_UA: return "X86ISD::LOAD_UA"; case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg"; case X86ISD::Wrapper: return "X86ISD::Wrapper"; + case X86ISD::WrapperRIP: return "X86ISD::WrapperRIP"; case X86ISD::S2VEC: return "X86ISD::S2VEC"; case X86ISD::PEXTRW: return "X86ISD::PEXTRW"; case X86ISD::PINSRW: return "X86ISD::PINSRW"; @@ -5220,12 +5248,13 @@ static SDOperand getShuffleScalarElt(SDNode *N, unsigned i, SelectionDAG &DAG) { /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the /// node is a GlobalAddress + an offset. static bool isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) { - if (N->getOpcode() == X86ISD::Wrapper) { + unsigned Opc = N->getOpcode(); + if (Opc == X86ISD::Wrapper || Opc == X86ISD::WrapperRIP) { if (dyn_cast(N->getOperand(0))) { GA = cast(N->getOperand(0))->getGlobal(); return true; } - } else if (N->getOpcode() == ISD::ADD) { + } else if (Opc == ISD::ADD) { SDOperand N1 = N->getOperand(0); SDOperand N2 = N->getOperand(1); if (isGAPlusOffset(N1.Val, GA, Offset)) { diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index f28b95127d2..26c8f336acf 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -150,6 +150,10 @@ namespace llvm { /// TargetExternalSymbol, and TargetGlobalAddress. Wrapper, + /// WrapperRIP - Special wrapper used under X86-64 PIC mode for RIP + /// relative displacements. + WrapperRIP, + /// S2VEC - X86 version of SCALAR_TO_VECTOR. The destination base does not /// have to match the operand type. S2VEC, diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index f50553c077a..cb07abe3655 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -84,7 +84,8 @@ def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr, def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc, [SDNPHasChain, SDNPOutFlag]>; -def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>; +def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>; +def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>; //===----------------------------------------------------------------------===// // X86 Operand Definitions. @@ -169,6 +170,8 @@ def HasSSE3 : Predicate<"Subtarget->hasSSE3()">; def FPStack : Predicate<"!Subtarget->hasSSE2()">; def In32BitMode : Predicate<"!Subtarget->is64Bit()">; def In64BitMode : Predicate<"Subtarget->is64Bit()">; +def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">; +def NotSmallCode :Predicate<"TM.getCodeModel() != CodeModel::Small">; //===----------------------------------------------------------------------===// // X86 specific pattern fragments. diff --git a/lib/Target/X86/X86InstrX86-64.td b/lib/Target/X86/X86InstrX86-64.td index 0e024d1931e..0c49e94c0b9 100644 --- a/lib/Target/X86/X86InstrX86-64.td +++ b/lib/Target/X86/X86InstrX86-64.td @@ -36,7 +36,8 @@ def lea64_32mem : Operand { // Complex Pattern Definitions... // def lea64addr : ComplexPattern; + [add, mul, shl, or, frameindex, X86WrapperRIP], + []>; //===----------------------------------------------------------------------===// // Instruction templates... @@ -1020,6 +1021,30 @@ def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (ops GR64:$dst, i64i32imm:$src), // Non-Instruction Patterns //===----------------------------------------------------------------------===// +// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable +def : Pat<(i64 (X86Wrapper tconstpool :$dst)), + (MOV64ri32 tconstpool :$dst)>, Requires<[SmallCode]>; +def : Pat<(i64 (X86Wrapper tjumptable :$dst)), + (MOV64ri32 tjumptable :$dst)>, Requires<[SmallCode]>; +def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)), + (MOV64ri32 tglobaladdr :$dst)>, Requires<[SmallCode]>; +def : Pat<(i64 (X86Wrapper texternalsym:$dst)), + (MOV64ri32 texternalsym:$dst)>, Requires<[SmallCode]>; + +def : Pat<(i64 (X86Wrapper tconstpool :$dst)), + (MOV64ri tconstpool :$dst)>, Requires<[NotSmallCode]>; +def : Pat<(i64 (X86Wrapper tjumptable :$dst)), + (MOV64ri tjumptable :$dst)>, Requires<[NotSmallCode]>; +def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)), + (MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>; +def : Pat<(i64 (X86Wrapper texternalsym:$dst)), + (MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>; + +def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst), + (MOV64mi32 addr:$dst, tglobaladdr:$src)>, Requires<[SmallCode]>; +def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst), + (MOV64mi32 addr:$dst, texternalsym:$src)>, Requires<[SmallCode]>; + // Calls // Direct PC relative function call for small code model. 32-bit displacement // sign extended to 64-bit.