[llvm] [RISCV][GlobalISel] Select G_GLOBAL_VALUE (PR #70091)
Michael Maitland via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 24 11:56:43 PDT 2023
https://github.com/michaelmaitland created https://github.com/llvm/llvm-project/pull/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.
>From a296eb27b2b5a2012c7f5ead2f2b9fb80511f496 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Tue, 24 Oct 2023 11:50:29 -0700
Subject: [PATCH] [RISCV][GlobalISel] Select G_GLOBAL_VALUE
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.
---
.../RISCV/GISel/RISCVInstructionSelector.cpp | 66 +++++++++++++++++++
.../instruction-select/global-value.mir | 38 +++++++++++
2 files changed, 104 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/global-value.mir
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index a7f18c04a190790..43da613a65dd60e 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -63,6 +63,8 @@ class RISCVInstructionSelector : public InstructionSelector {
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;
@@ -95,6 +97,7 @@ class RISCVInstructionSelector : public InstructionSelector {
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
@@ -120,6 +123,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"
@@ -302,6 +306,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 =
@@ -483,6 +489,66 @@ 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:
+ report_fatal_error("Unsupported code model for lowering");
+ 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: {
+ // Must lie within *any* 2GiB range. The generates (addi (auipc
+ // %pcrel_hi(sym)) %pcrel_lo(auipc)).
+ Register AddrHiDest = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+ MachineInstr *AddrHi = MIB.buildInstr(RISCV::AUIPC)
+ .addDef(AddrHiDest)
+ .addGlobalAddress(GV, RISCVII::MO_PCREL_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_PCREL_LO);
+ 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())
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/global-value.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/global-value.mir
new file mode 100644
index 000000000000000..0f986a82b14cf6f
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/global-value.mir
@@ -0,0 +1,38 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
+# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -code-model=small \
+# RUN: %s -o - | FileCheck --check-prefix=RV64-SMALL %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
+ }
+...
+---
+name: global_addr
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gprb, preferred-register: '' }
+body: |
+ bb.1.entry:
+ ; RV64-SMALL-LABEL: name: global_addr
+ ; RV64-SMALL: [[LUI:%[0-9]+]]:gpr = LUI @x + 4
+ ; RV64-SMALL-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) @x
+ ; RV64-SMALL-NEXT: $x10 = COPY [[ADDI]]
+ ; RV64-SMALL-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV64-MED-LABEL: name: global_addr
+ ; RV64-MED: [[AUIPC:%[0-9]+]]:gpr = AUIPC @x + 6
+ ; RV64-MED-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[AUIPC]], target-flags(riscv-pcrel-lo) @x
+ ; RV64-MED-NEXT: $x10 = COPY [[ADDI]]
+ ; RV64-MED-NEXT: PseudoRET implicit $x10
+ %0:gprb(p0) = G_GLOBAL_VALUE @x
+ $x10 = COPY %0(p0)
+ PseudoRET implicit $x10
+...
+
More information about the llvm-commits
mailing list