diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index 0382964fe94..1d97fbfbb3c 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -119,13 +119,9 @@ SelectAddr(SDValue Addr, SDValue &Offset, SDValue &Base) { // on PIC code Load GA if (TM.getRelocationModel() == Reloc::PIC_) { - if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || - (Addr.getOpcode() == ISD::TargetConstantPool) || - (Addr.getOpcode() == ISD::TargetJumpTable) || - (Addr.getOpcode() == ISD::TargetBlockAddress) || - (Addr.getOpcode() == ISD::TargetExternalSymbol)) { + if (Addr.getOpcode() == MipsISD::WrapperPIC) { Base = CurDAG->getRegister(Mips::GP, MVT::i32); - Offset = Addr; + Offset = Addr.getOperand(0); return true; } } else { diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 7aaf13ca59f..e5dfb253f55 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -55,6 +55,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::DivRemU: return "MipsISD::DivRemU"; case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64"; case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64"; + case MipsISD::WrapperPIC: return "MipsISD::WrapperPIC"; default: return NULL; } } @@ -770,6 +771,7 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, } else { SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, MipsII::MO_GOT); + GA = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, GA); SDValue ResNode = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), GA, MachinePointerInfo(), false, false, 0); @@ -807,6 +809,7 @@ SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op, SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true, MipsII::MO_GOT); + BAGOTOffset = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, BAGOTOffset); SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true, MipsII::MO_ABS_LO); SDValue Load = DAG.getLoad(MVT::i32, dl, @@ -841,10 +844,12 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG) const if (!IsPIC) { SDValue Ops[] = { JTI }; HiPart = DAG.getNode(MipsISD::Hi, dl, DAG.getVTList(MVT::i32), Ops, 1); - } else // Emit Load from Global Pointer + } else {// Emit Load from Global Pointer + JTI = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, JTI); HiPart = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), JTI, MachinePointerInfo(), false, false, 0); + } SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MipsII::MO_ABS_LO); @@ -884,6 +889,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const } else { SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), N->getOffset(), MipsII::MO_GOT); + CP = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, CP); SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), CP, MachinePointerInfo::getConstantPool(), false, false, 0); @@ -1288,6 +1294,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (IsPIC) { if (LoadSymAddr) { // Load callee address + Callee = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, Callee); SDValue LoadValue = DAG.getLoad(MVT::i32, dl, Chain, Callee, MachinePointerInfo::getGOT(), false, false, 0); diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 381d519479c..805ac955072 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -67,7 +67,9 @@ namespace llvm { DivRemU, BuildPairF64, - ExtractElementF64 + ExtractElementF64, + + WrapperPIC }; } diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 0e20f986c7f..d3fb724e824 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -75,6 +75,9 @@ def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsDivRem, def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsDivRem, [SDNPOutGlue]>; +// wrapper node +def MipsWrapperPIC : SDNode<"MipsISD::WrapperPIC", SDTIntUnaryOp>; + //===----------------------------------------------------------------------===// // Mips Instruction Predicate Definitions. //===----------------------------------------------------------------------===// @@ -589,6 +592,17 @@ def : Pat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)), def : Pat<(add CPURegs:$gp, (MipsGPRel tconstpool:$in)), (ADDiu CPURegs:$gp, tconstpool:$in)>; +// wrapper_pic +class WrapperPICPat: + Pat<(MipsWrapperPIC node:$in), + (ADDiu GP, node:$in)>; + +def : WrapperPICPat; +def : WrapperPICPat; +def : WrapperPICPat; +def : WrapperPICPat; +def : WrapperPICPat; + // Mips does not have "not", so we expand our way def : Pat<(not CPURegs:$in), (NOR CPURegs:$in, ZERO)>; @@ -656,13 +670,6 @@ multiclass MovnPats { defm : MovzPats; defm : MovnPats; -// select patterns with got access -let AddedComplexity = 10 in - def : Pat<(select (setne CPURegs:$lhs, CPURegs:$rhs), - (i32 tglobaladdr:$T), CPURegs:$F), - (MOVN_I CPURegs:$F, (ADDiu GP, tglobaladdr:$T), - (XOR CPURegs:$lhs, CPURegs:$rhs))>; - // setcc patterns def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs), (SLTu (XOR CPURegs:$lhs, CPURegs:$rhs), 1)>; diff --git a/test/CodeGen/Mips/cmov.ll b/test/CodeGen/Mips/cmov.ll index 8329c891f0c..ec3796190cc 100755 --- a/test/CodeGen/Mips/cmov.ll +++ b/test/CodeGen/Mips/cmov.ll @@ -4,8 +4,8 @@ @i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4 @i3 = common global i32* null, align 4 -; CHECK: lw ${{[0-9]+}}, %got(i3)($gp) ; CHECK: addiu ${{[0-9]+}}, $gp, %got(i1) +; CHECK: lw ${{[0-9]+}}, %got(i3)($gp) define i32* @cmov1(i32 %s) nounwind readonly { entry: %tobool = icmp ne i32 %s, 0 @@ -14,3 +14,19 @@ entry: ret i32* %cond } +@c = global i32 1, align 4 +@d = global i32 0, align 4 + +; CHECK: cmov2: +; CHECK: addiu $[[R0:[0-9]+]], $gp, %got(c) +; CHECK: addiu $[[R1:[0-9]+]], $gp, %got(d) +; CHECK: movn $[[R1]], $[[R0]], ${{[0-9]+}} +define i32 @cmov2(i32 %s) nounwind readonly { +entry: + %tobool = icmp ne i32 %s, 0 + %tmp1 = load i32* @c, align 4 + %tmp2 = load i32* @d, align 4 + %cond = select i1 %tobool, i32 %tmp1, i32 %tmp2 + ret i32 %cond +} +