Skip to content

[RISCV][GISEL] regbankselect and instruction-select for G_IMPLICIT_DEF #73060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class RISCVInstructionSelector : public InstructionSelector {

// Custom selection methods
bool selectCopy(MachineInstr &MI, MachineRegisterInfo &MRI) const;
bool selectImplicitDef(MachineInstr &MI, MachineIRBuilder &MIB,
MachineRegisterInfo &MRI) const;
bool materializeImm(Register Reg, int64_t Imm, MachineIRBuilder &MIB) const;
bool selectAddr(MachineInstr &MI, MachineIRBuilder &MIB,
MachineRegisterInfo &MRI, bool IsLocal = true,
Expand Down Expand Up @@ -623,6 +625,8 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
MI.eraseFromParent();
return true;
}
case TargetOpcode::G_IMPLICIT_DEF:
return selectImplicitDef(MI, MIB, MRI);
default:
return false;
}
Expand Down Expand Up @@ -736,6 +740,25 @@ bool RISCVInstructionSelector::selectCopy(MachineInstr &MI,
return true;
}

bool RISCVInstructionSelector::selectImplicitDef(
MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI) const {
assert(MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);

const Register DstReg = MI.getOperand(0).getReg();
const TargetRegisterClass *DstRC = getRegClassForTypeOnBank(
MRI.getType(DstReg), *RBI.getRegBank(DstReg, MRI, TRI));

assert(DstRC &&
"Register class not available for LLT, register bank combination");

if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(MI.getOpcode())
<< " operand\n");
}
MI.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
return true;
}

bool RISCVInstructionSelector::materializeImm(Register DstReg, int64_t Imm,
MachineIRBuilder &MIB) const {
MachineRegisterInfo &MRI = *MIB.getMRI();
Expand Down
34 changes: 26 additions & 8 deletions llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,14 @@ bool RISCVRegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
return hasFPConstraints(MI, MRI, TRI);
}

bool RISCVRegisterBankInfo::anyUseOnlyUseFP(
Register Def, const MachineRegisterInfo &MRI,
const TargetRegisterInfo &TRI) const {
return any_of(
MRI.use_nodbg_instructions(Def),
[&](const MachineInstr &UseMI) { return onlyUsesFP(UseMI, MRI, TRI); });
}

const RegisterBankInfo::InstructionMapping &
RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
const unsigned Opc = MI.getOpcode();
Expand Down Expand Up @@ -277,6 +285,19 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
getFPValueMapping(Ty.getSizeInBits()),
NumOperands);
}
case TargetOpcode::G_IMPLICIT_DEF: {
Register Dst = MI.getOperand(0).getReg();
auto Mapping = GPRValueMapping;
// FIXME: May need to do a better job determining when to use FPRB.
// For example, the look through COPY case:
// %0:_(s32) = G_IMPLICIT_DEF
// %1:_(s32) = COPY %0
// $f10_d = COPY %1(s32)
if (anyUseOnlyUseFP(Dst, MRI, TRI))
Mapping = getFPValueMapping(MRI.getType(Dst).getSizeInBits());
return getInstructionMapping(DefaultMappingID, /*Cost=*/1, Mapping,
NumOperands);
}
}

SmallVector<const ValueMapping *, 4> OpdsMapping(NumOperands);
Expand All @@ -296,14 +317,11 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
// Check if that load feeds fp instructions.
// In that case, we want the default mapping to be on FPR
// instead of blind map every scalar to GPR.
if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
[&](const MachineInstr &UseMI) {
// If we have at least one direct use in a FP instruction,
// assume this was a floating point load in the IR. If it was
// not, we would have had a bitcast before reaching that
// instruction.
return onlyUsesFP(UseMI, MRI, TRI);
}))
if (anyUseOnlyUseFP(MI.getOperand(0).getReg(), MRI, TRI))
// If we have at least one direct use in a FP instruction,
// assume this was a floating point load in the IR. If it was
// not, we would have had a bitcast before reaching that
// instruction.
OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits());

