[llvm] [RISCV][GlobalISel] Select G_GLOBAL_VALUE (PR #70091)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 24 13:23:05 PDT 2023
================
@@ -483,6 +489,78 @@ bool RISCVInstructionSelector::selectConstant(MachineInstr &MI,
return true;
}
+bool RISCVInstructionSelector::selectGlobalValue(
+ MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI) const {
+ assert(MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
+ "Expected G_GLOBAL_VALUE");
+ auto GV = MI.getOperand(1).getGlobal();
+ if (GV->isThreadLocal()) {
+ // TODO: implement this case.
+ return false;
+ }
+
+ switch (TM.getCodeModel()) {
+ default: {
+ reportGISelFailure(const_cast<MachineFunction &>(*MF), *TPC, *MORE,
+ getName(), "Unsupported code model for lowering", MI);
+ return false;
+ }
+ case CodeModel::Small: {
+ // Must lie within a single 2 GiB address range and must lie between
+ // absolute addresses -2 GiB and +2 GiB. This generates the pattern (addi
+ // (lui %hi(sym)) %lo(sym)).
+ Register AddrHiDest = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+ MachineInstr *AddrHi = MIB.buildInstr(RISCV::LUI)
+ .addDef(AddrHiDest)
+ .addGlobalAddress(GV, RISCVII::MO_HI);
+ if (!constrainSelectedInstRegOperands(*AddrHi, TII, TRI, RBI))
+ return false;
+
+ Register DstReg = MI.getOperand(0).getReg();
+ MachineInstr *Result = MIB.buildInstr(RISCV::ADDI)
+ .addDef(DstReg)
+ .addReg(AddrHiDest)
+ .addGlobalAddress(GV, 0, RISCVII::MO_LO);
+ if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
+ return false;
+
+ MI.eraseFromParent();
+ return true;
+ }
+ case CodeModel::Medium: {
+ Register DstReg = MI.getOperand(0).getReg();
+ MachineInstr *Result = nullptr;
+
+ // Emit LGA/LLA instead of the sequence it expands to because the pcrel_lo
+ // relocation needs to reference a label that points to the auipc
+ // instruction itself, not the global. This cannot be done inside the
+ // instruction selector.
+ if (GV->hasExternalWeakLinkage())
+ // An extern weak symbol may be undefined, i.e. have value 0, which may
+ // not be within 2GiB of PC, so use GOT-indirect addressing to access the
+ // symbol. This generates the pattern (PseudoLGA sym), which expands to
+ // (ld (addi (auipc %got_pcrel_hi(sym)) %pcrel_lo(auipc))).
+ Result = MIB.buildInstr(RISCV::PseudoLGA)
----------------
topperc wrote:
Need to add a MemOperand for the GOT.
https://github.com/llvm/llvm-project/pull/70091
More information about the llvm-commits
mailing list