-
Notifications
You must be signed in to change notification settings - Fork 14.9k
AMDGPU: Fix fixme for out of bounds indexing in usesConstantBus check #155603
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
base: users/arsenm/amdgpu/dpp-avoid-isOperandLegal-incomplete-instruction
Are you sure you want to change the base?
Conversation
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-backend-amdgpu Author: Matt Arsenault (arsenm) ChangesThis loop over all the operands in the MachineInstr will eventually Full diff: https://github.com/llvm/llvm-project/pull/155603.diff 2 Files Affected:
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index ac60dc19aa974..d3c8e8ad7c02e 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -4758,6 +4758,36 @@ MachineInstr *SIInstrInfo::buildShrunkInst(MachineInstr &MI,
return Inst32;
}
+bool SIInstrInfo::physRegUsesConstantBus(const MachineOperand &RegOp) const {
+ // Null is free
+ Register Reg = RegOp.getReg();
+ if (Reg == AMDGPU::SGPR_NULL || Reg == AMDGPU::SGPR_NULL64)
+ return false;
+
+ // SGPRs use the constant bus
+
+ // FIXME: implicit registers that are not part of the MCInstrDesc's implicit
+ // physical register operands should also count.
+ if (RegOp.isImplicit())
+ return Reg == AMDGPU::VCC || Reg == AMDGPU::VCC_LO || Reg == AMDGPU::M0;
+
+ // Normal exec read does not count.
+ if ((Reg == AMDGPU::EXEC || Reg == AMDGPU::EXEC_LO) && RegOp.isImplicit())
+ return false;
+
+ // SGPRs use the constant bus
+ return AMDGPU::SReg_32RegClass.contains(Reg) ||
+ AMDGPU::SReg_64RegClass.contains(Reg);
+}
+
+bool SIInstrInfo::regUsesConstantBus(const MachineOperand &RegOp,
+ const MachineRegisterInfo &MRI) const {
+ Register Reg = RegOp.getReg();
+ if (Reg.isVirtual())
+ return RI.isSGPRClass(MRI.getRegClass(Reg));
+ return physRegUsesConstantBus(RegOp);
+}
+
bool SIInstrInfo::usesConstantBus(const MachineRegisterInfo &MRI,
const MachineOperand &MO,
const MCOperandInfo &OpInfo) const {
@@ -4765,23 +4795,10 @@ bool SIInstrInfo::usesConstantBus(const MachineRegisterInfo &MRI,
if (!MO.isReg())
return !isInlineConstant(MO, OpInfo);
- if (!MO.isUse())
- return false;
-
- if (MO.getReg().isVirtual())
- return RI.isSGPRClass(MRI.getRegClass(MO.getReg()));
-
- // Null is free
- if (MO.getReg() == AMDGPU::SGPR_NULL || MO.getReg() == AMDGPU::SGPR_NULL64)
- return false;
-
- // SGPRs use the constant bus
- if (MO.isImplicit()) {
- return MO.getReg() == AMDGPU::M0 || MO.getReg() == AMDGPU::VCC ||
- MO.getReg() == AMDGPU::VCC_LO;
- }
- return AMDGPU::SReg_32RegClass.contains(MO.getReg()) ||
- AMDGPU::SReg_64RegClass.contains(MO.getReg());
+ Register Reg = MO.getReg();
+ if (Reg.isVirtual())
+ return RI.isSGPRClass(MRI.getRegClass(Reg));
+ return physRegUsesConstantBus(MO);
}
static Register findImplicitSGPRRead(const MachineInstr &MI) {
@@ -6250,13 +6267,12 @@ bool SIInstrInfo::isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
continue;
const MachineOperand &Op = MI.getOperand(i);
if (Op.isReg()) {
- RegSubRegPair SGPR(Op.getReg(), Op.getSubReg());
- if (!SGPRsUsed.count(SGPR) &&
- // FIXME: This can access off the end of the operands() array.
- usesConstantBus(MRI, Op, InstDesc.operands().begin()[i])) {
- if (--ConstantBusLimit <= 0)
- return false;
- SGPRsUsed.insert(SGPR);
+ if (Op.isUse()) {
+ RegSubRegPair SGPR(Op.getReg(), Op.getSubReg());
+ if (regUsesConstantBus(Op, MRI) && SGPRsUsed.insert(SGPR).second) {
+ if (--ConstantBusLimit <= 0)
+ return false;
+ }
}
} else if (AMDGPU::isSISrcOperand(InstDesc, i) &&
!isInlineConstant(Op, InstDesc.operands()[i])) {
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
index 7552ead12570f..9482b91350d80 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
@@ -1189,6 +1189,10 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
/// This function will return false if you pass it a 32-bit instruction.
bool hasVALU32BitEncoding(unsigned Opcode) const;
+ bool physRegUsesConstantBus(const MachineOperand &Reg) const;
+ bool regUsesConstantBus(const MachineOperand &Reg,
+ const MachineRegisterInfo &MRI) const;
+
/// Returns true if this operand uses the constant bus.
bool usesConstantBus(const MachineRegisterInfo &MRI,
const MachineOperand &MO,
|
This loop over all the operands in the MachineInstr will eventually go past the end of the MCInstrDesc's explicit operands. We don't need the instr desc to compute the constant bus usage, just the register and whether it's implicit or not. The check here is slightly conservative. e.g. a random vcc implicit use appended to an instruction will falsely report a constant bus use.
088e57a
to
11df2dc
Compare
e16231a
to
3aaf3b7
Compare
return false; | ||
|
||
// SGPRs use the constant bus | ||
return AMDGPU::SReg_32RegClass.contains(Reg) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isSGPRPhysReg()
? Just in case we will have more classes, or got ttmp or something like that in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate change, this just shuffles the existing logic
This loop over all the operands in the MachineInstr will eventually
go past the end of the MCInstrDesc's explicit operands. We don't
need the instr desc to compute the constant bus usage, just the
register and whether it's implicit or not. The check here is slightly
conservative. e.g. a random vcc implicit use appended to an instruction
will falsely report a constant bus use.