[llvm] [RISCV][GlobalISel] Select G_GLOBAL_VALUE (PR #68380)

Nitin John Raj via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 6 13:05:42 PDT 2023


https://github.com/nitinjohnraj updated https://github.com/llvm/llvm-project/pull/68380

>From eef2a293d346c05d7fceaa241c0f8489c37e6dea Mon Sep 17 00:00:00 2001
From: Nitin John Raj <nitin.raj at sifive.com>
Date: Thu, 21 Sep 2023 10:41:50 -0700
Subject: [PATCH 1/6] [RISCV][GlobalISel] Select G_PTR_ADD

---
 .../RISCV/GISel/RISCVInstructionSelector.cpp  | 48 +++++++++++++++++-
 .../instruction-select/ptradd-rv32.mir        | 50 +++++++++++++++++++
 .../instruction-select/ptradd-rv64.mir        | 50 +++++++++++++++++++
 3 files changed, 147 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv32.mir
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv64.mir

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 4f97a0d84f686f9..cead3a4a6c7fb06 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -45,6 +45,16 @@ class RISCVInstructionSelector : public InstructionSelector {
   getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB) const;
 
   bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
+
+  // A lowering phase that runs before any selection attempts.
+  // Returns true if the instruction was modified.
+  bool preISelLower(MachineInstr &MI, MachineIRBuilder &MIB,
+                    MachineRegisterInfo &MRI);
+
+  bool replacePtrWithInt(MachineOperand &Op, MachineIRBuilder &MIB,
+                         MachineRegisterInfo &MRI);
+
+  // Custom selection methods
   bool selectCopy(MachineInstr &MI, MachineRegisterInfo &MRI) const;
   bool selectConstant(MachineInstr &MI, MachineIRBuilder &MIB,
                       MachineRegisterInfo &MRI) const;
@@ -130,12 +140,14 @@ bool RISCVInstructionSelector::earlySelectShift(
 }
 
 bool RISCVInstructionSelector::select(MachineInstr &MI) {
-  unsigned Opc = MI.getOpcode();
   MachineBasicBlock &MBB = *MI.getParent();
   MachineFunction &MF = *MBB.getParent();
   MachineRegisterInfo &MRI = MF.getRegInfo();
   MachineIRBuilder MIB(MI);
 
+  preISelLower(MI, MIB, MRI);
+  const unsigned Opc = MI.getOpcode();
+
   if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
     if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) {
       const Register DefReg = MI.getOperand(0).getReg();
@@ -225,6 +237,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
 
   switch (Opc) {
   case TargetOpcode::G_ANYEXT:
+  case TargetOpcode::G_PTRTOINT:
   case TargetOpcode::G_TRUNC:
     return selectCopy(MI, MRI);
   case TargetOpcode::G_CONSTANT:
@@ -244,6 +257,39 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
   }
 }
 
+bool RISCVInstructionSelector::replacePtrWithInt(MachineOperand &Op,
+                                                 MachineIRBuilder &MIB,
+                                                 MachineRegisterInfo &MRI) {
+  assert(Op.isReg() && "Operand is not a register!");
+  Register PtrReg = Op.getReg();
+  assert(MRI.getType(PtrReg).isPointer() && "Operand is not a pointer!");
+
+  const LLT XLenLLT = LLT::scalar(STI.getXLen());
+  auto PtrToInt = MIB.buildPtrToInt(XLenLLT, PtrReg);
+  MRI.setRegBank(PtrToInt.getReg(0), RBI.getRegBank(RISCV::GPRRegBankID));
+  MRI.setType(PtrReg, XLenLLT);
+  Op.setReg(PtrToInt.getReg(0));
+  return select(*PtrToInt);
+}
+
+bool RISCVInstructionSelector::preISelLower(MachineInstr &MI,
+                                            MachineIRBuilder &MIB,
+                                            MachineRegisterInfo &MRI) {
+  switch (MI.getOpcode()) {
+  case TargetOpcode::G_PTR_ADD: {
+    Register DstReg = MI.getOperand(0).getReg();
+    const LLT XLenLLT = LLT::scalar(STI.getXLen());
+
+    replacePtrWithInt(MI.getOperand(1), MIB, MRI);
+    MI.setDesc(TII.get(TargetOpcode::G_ADD));
+    MRI.setType(DstReg, XLenLLT);
+    return true;
+  }
+  default:
+    return false;
+  }
+}
+
 void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB,
                                             const MachineInstr &MI,
                                             int OpIdx) const {
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv32.mir
new file mode 100644
index 000000000000000..bc0395685b40e9e
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv32.mir
@@ -0,0 +1,50 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -march=riscv32 -run-pass=instruction-select -simplify-mir \
+# RUN: -verify-machineinstrs %s -o - | FileCheck %s
+---
+name:            add_i32
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11
+
+    ; CHECK-LABEL: name: add_i32
+    ; CHECK: liveins: $x10, $x11
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[ADD]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(p0) = COPY $x10
+    %1:gprb(s32) = COPY $x11
+    %2:gprb(p0) = G_PTR_ADD %0, %1
+    $x10 = COPY %2(p0)
+    PseudoRET implicit $x10
+
+...
+---
+name:            addi_i32
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11
+
+    ; CHECK-LABEL: name: addi_i32
+    ; CHECK: liveins: $x10, $x11
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[COPY]], 20
+    ; CHECK-NEXT: $x10 = COPY [[ADDI]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(p0) = COPY $x10
+    %1:gprb(s32) = G_CONSTANT i32 20
+    %2:gprb(p0) = G_PTR_ADD %0, %1
+    $x10 = COPY %2(p0)
+    PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv64.mir
new file mode 100644
index 000000000000000..d024a7c659878de
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv64.mir
@@ -0,0 +1,50 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -march=riscv64 -run-pass=instruction-select -simplify-mir \
+# RUN: -verify-machineinstrs %s -o - | FileCheck %s
+---
+name:            add_i64
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11
+
+    ; CHECK-LABEL: name: add_i64
+    ; CHECK: liveins: $x10, $x11
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[ADD]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(p0) = COPY $x10
+    %1:gprb(s64) = COPY $x11
+    %2:gprb(p0) = G_PTR_ADD %0, %1
+    $x10 = COPY %2(p0)
+    PseudoRET implicit $x10
+
+...
+---
+name:            addi_i64
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11
+
+    ; CHECK-LABEL: name: addi_i64
+    ; CHECK: liveins: $x10, $x11
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[COPY]], 20
+    ; CHECK-NEXT: $x10 = COPY [[ADDI]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(p0) = COPY $x10
+    %1:gprb(s64) = G_CONSTANT i64 20
+    %2:gprb(p0) = G_PTR_ADD %0, %1
+    $x10 = COPY %2(p0)
+    PseudoRET implicit $x10
+
+...

>From 28f982ce78c092a02d63e7877f11c301a0e9fe78 Mon Sep 17 00:00:00 2001
From: Nitin John Raj <nitin.raj at sifive.com>
Date: Wed, 4 Oct 2023 17:19:22 -0700
Subject: [PATCH 2/6] bool preISelLower -> void preISelLower

---
 llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index cead3a4a6c7fb06..7537d75c0aeba40 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -48,7 +48,7 @@ class RISCVInstructionSelector : public InstructionSelector {
 
   // A lowering phase that runs before any selection attempts.
   // Returns true if the instruction was modified.
-  bool preISelLower(MachineInstr &MI, MachineIRBuilder &MIB,
+  void preISelLower(MachineInstr &MI, MachineIRBuilder &MIB,
                     MachineRegisterInfo &MRI);
 
   bool replacePtrWithInt(MachineOperand &Op, MachineIRBuilder &MIB,
@@ -260,7 +260,6 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
 bool RISCVInstructionSelector::replacePtrWithInt(MachineOperand &Op,
                                                  MachineIRBuilder &MIB,
                                                  MachineRegisterInfo &MRI) {
-  assert(Op.isReg() && "Operand is not a register!");
   Register PtrReg = Op.getReg();
   assert(MRI.getType(PtrReg).isPointer() && "Operand is not a pointer!");
 
@@ -272,7 +271,7 @@ bool RISCVInstructionSelector::replacePtrWithInt(MachineOperand &Op,
   return select(*PtrToInt);
 }
 
-bool RISCVInstructionSelector::preISelLower(MachineInstr &MI,
+void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
                                             MachineIRBuilder &MIB,
                                             MachineRegisterInfo &MRI) {
   switch (MI.getOpcode()) {
@@ -283,10 +282,7 @@ bool RISCVInstructionSelector::preISelLower(MachineInstr &MI,
     replacePtrWithInt(MI.getOperand(1), MIB, MRI);
     MI.setDesc(TII.get(TargetOpcode::G_ADD));
     MRI.setType(DstReg, XLenLLT);
-    return true;
   }
-  default:
-    return false;
   }
 }
 

>From 527fc0f84b01fda00e0ad96576b1bf33c879b889 Mon Sep 17 00:00:00 2001
From: Nitin John Raj <nitin.raj at sifive.com>
Date: Thu, 5 Oct 2023 16:48:02 -0700
Subject: [PATCH 3/6] Added missing break statement

---
 llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 7537d75c0aeba40..625e50ae90d0896 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -282,6 +282,7 @@ void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
     replacePtrWithInt(MI.getOperand(1), MIB, MRI);
     MI.setDesc(TII.get(TargetOpcode::G_ADD));
     MRI.setType(DstReg, XLenLLT);
+    break;
   }
   }
 }

>From c46b680333e205315569a865dcfcf549a29b62fa Mon Sep 17 00:00:00 2001
From: Nitin John Raj <nitin.raj at sifive.com>
Date: Thu, 5 Oct 2023 21:18:16 -0700
Subject: [PATCH 4/6] [RISCV][GlobalISel] Select G_GLOBAL_VALUE

---
 .../RISCV/GISel/RISCVInstructionSelector.cpp  | 38 ++++++++++++++++---
 llvm/lib/Target/RISCV/RISCVGISel.td           | 20 ++++++++++
 2 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 625e50ae90d0896..669a19df09390ac 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -48,7 +48,7 @@ class RISCVInstructionSelector : public InstructionSelector {
 
   // A lowering phase that runs before any selection attempts.
   // Returns true if the instruction was modified.
-  void preISelLower(MachineInstr &MI, MachineIRBuilder &MIB,
+  bool preISelLower(MachineInstr &MI, MachineIRBuilder &MIB,
                     MachineRegisterInfo &MRI);
 
   bool replacePtrWithInt(MachineOperand &Op, MachineIRBuilder &MIB,
@@ -73,6 +73,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
@@ -97,7 +98,7 @@ class RISCVInstructionSelector : public InstructionSelector {
 RISCVInstructionSelector::RISCVInstructionSelector(
     const RISCVTargetMachine &TM, const RISCVSubtarget &STI,
     const RISCVRegisterBankInfo &RBI)
-    : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI),
+    : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI), TM(TM),
 
 #define GET_GLOBALISEL_PREDICATES_INIT
 #include "RISCVGenGlobalISel.inc"
@@ -145,7 +146,9 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
   MachineRegisterInfo &MRI = MF.getRegInfo();
   MachineIRBuilder MIB(MI);
 
-  preISelLower(MI, MIB, MRI);
+  if (!preISelLower(MI, MIB, MRI))
+    return false;
+
   const unsigned Opc = MI.getOpcode();
 
   if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
@@ -271,10 +274,35 @@ bool RISCVInstructionSelector::replacePtrWithInt(MachineOperand &Op,
   return select(*PtrToInt);
 }
 
-void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
+bool RISCVInstructionSelector::preISelLower(MachineInstr &MI,
                                             MachineIRBuilder &MIB,
                                             MachineRegisterInfo &MRI) {
   switch (MI.getOpcode()) {
+  case TargetOpcode::G_GLOBAL_VALUE: {
+    switch (TM.getCodeModel()) {
+    case CodeModel::Small: {
+      const GlobalValue *GV = MI.getOperand(1).getGlobal();
+      MachineInstr *Result = MIB.buildInstr(RISCV::G_HI)
+        .addGlobalAddress(GV, 0, RISCVII::MO_HI);
+
+      if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
+        return false;
+
+      Register AddrHiReg = Result.getOperand(0).getReg();
+      Result = MIB.buildInstr(RISCV::G_ADD_LO)
+        .addReg(AddrHiReg)
+        .addGlobalAddress(GV, 0, RISCVII::MO_LO);
+
+      if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
+        return false;
+
+      MI.eraseFromParent();
+      return true;
+    }
+    default:
+      return false;
+    }
+  }
   case TargetOpcode::G_PTR_ADD: {
     Register DstReg = MI.getOperand(0).getReg();
     const LLT XLenLLT = LLT::scalar(STI.getXLen());
@@ -282,7 +310,7 @@ void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
     replacePtrWithInt(MI.getOperand(1), MIB, MRI);
     MI.setDesc(TII.get(TargetOpcode::G_ADD));
     MRI.setType(DstReg, XLenLLT);
-    break;
+    return true;
   }
   }
 }
diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td
index 8059b517f26ba3c..490f799b82a5e4f 100644
--- a/llvm/lib/Target/RISCV/RISCVGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVGISel.td
@@ -16,6 +16,26 @@
 include "RISCV.td"
 include "RISCVCombine.td"
 
+class RISCVGenericInstruction : GenericInstruction {
+  let Namespace = "RISCV";
+}
+
+// A pseudo to represent a relocatable add instruction as part of address
+// computation.
+def G_ADD_LO : RISCVGenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$src, type2:$imm);
+  let hasSideEffects = 0;
+}
+def : GINodeEquiv<G_ADD_LO, riscv_add_lo>;
+
+def G_HI : RISCVGenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$imm);
+  let hasSideEffects = 0;
+}
+def : GINodeEquiv<G_HI, riscv_hi>;
+
 def simm12Plus1 : ImmLeaf<XLenVT, [{
     return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>;
 

>From 894d6dd037669512c11f7d54882f9e52ce05dd26 Mon Sep 17 00:00:00 2001
From: Nitin John Raj <nitin.raj at sifive.com>
Date: Fri, 6 Oct 2023 13:04:41 -0700
Subject: [PATCH 5/6] Move functionality from ISelLowering to select + Delete
 new generic instructions

---
 .../RISCV/GISel/RISCVInstructionSelector.cpp  | 72 +++++++++++--------
 llvm/lib/Target/RISCV/RISCVGISel.td           | 20 ------
 llvm/lib/Target/RISCV/RISCVInstrInfo.td       | 22 ++++++
 3 files changed, 63 insertions(+), 51 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 669a19df09390ac..1c06a359622e6ef 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -48,7 +48,7 @@ class RISCVInstructionSelector : public InstructionSelector {
 
   // A lowering phase that runs before any selection attempts.
   // Returns true if the instruction was modified.
-  bool preISelLower(MachineInstr &MI, MachineIRBuilder &MIB,
+  void preISelLower(MachineInstr &MI, MachineIRBuilder &MIB,
                     MachineRegisterInfo &MRI);
 
   bool replacePtrWithInt(MachineOperand &Op, MachineIRBuilder &MIB,
@@ -58,6 +58,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 earlySelectShift(unsigned Opc, MachineInstr &I, MachineIRBuilder &MIB,
@@ -98,7 +100,8 @@ class RISCVInstructionSelector : public InstructionSelector {
 RISCVInstructionSelector::RISCVInstructionSelector(
     const RISCVTargetMachine &TM, const RISCVSubtarget &STI,
     const RISCVRegisterBankInfo &RBI)
-    : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI), TM(TM),
+    : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI),
+      TM(TM),
 
 #define GET_GLOBALISEL_PREDICATES_INIT
 #include "RISCVGenGlobalISel.inc"
@@ -146,8 +149,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
   MachineRegisterInfo &MRI = MF.getRegInfo();
   MachineIRBuilder MIB(MI);
 
-  if (!preISelLower(MI, MIB, MRI))
-    return false;
+  preISelLower(MI, MIB, MRI);
 
   const unsigned Opc = MI.getOpcode();
 
@@ -245,6 +247,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 =
@@ -274,35 +278,10 @@ bool RISCVInstructionSelector::replacePtrWithInt(MachineOperand &Op,
   return select(*PtrToInt);
 }
 
-bool RISCVInstructionSelector::preISelLower(MachineInstr &MI,
+void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
                                             MachineIRBuilder &MIB,
                                             MachineRegisterInfo &MRI) {
   switch (MI.getOpcode()) {
-  case TargetOpcode::G_GLOBAL_VALUE: {
-    switch (TM.getCodeModel()) {
-    case CodeModel::Small: {
-      const GlobalValue *GV = MI.getOperand(1).getGlobal();
-      MachineInstr *Result = MIB.buildInstr(RISCV::G_HI)
-        .addGlobalAddress(GV, 0, RISCVII::MO_HI);
-
-      if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
-        return false;
-
-      Register AddrHiReg = Result.getOperand(0).getReg();
-      Result = MIB.buildInstr(RISCV::G_ADD_LO)
-        .addReg(AddrHiReg)
-        .addGlobalAddress(GV, 0, RISCVII::MO_LO);
-
-      if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
-        return false;
-
-      MI.eraseFromParent();
-      return true;
-    }
-    default:
-      return false;
-    }
-  }
   case TargetOpcode::G_PTR_ADD: {
     Register DstReg = MI.getOperand(0).getReg();
     const LLT XLenLLT = LLT::scalar(STI.getXLen());
@@ -310,7 +289,6 @@ bool RISCVInstructionSelector::preISelLower(MachineInstr &MI,
     replacePtrWithInt(MI.getOperand(1), MIB, MRI);
     MI.setDesc(TII.get(TargetOpcode::G_ADD));
     MRI.setType(DstReg, XLenLLT);
-    return true;
   }
   }
 }
@@ -424,6 +402,38 @@ bool RISCVInstructionSelector::selectConstant(MachineInstr &MI,
   return true;
 }
 
+bool RISCVInstructionSelector::selectGlobalValue(MachineInstr &MI, MachineIRBuilder &MIB,
+                                                 MachineRegisterInfo &MRI) const {
+  assert(MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
+         "Wrong selector used!");
+
+  switch (TM.getCodeModel()) {
+  case CodeModel::Small: {
+    Register DstReg = MI.getOperand(0).getReg();
+    const GlobalValue *GV = MI.getOperand(1).getGlobal();
+    Register TmpReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+    MachineInstr *Result =
+        MIB.buildInstr(RISCV::LUI).addDef(TmpReg).addGlobalAddress(GV, 0, RISCVII::MO_HI);
+
+    if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
+      return false;
+
+    Result = MIB.buildInstr(RISCV::ADDI)
+      .addDef(DstReg)
+                 .addReg(TmpReg)
+                 .addGlobalAddress(GV, 0, RISCVII::MO_LO);
+
+    if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
+      return false;
+
+    MI.eraseFromParent();
+    return true;
+  }
+  default:
+    return false;
+  }
+}
+
 bool RISCVInstructionSelector::selectSExtInreg(MachineInstr &MI,
                                                MachineIRBuilder &MIB) const {
   if (!STI.isRV64())
diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td
index 490f799b82a5e4f..8059b517f26ba3c 100644
--- a/llvm/lib/Target/RISCV/RISCVGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVGISel.td
@@ -16,26 +16,6 @@
 include "RISCV.td"
 include "RISCVCombine.td"
 
-class RISCVGenericInstruction : GenericInstruction {
-  let Namespace = "RISCV";
-}
-
-// A pseudo to represent a relocatable add instruction as part of address
-// computation.
-def G_ADD_LO : RISCVGenericInstruction {
-  let OutOperandList = (outs type0:$dst);
-  let InOperandList = (ins type1:$src, type2:$imm);
-  let hasSideEffects = 0;
-}
-def : GINodeEquiv<G_ADD_LO, riscv_add_lo>;
-
-def G_HI : RISCVGenericInstruction {
-  let OutOperandList = (outs type0:$dst);
-  let InOperandList = (ins type1:$imm);
-  let hasSideEffects = 0;
-}
-def : GINodeEquiv<G_HI, riscv_hi>;
-
 def simm12Plus1 : ImmLeaf<XLenVT, [{
     return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>;
 
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index abbeff78b6e2864..3e1a3ec108b679d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2032,6 +2032,28 @@ def : Pat<(binop_allwusers<add> GPR:$rs1, (AddiPair:$rs2)),
                  (AddiPairImmSmall AddiPair:$rs2))>;
 }
 
+//===----------------------------------------------------------------------===//
+// GlobalISel generic instruction definitions
+/* /===----------------------------------------------------------------------===//
+
+class RISCVGenericInstruction : GenericInstruction {
+  let Namespace = "RISCV";
+}
+
+def G_ADD_LO : RISCVGenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$src, type2:$imm);
+  let hasSideEffects = 0;
+}
+def : GINodeEquiv<G_ADD_LO, riscv_add_lo>;
+
+def G_HI : RISCVGenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$imm);
+  let hasSideEffects = 0;
+}
+def : GINodeEquiv<G_HI, riscv_hi>;
+*/
 //===----------------------------------------------------------------------===//
 // Standard extensions
 //===----------------------------------------------------------------------===//

>From 280b4164b5533eb05933451781b2578f3e747c70 Mon Sep 17 00:00:00 2001
From: Nitin John Raj <nitin.raj at sifive.com>
Date: Fri, 6 Oct 2023 13:05:21 -0700
Subject: [PATCH 6/6] Add Test

---
 .../instruction-select/global-value-rv32.mir  | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/global-value-rv32.mir

diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/global-value-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/global-value-rv32.mir
new file mode 100644
index 000000000000000..22d339b8a9a0858
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/global-value-rv32.mir
@@ -0,0 +1,40 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -march=riscv32 -run-pass=instruction-select -simplify-mir \
+# RUN:   -verify-machineinstrs %s -o - | FileCheck --check-prefix=RV32I %s
+# RUN: llc -march=riscv64 -run-pass=instruction-select -simplify-mir \
+# RUN:   -verify-machineinstrs %s -o - | FileCheck --check-prefix=RV64I %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:
+    ; RV32I-LABEL: name: global_addr
+    ; RV32I: [[LUI:%[0-9]+]]:gpr = LUI target-flags(riscv-hi) @x
+    ; RV32I-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) @x
+    ; RV32I-NEXT: $x10 = COPY [[ADDI]]
+    ; RV32I-NEXT: PseudoRET implicit $x10
+    ;
+    ; RV64I-LABEL: name: global_addr
+    ; RV64I: [[LUI:%[0-9]+]]:gpr = LUI target-flags(riscv-hi) @x
+    ; RV64I-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) @x
+    ; RV64I-NEXT: $x10 = COPY [[ADDI]]
+    ; RV64I-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