llvm.org GIT mirror llvm / 745fff8
ARM: partially handle 32-bit relocations for WoA IMAGE_REL_ARM_MOV32T relocations require that the movw/movt pair-wise relocation is not split up and reordered. When expanding the mov32imm pseudo-instruction, create a bundle if the machine operand is referencing an address. This helps ensure that the relocatable address load is not reordered by subsequent passes. Unfortunately, this only partially handles the case as the Constant Island Pass occurs after the instructions are unbundled and does not properly handle bundles. That is a more fundamental issue with the pass itself and beyond the scope of this change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207608 91177308-0d34-0410-b5e6-96231b3b80d8 Saleem Abdulrasool 6 years ago
2 changed file(s) with 72 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
614614 MI.eraseFromParent();
615615 }
616616
617 static bool IsAnAddressOperand(const MachineOperand &MO) {
618 // This check is overly conservative. Unless we are certain that the machine
619 // operand is not a symbol reference, we return that it is a symbol reference.
620 // This is important as the load pair may not be split up Windows.
621 switch (MO.getType()) {
622 default: llvm_unreachable("unhandled machine operand type");
623 case MachineOperand::MO_Register:
624 case MachineOperand::MO_Immediate:
625 case MachineOperand::MO_CImmediate:
626 case MachineOperand::MO_FPImmediate:
627 return false;
628 case MachineOperand::MO_MachineBasicBlock:
629 return true;
630 case MachineOperand::MO_FrameIndex:
631 return false;
632 case MachineOperand::MO_ConstantPoolIndex:
633 case MachineOperand::MO_TargetIndex:
634 case MachineOperand::MO_JumpTableIndex:
635 case MachineOperand::MO_ExternalSymbol:
636 case MachineOperand::MO_GlobalAddress:
637 case MachineOperand::MO_BlockAddress:
638 return true;
639 case MachineOperand::MO_RegisterMask:
640 case MachineOperand::MO_RegisterLiveOut:
641 return false;
642 case MachineOperand::MO_Metadata:
643 case MachineOperand::MO_MCSymbol:
644 return true;
645 case MachineOperand::MO_CFIIndex:
646 return false;
647 }
648 }
649
617650 void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
618651 MachineBasicBlock::iterator &MBBI) {
619652 MachineInstr &MI = *MBBI;
624657 bool DstIsDead = MI.getOperand(0).isDead();
625658 bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
626659 const MachineOperand &MO = MI.getOperand(isCC ? 2 : 1);
660 bool RequiresBundling = STI->isTargetWindows() && IsAnAddressOperand(MO);
627661 MachineInstrBuilder LO16, HI16;
628662
629663 if (!STI->hasV6T2Ops() &&
630664 (Opcode == ARM::MOVi32imm || Opcode == ARM::MOVCCi32imm)) {
665 // FIXME Windows CE supports older ARM CPUs
666 assert(!STI->isTargetWindows() && "Windows on ARM requires ARMv7+");
667
631668 // Expand into a movi + orr.
632669 LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi), DstReg);
633670 HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ORRri))
659696 HI16Opc = ARM::MOVTi16;
660697 }
661698
699 if (RequiresBundling)
700 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(TargetOpcode::BUNDLE));
701
662702 LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg);
663703 HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc))
664704 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
681721 HI16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
682722 LO16.addImm(Pred).addReg(PredReg);
683723 HI16.addImm(Pred).addReg(PredReg);
724
725 if (RequiresBundling) {
726 LO16->bundleWithPred();
727 HI16->bundleWithPred();
728 }
684729
685730 TransferImpOps(MI, LO16, HI16);
686731 MI.eraseFromParent();
0 ; RUN: llc -mtriple=thumbv7-windows -o - %s \
1 ; RUN: | FileCheck %s -check-prefix CHECK-WINDOWS
2
3 ; RUN: llc -mtriple=thumbv7-eabi -o - %s \
4 ; RUN: | FileCheck %s -check-prefix CHECK-EABI
5
6 @i = common global i32 0, align 4
7 @j = common global i32 0, align 4
8
9 ; Function Attrs: nounwind optsize readonly
10 define i32 @relocation(i32 %j, i32 %k) {
11 entry:
12 %0 = load i32* @i, align 4
13 %1 = load i32* @j, align 4
14 %add = add nsw i32 %1, %0
15 ret i32 %add
16 }
17
18 ; CHECK-WINDOWS: movw r[[i:[0-4]]], :lower16:i
19 ; CHECK-WINDOWS-NEXT: movt r[[i]], :upper16:i
20 ; CHECK-WINDOWS: movw r[[j:[0-4]]], :lower16:j
21 ; CHECK-WINDOWS-NEXT: movt r[[j]], :upper16:j
22
23 ; CHECK-EABI: movw r[[i:[0-4]]], :lower16:i
24 ; CHECK-EABI: movw r[[j:[0-4]]], :lower16:j
25 ; CHECK-EABI-NEXT: movt r[[i]], :upper16:i
26 ; CHECK-EABI-NEXT: movt r[[j]], :upper16:j