diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 41a597a00fb..d7e6642bd91 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1209,9 +1209,26 @@ static SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) { SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) { DebugLoc DL = Op.getDebugLoc(); + EVT PtrVT = getPointerTy(); BlockAddress *BA = cast(Op)->getBlockAddress(); - SDValue Result = DAG.getBlockAddress(BA, DL, /*isTarget=*/true); - return DAG.getNode(ARMISD::Wrapper, DL, getPointerTy(), Result); + Reloc::Model RelocM = getTargetMachine().getRelocationModel(); + SDValue CPAddr; + if (RelocM == Reloc::Static) { + CPAddr = DAG.getTargetConstantPool(BA, PtrVT, 4); + } else { + unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; + ARMConstantPoolValue *CPV = new ARMConstantPoolValue(BA, ARMPCLabelIndex, + ARMCP::CPBlockAddress, + PCAdj); + CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); + } + CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr); + SDValue Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), CPAddr, + PseudoSourceValue::getConstantPool(), 0); + if (RelocM == Reloc::Static) + return Result; + SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); + return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel); } // Lower ISD::GlobalTLSAddress using the "general dynamic" model diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index e33d9fc32d6..cbe80b4800c 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1607,7 +1607,6 @@ let Defs = // ConstantPool, GlobalAddress, and JumpTable def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>; def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; -def : ARMPat<(ARMWrapper tblockaddress:$dst), (LEApcrel tblockaddress:$dst)>; def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id), (LEApcrelJT tjumptable:$dst, imm:$id)>; diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 724366cce39..2a391992874 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -685,7 +685,6 @@ def : T1Pat<(subc tGPR:$lhs, tGPR:$rhs), // ConstantPool, GlobalAddress def : T1Pat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; def : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; -def : T1Pat<(ARMWrapper tblockaddress:$dst), (tLEApcrel tblockaddress:$dst)>; // JumpTable def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 13fb620e254..26b57599d36 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -1169,7 +1169,6 @@ def : T2Pat<(sub GPR:$LHS, t2_so_imm2part:$RHS), // ConstantPool, GlobalAddress, and JumpTable def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>; def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>; -def : T2Pat<(ARMWrapper tblockaddress:$dst), (t2LEApcrel tblockaddress:$dst)>; def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), (t2LEApcrelJT tjumptable:$dst, imm:$id)>;