[llvm] [RISCV][GlobalISel] Select G_GLOBAL_VALUE (PR #68380)
Nitin John Raj via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 5 21:21:46 PDT 2023
https://github.com/nitinjohnraj created https://github.com/llvm/llvm-project/pull/68380
We create generic instructions to serve as globalisel equivalents to selection DAG nodes, in order to leverage the SelectionDAG patterns.
>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/4] [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/4] 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/4] 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/4] [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;}]>;
More information about the llvm-commits
mailing list