Materialize GA addresses with movw + movt pairs for Darwin in PIC mode. e.g.
movw r0, :lower16:(L_foo$non_lazy_ptr-(LPC0_0+4))
movt r0, :upper16:(L_foo$non_lazy_ptr-(LPC0_0+4))
LPC0_0:
add r0, pc, r0
It's not yet enabled by default as some tests are failing. I suspect bugs in
down stream tools.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123619 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index 05d7231..2dde617 100644
--- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -765,13 +765,16 @@
case ARM::MOVi32imm:
case ARM::MOVCCi32imm:
+ case ARM::MOV_pic_ga:
case ARM::t2MOVi32imm:
- case ARM::t2MOVCCi32imm: {
+ case ARM::t2MOVCCi32imm:
+ case ARM::t2MOV_pic_ga: {
unsigned PredReg = 0;
ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
unsigned DstReg = MI.getOperand(0).getReg();
bool DstIsDead = MI.getOperand(0).isDead();
bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
+ bool isPIC_GA = (Opcode == ARM::t2MOV_pic_ga || Opcode == ARM::MOV_pic_ga);
const MachineOperand &MO = MI.getOperand(isCC ? 2 : 1);
MachineInstrBuilder LO16, HI16;
@@ -798,14 +801,24 @@
break;
}
- bool isThumb =
- (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm);
+ unsigned LO16Opc = 0;
+ unsigned HI16Opc = 0;
+ if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) {
+ LO16Opc = ARM::t2MOVi16;
+ HI16Opc = ARM::t2MOVTi16;
+ } else if (Opcode == ARM::MOV_pic_ga) {
+ LO16Opc = ARM::MOVi16_pic_ga;
+ HI16Opc = ARM::MOVTi16_pic_ga;
+ } else if (Opcode == ARM::t2MOV_pic_ga) {
+ LO16Opc = ARM::t2MOVi16_pic_ga;
+ HI16Opc = ARM::t2MOVTi16_pic_ga;
+ } else {
+ LO16Opc = ARM::MOVi16;
+ HI16Opc = ARM::MOVTi16;
+ }
- LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
- TII->get(isThumb ? ARM::t2MOVi16 : ARM::MOVi16),
- DstReg);
- HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
- TII->get(isThumb ? ARM::t2MOVTi16 : ARM::MOVTi16))
+ LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg);
+ HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc))
.addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
.addReg(DstReg);
@@ -815,16 +828,30 @@
unsigned Hi16 = (Imm >> 16) & 0xffff;
LO16 = LO16.addImm(Lo16);
HI16 = HI16.addImm(Hi16);
+ } else if (isPIC_GA) {
+ unsigned LabelId = MI.getOperand(2).getImm();
+ const GlobalValue *GV = MO.getGlobal();
+ unsigned TF = MO.getTargetFlags();
+ LO16 = LO16.addGlobalAddress(GV, MO.getOffset(),
+ TF | ARMII::MO_LO16_NONLAZY_PIC)
+ .addImm(LabelId);
+ HI16 = HI16.addGlobalAddress(GV, MO.getOffset(),
+ TF | ARMII::MO_HI16_NONLAZY_PIC)
+ .addImm(LabelId);
} else {
const GlobalValue *GV = MO.getGlobal();
unsigned TF = MO.getTargetFlags();
LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
}
+
(*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
(*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
- LO16.addImm(Pred).addReg(PredReg);
- HI16.addImm(Pred).addReg(PredReg);
+
+ if (!isPIC_GA) {
+ LO16.addImm(Pred).addReg(PredReg);
+ HI16.addImm(Pred).addReg(PredReg);
+ }
TransferImpOps(MI, LO16, HI16);
MI.eraseFromParent();
break;