break;
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ class RISCVRegisterBankInfo final : public RISCVGenRegisterBankInfo {
bool onlyUsesFP(const MachineInstr &MI, const MachineRegisterInfo &MRI,
const TargetRegisterInfo &TRI) const;

/// \returns true if any use of \p Def only user FPRs.
bool anyUseOnlyUseFP(Register Def, const MachineRegisterInfo &MRI,
const TargetRegisterInfo &TRI) const;

/// \returns true if \p MI only defines FPRs.
bool onlyDefinesFP(const MachineInstr &MI, const MachineRegisterInfo &MRI,
const TargetRegisterInfo &TRI) const;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=riscv32 -mattr=+f -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - \
# RUN: | FileCheck -check-prefix=RV32F %s

---
name: implicit_def_gpr
legalized: true
regBankSelected: true
body: |
bb.0:
; RV32F-LABEL: name: implicit_def_gpr
; RV32F: [[DEF:%[0-9]+]]:gpr = IMPLICIT_DEF
; RV32F-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[DEF]], [[DEF]]
; RV32F-NEXT: $x10 = COPY [[ADD]]
%0:gprb(s32) = G_IMPLICIT_DEF
%1:gprb(s32) = G_ADD %0, %0
$x10 = COPY %1(s32)
...
---
name: implicit_def_copy_gpr
legalized: true
regBankSelected: true
body: |
bb.0:
; RV32F-LABEL: name: implicit_def_copy_gpr
; RV32F: [[DEF:%[0-9]+]]:gpr = IMPLICIT_DEF
; RV32F-NEXT: $x10 = COPY [[DEF]]
%0:gprb(s32) = G_IMPLICIT_DEF
%1:gprb(s32) = COPY %0(s32)
$x10 = COPY %1(s32)
...

---
name: implicit_def_fpr
legalized: true
regBankSelected: true
body: |
bb.0:
; RV32F-LABEL: name: implicit_def_fpr
; RV32F: [[DEF:%[0-9]+]]:fpr32 = IMPLICIT_DEF
; RV32F-NEXT: [[FADD_S:%[0-9]+]]:fpr32 = nofpexcept FADD_S [[DEF]], [[DEF]], 7
; RV32F-NEXT: $f10_f = COPY [[FADD_S]]
%0:fprb(s32) = G_IMPLICIT_DEF
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can register bank selection produce this? There's no code for G_IMPLICIT_DEF in RISCVRegistrBankInfo so it would always have gprb?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good point. I should add support and test regbankselection for this case.

%1:fprb(s32) = G_FADD %0, %0
$f10_f = COPY %1(s32)
...
---
name: implicit_def_copy_fpr
legalized: true
regBankSelected: true
body: |
bb.0:
; RV32F-LABEL: name: implicit_def_copy_fpr
; RV32F: [[DEF:%[0-9]+]]:fpr32 = IMPLICIT_DEF
; RV32F-NEXT: $f10_f = COPY [[DEF]]
%0:fprb(s32) = G_IMPLICIT_DEF
%1:fprb(s32) = COPY %0(s32)
$f10_f = COPY %1(s32)
...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test with a user with a user that has constraints, such that the selection of the user will have already pre-constrained the register?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that different than implicit_def_fpr? I assumed that G_FADD would constrain all operands to FPR. I don't know where to read the definition of selectImpl which handles G_FADD, but I would guess that it constrains reg operands.

Are you asking to test something else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's what I meant. I was looking at the copy chains below

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=riscv64 -mattr=+d -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - \
# RUN: | FileCheck -check-prefix=RV64D %s

---
name: implicit_def_gpr
legalized: true
regBankSelected: true
body: |
bb.0:
; RV64D-LABEL: name: implicit_def_gpr
; RV64D: [[DEF:%[0-9]+]]:gpr = IMPLICIT_DEF
; RV64D-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[DEF]], [[DEF]]
; RV64D-NEXT: $x10 = COPY [[ADD]]
%0:gprb(s64) = G_IMPLICIT_DEF
%1:gprb(s64) = G_ADD %0, %0
$x10 = COPY %1(s64)
...
---
name: implicit_def_copy_gpr
legalized: true
regBankSelected: true
body: |
bb.0:
; RV64D-LABEL: name: implicit_def_copy_gpr
; RV64D: [[DEF:%[0-9]+]]:gpr = IMPLICIT_DEF
; RV64D-NEXT: $x10 = COPY [[DEF]]
%0:gprb(s64) = G_IMPLICIT_DEF
%1:gprb(s64) = COPY %0(s64)
$x10 = COPY %1(s64)
...

---
name: implicit_def_fpr
legalized: true
regBankSelected: true
body: |
bb.0:
; RV64D-LABEL: name: implicit_def_fpr
; RV64D: [[DEF:%[0-9]+]]:fpr64 = IMPLICIT_DEF
; RV64D-NEXT: [[FADD_D:%[0-9]+]]:fpr64 = nofpexcept FADD_D [[DEF]], [[DEF]], 7
; RV64D-NEXT: $f10_d = COPY [[FADD_D]]
%0:fprb(s64) = G_IMPLICIT_DEF
%1:fprb(s64) = G_FADD %0, %0
$f10_d = COPY %1(s64)
...
---
name: implicit_def_copy_fpr
legalized: true
regBankSelected: true
body: |
bb.0:
; RV64D-LABEL: name: implicit_def_copy_fpr
; RV64D: [[DEF:%[0-9]+]]:fpr64 = IMPLICIT_DEF
; RV64D-NEXT: $f10_d = COPY [[DEF]]
%0:fprb(s64) = G_IMPLICIT_DEF
%1:fprb(s64) = COPY %0(s64)
$f10_d = COPY %1(s64)
...
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=riscv32 -mattr=+f -run-pass=regbankselect -simplify-mir -verify-machineinstrs %s -o - \
# RUN: | FileCheck -check-prefix=RV32F %s

