mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 01:58:44 +08:00
[RISCV][GlobalISel] Select G_GLOBAL_VALUE (#70091)
G_GLOBAL_VALUE should be lowered into an absolute address if `-codemodel=small` is used or into a PC-relative if `-codemodel=medium` is used. PR #68380 tried to create special instructions to do this, but I don't see why we need to do that.
This commit is contained in:
@@ -31,6 +31,14 @@ public:
|
||||
/// for I in all mutated/inserted instructions:
|
||||
/// !isPreISelGenericOpcode(I.getOpcode())
|
||||
virtual bool select(MachineInstr &I) = 0;
|
||||
|
||||
void setTargetPassConfig(const TargetPassConfig *T) { TPC = T; }
|
||||
|
||||
void setRemarkEmitter(MachineOptimizationRemarkEmitter *M) { MORE = M; }
|
||||
|
||||
protected:
|
||||
const TargetPassConfig *TPC = nullptr;
|
||||
MachineOptimizationRemarkEmitter *MORE = nullptr;
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
||||
const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
|
||||
InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector();
|
||||
ISel->setTargetPassConfig(&TPC);
|
||||
|
||||
CodeGenOptLevel OldOptLevel = OptLevel;
|
||||
auto RestoreOptLevel = make_scope_exit([=]() { OptLevel = OldOptLevel; });
|
||||
@@ -109,6 +110,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
||||
// An optimization remark emitter. Used to report failures.
|
||||
MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
|
||||
ISel->setRemarkEmitter(&MORE);
|
||||
|
||||
// FIXME: There are many other MF/MFI fields we need to initialize.
|
||||
|
||||
|
||||
@@ -63,6 +63,8 @@ private:
|
||||
bool selectCopy(MachineInstr &MI, MachineRegisterInfo &MRI) const;
|
||||
bool selectConstant(MachineInstr &MI, MachineIRBuilder &MIB,
|
||||
MachineRegisterInfo &MRI) const;
|
||||
bool selectGlobalValue(MachineInstr &MI, MachineIRBuilder &MIB,
|
||||
MachineRegisterInfo &MRI) const;
|
||||
bool selectSExtInreg(MachineInstr &MI, MachineIRBuilder &MIB) const;
|
||||
bool selectSelect(MachineInstr &MI, MachineIRBuilder &MIB,
|
||||
MachineRegisterInfo &MRI) const;
|
||||
@@ -98,6 +100,7 @@ private:
|
||||
const RISCVInstrInfo &TII;
|
||||
const RISCVRegisterInfo &TRI;
|
||||
const RISCVRegisterBankInfo &RBI;
|
||||
const RISCVTargetMachine &TM;
|
||||
|
||||
// FIXME: This is necessary because DAGISel uses "Subtarget->" and GlobalISel
|
||||
// uses "STI." in the code generated by TableGen. We need to unify the name of
|
||||
@@ -123,6 +126,7 @@ RISCVInstructionSelector::RISCVInstructionSelector(
|
||||
const RISCVTargetMachine &TM, const RISCVSubtarget &STI,
|
||||
const RISCVRegisterBankInfo &RBI)
|
||||
: STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI),
|
||||
TM(TM),
|
||||
|
||||
#define GET_GLOBALISEL_PREDICATES_INIT
|
||||
#include "RISCVGenGlobalISel.inc"
|
||||
@@ -346,6 +350,8 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
|
||||
return selectCopy(MI, MRI);
|
||||
case TargetOpcode::G_CONSTANT:
|
||||
return selectConstant(MI, MIB, MRI);
|
||||
case TargetOpcode::G_GLOBAL_VALUE:
|
||||
return selectGlobalValue(MI, MIB, MRI);
|
||||
case TargetOpcode::G_BRCOND: {
|
||||
// TODO: Fold with G_ICMP.
|
||||
auto Bcc =
|
||||
@@ -543,6 +549,127 @@ 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;
|
||||
}
|
||||
|
||||
Register DefReg = MI.getOperand(0).getReg();
|
||||
const LLT DefTy = MRI.getType(DefReg);
|
||||
MachineInstr *Result = nullptr;
|
||||
|
||||
// When HWASAN is used and tagging of global variables is enabled
|
||||
// they should be accessed via the GOT, since the tagged address of a global
|
||||
// is incompatible with existing code models. This also applies to non-pic
|
||||
// mode.
|
||||
if (TM.isPositionIndependent() || Subtarget->allowTaggedGlobals()) {
|
||||
if (GV->isDSOLocal() && !Subtarget->allowTaggedGlobals()) {
|
||||
// Use PC-relative addressing to access the symbol. This generates the
|
||||
// pattern (PseudoLLA sym), which expands to (addi (auipc %pcrel_hi(sym))
|
||||
// %pcrel_lo(auipc)).
|
||||
Result = MIB.buildInstr(RISCV::PseudoLLA)
|
||||
.addDef(DefReg)
|
||||
.addGlobalAddress(GV, 0);
|
||||
} else {
|
||||
// Use PC-relative addressing to access the GOT for this symbol, then
|
||||
// load the address from the GOT. This generates the pattern (PseudoLGA
|
||||
// sym), which expands to (ld (addi (auipc %got_pcrel_hi(sym))
|
||||
// %pcrel_lo(auipc))).
|
||||
MachineFunction &MF = *MI.getParent()->getParent();
|
||||
MachineMemOperand *MemOp = MF.getMachineMemOperand(
|
||||
MachinePointerInfo::getGOT(MF),
|
||||
MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
|
||||
MachineMemOperand::MOInvariant,
|
||||
DefTy, Align(DefTy.getSizeInBits() / 8));
|
||||
|
||||
Result = MIB.buildInstr(RISCV::PseudoLGA)
|
||||
.addDef(DefReg)
|
||||
.addGlobalAddress(GV, 0)
|
||||
.addMemOperand(MemOp);
|
||||
}
|
||||
|
||||
if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
|
||||
return false;
|
||||
|
||||
MI.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Result = MIB.buildInstr(RISCV::ADDI)
|
||||
.addDef(DefReg)
|
||||
.addReg(AddrHiDest)
|
||||
.addGlobalAddress(GV, 0, RISCVII::MO_LO);
|
||||
|
||||
if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
|
||||
return false;
|
||||
|
||||
MI.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
case CodeModel::Medium: {
|
||||
// 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))).
|
||||
MachineFunction &MF = *MI.getParent()->getParent();
|
||||
MachineMemOperand *MemOp = MF.getMachineMemOperand(
|
||||
MachinePointerInfo::getGOT(MF),
|
||||
MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
|
||||
MachineMemOperand::MOInvariant,
|
||||
DefTy, Align(DefTy.getSizeInBits() / 8));
|
||||
|
||||
Result = MIB.buildInstr(RISCV::PseudoLGA)
|
||||
.addDef(DefReg)
|
||||
.addGlobalAddress(GV, 0)
|
||||
.addMemOperand(MemOp);
|
||||
} else {
|
||||
// Generate a sequence for accessing addresses within any 2GiB range
|
||||
// within the address space. This generates the pattern (PseudoLLA sym),
|
||||
// which expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)).
|
||||
Result = MIB.buildInstr(RISCV::PseudoLLA)
|
||||
.addDef(DefReg)
|
||||
.addGlobalAddress(GV, 0);
|
||||
}
|
||||
|
||||
if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
|
||||
return false;
|
||||
|
||||
MI.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RISCVInstructionSelector::selectSExtInreg(MachineInstr &MI,
|
||||
MachineIRBuilder &MIB) const {
|
||||
if (!STI.isRV64())
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
|
||||
# RUN: llc -mtriple=riscv32 -run-pass=instruction-select -relocation-model=pic \
|
||||
# RUN: %s -o - | FileCheck --check-prefix=RV32-PIE %s
|
||||
# RUN: llc -mtriple=riscv32 -run-pass=instruction-select \
|
||||
# RUN: -mattr=+tagged-globals %s -o - | FileCheck \
|
||||
# RUN: --check-prefix=RV32-NOPIE-TAG %s
|
||||
# RUN: llc -mtriple=riscv32 -run-pass=instruction-select -code-model=small \
|
||||
# RUN: %s -o - | FileCheck --check-prefix=RV32-SMALL-NOPIE-NOTAG %s
|
||||
# RUN: llc -mtriple=riscv32 -run-pass=instruction-select -code-model=medium \
|
||||
# RUN: %s -o - | FileCheck --check-prefix=RV32-MED %s
|
||||
|
||||
|
||||
--- |
|
||||
@x = global i32 0, align 4
|
||||
define ptr @global_addr() {
|
||||
entry:
|
||||
ret ptr @x
|
||||
}
|
||||
@y = extern_weak global i32, align 4
|
||||
define ptr @extern_weak_global_addr() {
|
||||
entry:
|
||||
ret ptr @y
|
||||
}
|
||||
@z = dso_local global i32 0, align 4
|
||||
define ptr @local_global_addr() {
|
||||
entry:
|
||||
ret ptr @z
|
||||
}
|
||||
...
|
||||
---
|
||||
name: global_addr
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: gprb, preferred-register: '' }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; RV32-PIE-LABEL: name: global_addr
|
||||
; RV32-PIE: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @x :: (dereferenceable invariant load (p0) from got)
|
||||
; RV32-PIE-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV32-PIE-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV32-NOPIE-TAG-LABEL: name: global_addr
|
||||
; RV32-NOPIE-TAG: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @x :: (dereferenceable invariant load (p0) from got)
|
||||
; RV32-NOPIE-TAG-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV32-NOPIE-TAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV32-SMALL-NOPIE-NOTAG-LABEL: name: global_addr
|
||||
; RV32-SMALL-NOPIE-NOTAG: [[LUI:%[0-9]+]]:gpr = LUI @x + 4
|
||||
; RV32-SMALL-NOPIE-NOTAG-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) @x
|
||||
; RV32-SMALL-NOPIE-NOTAG-NEXT: $x10 = COPY [[ADDI]]
|
||||
; RV32-SMALL-NOPIE-NOTAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV32-MED-LABEL: name: global_addr
|
||||
; RV32-MED: [[PseudoLLA:%[0-9]+]]:gpr = PseudoLLA @x
|
||||
; RV32-MED-NEXT: $x10 = COPY [[PseudoLLA]]
|
||||
; RV32-MED-NEXT: PseudoRET implicit $x10
|
||||
%0:gprb(p0) = G_GLOBAL_VALUE @x
|
||||
$x10 = COPY %0(p0)
|
||||
PseudoRET implicit $x10
|
||||
...
|
||||
---
|
||||
name: extern_weak_global_addr
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: gprb, preferred-register: '' }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; RV32-PIE-LABEL: name: extern_weak_global_addr
|
||||
; RV32-PIE: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @y :: (dereferenceable invariant load (p0) from got)
|
||||
; RV32-PIE-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV32-PIE-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV32-NOPIE-TAG-LABEL: name: extern_weak_global_addr
|
||||
; RV32-NOPIE-TAG: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @y :: (dereferenceable invariant load (p0) from got)
|
||||
; RV32-NOPIE-TAG-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV32-NOPIE-TAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV32-SMALL-NOPIE-NOTAG-LABEL: name: extern_weak_global_addr
|
||||
; RV32-SMALL-NOPIE-NOTAG: [[LUI:%[0-9]+]]:gpr = LUI @y + 4
|
||||
; RV32-SMALL-NOPIE-NOTAG-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) @y
|
||||
; RV32-SMALL-NOPIE-NOTAG-NEXT: $x10 = COPY [[ADDI]]
|
||||
; RV32-SMALL-NOPIE-NOTAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV32-MED-LABEL: name: extern_weak_global_addr
|
||||
; RV32-MED: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @y :: (dereferenceable invariant load (p0) from got)
|
||||
; RV32-MED-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV32-MED-NEXT: PseudoRET implicit $x10
|
||||
%0:gprb(p0) = G_GLOBAL_VALUE @y
|
||||
$x10 = COPY %0(p0)
|
||||
PseudoRET implicit $x10
|
||||
...
|
||||
---
|
||||
name: local_global_addr
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: gprb, preferred-register: '' }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; RV32-PIE-LABEL: name: local_global_addr
|
||||
; RV32-PIE: [[PseudoLLA:%[0-9]+]]:gpr = PseudoLLA @z
|
||||
; RV32-PIE-NEXT: $x10 = COPY [[PseudoLLA]]
|
||||
; RV32-PIE-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV32-NOPIE-TAG-LABEL: name: local_global_addr
|
||||
; RV32-NOPIE-TAG: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @z :: (dereferenceable invariant load (p0) from got)
|
||||
; RV32-NOPIE-TAG-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV32-NOPIE-TAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV32-SMALL-NOPIE-NOTAG-LABEL: name: local_global_addr
|
||||
; RV32-SMALL-NOPIE-NOTAG: [[LUI:%[0-9]+]]:gpr = LUI @z + 4
|
||||
; RV32-SMALL-NOPIE-NOTAG-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) @z
|
||||
; RV32-SMALL-NOPIE-NOTAG-NEXT: $x10 = COPY [[ADDI]]
|
||||
; RV32-SMALL-NOPIE-NOTAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV32-MED-LABEL: name: local_global_addr
|
||||
; RV32-MED: [[PseudoLLA:%[0-9]+]]:gpr = PseudoLLA @z
|
||||
; RV32-MED-NEXT: $x10 = COPY [[PseudoLLA]]
|
||||
; RV32-MED-NEXT: PseudoRET implicit $x10
|
||||
%0:gprb(p0) = G_GLOBAL_VALUE @z
|
||||
$x10 = COPY %0(p0)
|
||||
PseudoRET implicit $x10
|
||||
...
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
|
||||
# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -relocation-model=pic \
|
||||
# RUN: %s -o - | FileCheck --check-prefix=RV64-PIE %s
|
||||
# RUN: llc -mtriple=riscv64 -run-pass=instruction-select \
|
||||
# RUN: -mattr=+tagged-globals %s -o - | FileCheck \
|
||||
# RUN: --check-prefix=RV64-NOPIE-TAG %s
|
||||
# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -code-model=small \
|
||||
# RUN: %s -o - | FileCheck --check-prefix=RV64-SMALL-NOPIE-NOTAG %s
|
||||
# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -code-model=medium \
|
||||
# RUN: %s -o - | FileCheck --check-prefix=RV64-MED %s
|
||||
|
||||
--- |
|
||||
@x = global i32 0, align 4
|
||||
define ptr @global_addr() {
|
||||
entry:
|
||||
ret ptr @x
|
||||
}
|
||||
@y = extern_weak global i32, align 4
|
||||
define ptr @extern_weak_global_addr() {
|
||||
entry:
|
||||
ret ptr @y
|
||||
}
|
||||
@z = dso_local global i32 0, align 4
|
||||
define ptr @local_global_addr() {
|
||||
entry:
|
||||
ret ptr @z
|
||||
}
|
||||
...
|
||||
---
|
||||
name: global_addr
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: gprb, preferred-register: '' }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; RV64-PIE-LABEL: name: global_addr
|
||||
; RV64-PIE: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @x :: (dereferenceable invariant load (p0) from got)
|
||||
; RV64-PIE-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV64-PIE-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV64-NOPIE-TAG-LABEL: name: global_addr
|
||||
; RV64-NOPIE-TAG: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @x :: (dereferenceable invariant load (p0) from got)
|
||||
; RV64-NOPIE-TAG-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV64-NOPIE-TAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV64-SMALL-NOPIE-NOTAG-LABEL: name: global_addr
|
||||
; RV64-SMALL-NOPIE-NOTAG: [[LUI:%[0-9]+]]:gpr = LUI @x + 4
|
||||
; RV64-SMALL-NOPIE-NOTAG-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) @x
|
||||
; RV64-SMALL-NOPIE-NOTAG-NEXT: $x10 = COPY [[ADDI]]
|
||||
; RV64-SMALL-NOPIE-NOTAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV64-MED-LABEL: name: global_addr
|
||||
; RV64-MED: [[PseudoLLA:%[0-9]+]]:gpr = PseudoLLA @x
|
||||
; RV64-MED-NEXT: $x10 = COPY [[PseudoLLA]]
|
||||
; RV64-MED-NEXT: PseudoRET implicit $x10
|
||||
%0:gprb(p0) = G_GLOBAL_VALUE @x
|
||||
$x10 = COPY %0(p0)
|
||||
PseudoRET implicit $x10
|
||||
...
|
||||
---
|
||||
name: extern_weak_global_addr
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: gprb, preferred-register: '' }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; RV64-PIE-LABEL: name: extern_weak_global_addr
|
||||
; RV64-PIE: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @y :: (dereferenceable invariant load (p0) from got)
|
||||
; RV64-PIE-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV64-PIE-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV64-NOPIE-TAG-LABEL: name: extern_weak_global_addr
|
||||
; RV64-NOPIE-TAG: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @y :: (dereferenceable invariant load (p0) from got)
|
||||
; RV64-NOPIE-TAG-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV64-NOPIE-TAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV64-SMALL-NOPIE-NOTAG-LABEL: name: extern_weak_global_addr
|
||||
; RV64-SMALL-NOPIE-NOTAG: [[LUI:%[0-9]+]]:gpr = LUI @y + 4
|
||||
; RV64-SMALL-NOPIE-NOTAG-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) @y
|
||||
; RV64-SMALL-NOPIE-NOTAG-NEXT: $x10 = COPY [[ADDI]]
|
||||
; RV64-SMALL-NOPIE-NOTAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV64-MED-LABEL: name: extern_weak_global_addr
|
||||
; RV64-MED: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @y :: (dereferenceable invariant load (p0) from got)
|
||||
; RV64-MED-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV64-MED-NEXT: PseudoRET implicit $x10
|
||||
%0:gprb(p0) = G_GLOBAL_VALUE @y
|
||||
$x10 = COPY %0(p0)
|
||||
PseudoRET implicit $x10
|
||||
...
|
||||
---
|
||||
name: local_global_addr
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: gprb, preferred-register: '' }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; RV64-PIE-LABEL: name: local_global_addr
|
||||
; RV64-PIE: [[PseudoLLA:%[0-9]+]]:gpr = PseudoLLA @z
|
||||
; RV64-PIE-NEXT: $x10 = COPY [[PseudoLLA]]
|
||||
; RV64-PIE-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV64-NOPIE-TAG-LABEL: name: local_global_addr
|
||||
; RV64-NOPIE-TAG: [[PseudoLGA:%[0-9]+]]:gpr = PseudoLGA @z :: (dereferenceable invariant load (p0) from got)
|
||||
; RV64-NOPIE-TAG-NEXT: $x10 = COPY [[PseudoLGA]]
|
||||
; RV64-NOPIE-TAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV64-SMALL-NOPIE-NOTAG-LABEL: name: local_global_addr
|
||||
; RV64-SMALL-NOPIE-NOTAG: [[LUI:%[0-9]+]]:gpr = LUI @z + 4
|
||||
; RV64-SMALL-NOPIE-NOTAG-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) @z
|
||||
; RV64-SMALL-NOPIE-NOTAG-NEXT: $x10 = COPY [[ADDI]]
|
||||
; RV64-SMALL-NOPIE-NOTAG-NEXT: PseudoRET implicit $x10
|
||||
;
|
||||
; RV64-MED-LABEL: name: local_global_addr
|
||||
; RV64-MED: [[PseudoLLA:%[0-9]+]]:gpr = PseudoLLA @z
|
||||
; RV64-MED-NEXT: $x10 = COPY [[PseudoLLA]]
|
||||
; RV64-MED-NEXT: PseudoRET implicit $x10
|
||||
%0:gprb(p0) = G_GLOBAL_VALUE @z
|
||||
$x10 = COPY %0(p0)
|
||||
PseudoRET implicit $x10
|
||||
...
|
||||
|
||||
Reference in New Issue
Block a user