---
name: implicit_def_gpr
legalized: true
body: |
bb.0:
; RV32F-LABEL: name: implicit_def_gpr
; RV32F: [[DEF:%[0-9]+]]:gprb(s32) = G_IMPLICIT_DEF
; RV32F-NEXT: [[ADD:%[0-9]+]]:gprb(s32) = G_ADD [[DEF]], [[DEF]]
; RV32F-NEXT: $x10 = COPY [[ADD]](s32)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = G_ADD %0, %0
$x10 = COPY %1(s32)
...
---
name: implicit_def_copy_gpr
legalized: true
body: |
bb.0:
; RV32F-LABEL: name: implicit_def_copy_gpr
; RV32F: [[DEF:%[0-9]+]]:gprb(s32) = G_IMPLICIT_DEF
; RV32F-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY [[DEF]](s32)
; RV32F-NEXT: $x10 = COPY [[COPY]](s32)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = COPY %0(s32)
$x10 = COPY %1(s32)
...

---
name: implicit_def_fpr
legalized: true
body: |
bb.0:
; RV32F-LABEL: name: implicit_def_fpr
; RV32F: [[DEF:%[0-9]+]]:fprb(s32) = G_IMPLICIT_DEF
; RV32F-NEXT: [[FADD:%[0-9]+]]:fprb(s32) = G_FADD [[DEF]], [[DEF]]
; RV32F-NEXT: $f10_f = COPY [[FADD]](s32)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = G_FADD %0, %0
$f10_f = COPY %1(s32)
...
---
name: implicit_def_copy_fpr
legalized: true
body: |
bb.0:
; RV32F-LABEL: name: implicit_def_copy_fpr
; RV32F: [[DEF:%[0-9]+]]:fprb(s32) = G_IMPLICIT_DEF
; RV32F-NEXT: $f10_f = COPY [[DEF]](s32)
%0:_(s32) = G_IMPLICIT_DEF
$f10_f = COPY %0(s32)
...
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=riscv64 -mattr=+d -run-pass=regbankselect -simplify-mir -verify-machineinstrs %s -o - \
# RUN: | FileCheck -check-prefix=RV64D %s

---
name: implicit_def_gpr
legalized: true
body: |
bb.0:
; RV64D-LABEL: name: implicit_def_gpr
; RV64D: [[DEF:%[0-9]+]]:gprb(s64) = G_IMPLICIT_DEF
; RV64D-NEXT: [[ADD:%[0-9]+]]:gprb(s64) = G_ADD [[DEF]], [[DEF]]
; RV64D-NEXT: $x10 = COPY [[ADD]](s64)
%0:_(s64) = G_IMPLICIT_DEF
%1:_(s64) = G_ADD %0, %0
$x10 = COPY %1(s64)
...
---
name: implicit_def_copy_gpr
legalized: true
body: |
bb.0:
; RV64D-LABEL: name: implicit_def_copy_gpr
; RV64D: [[DEF:%[0-9]+]]:gprb(s64) = G_IMPLICIT_DEF
; RV64D-NEXT: [[COPY:%[0-9]+]]:gprb(s64) = COPY [[DEF]](s64)
; RV64D-NEXT: $x10 = COPY [[COPY]](s64)
%0:_(s64) = G_IMPLICIT_DEF
%1:_(s64) = COPY %0(s64)
$x10 = COPY %1(s64)
...

---
name: implicit_def_fpr
legalized: true
body: |
bb.0:
; RV64D-LABEL: name: implicit_def_fpr
; RV64D: [[DEF:%[0-9]+]]:fprb(s64) = G_IMPLICIT_DEF
; RV64D-NEXT: [[FADD:%[0-9]+]]:fprb(s64) = G_FADD [[DEF]], [[DEF]]
; RV64D-NEXT: $f10_d = COPY [[FADD]](s64)
%0:_(s64) = G_IMPLICIT_DEF
%1:_(s64) = G_FADD %0, %0
$f10_d = COPY %1(s64)
...
---
name: implicit_def_copy_fpr
legalized: true
body: |
bb.0:
%0:_(s64) = G_IMPLICIT_DEF
$f10_d = COPY %0(s64)
...