R600: Fix tracking of implicit defs in the IndirectAddressing pass
In some cases, we were losing track of live implicit registers which
was creating dead defs and causing the scheduler to produce invalid
code.
NOTE: This is a candidate for the Mesa stable branch.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175516 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/R600/AMDGPUIndirectAddressing.cpp b/lib/Target/R600/AMDGPUIndirectAddressing.cpp
index 56aaf23..15840b3 100644
--- a/lib/Target/R600/AMDGPUIndirectAddressing.cpp
+++ b/lib/Target/R600/AMDGPUIndirectAddressing.cpp
@@ -169,9 +169,6 @@
}
if (RegisterAddressMap[Reg] == Address) {
- if (!regHasExplicitDef(MRI, Reg)) {
- continue;
- }
PhiRegisters.push_back(Reg);
}
}
@@ -270,7 +267,8 @@
// instruction that uses indirect addressing.
BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
MI.getOperand(0).getReg())
- .addReg(AddrReg);
+ .addReg(AddrReg)
+ .addReg(Reg, RegState::Implicit);
}
} else {
// Indirect register access
@@ -292,8 +290,7 @@
// We only need to use REG_SEQUENCE for explicit defs, since the
// register coalescer won't do anything with the implicit defs.
MachineInstr *DefInstr = MRI.getVRegDef(Reg);
- if (!DefInstr->getOperand(0).isReg() ||
- DefInstr->getOperand(0).getReg() != Reg) {
+ if (!regHasExplicitDef(MRI, Reg)) {
continue;
}
@@ -310,6 +307,7 @@
Mov.addReg(IndirectReg, RegState::Implicit | RegState::Kill);
+ Mov.addReg(LiveAddressRegisterMap[Address], RegState::Implicit);
}
MI.eraseFromParent();
@@ -321,6 +319,26 @@
bool AMDGPUIndirectAddressingPass::regHasExplicitDef(MachineRegisterInfo &MRI,
unsigned Reg) const {
MachineInstr *DefInstr = MRI.getVRegDef(Reg);
- return DefInstr && DefInstr->getOperand(0).isReg() &&
+
+ if (!DefInstr) {
+ return false;
+ }
+
+ if (DefInstr->getOpcode() == AMDGPU::PHI) {
+ bool Explicit = false;
+ for (MachineInstr::const_mop_iterator I = DefInstr->operands_begin(),
+ E = DefInstr->operands_end();
+ I != E; ++I) {
+ const MachineOperand &MO = *I;
+ if (!MO.isReg() || MO.isDef()) {
+ continue;
+ }
+
+ Explicit = Explicit || regHasExplicitDef(MRI, MO.getReg());
+ }
+ return Explicit;
+ }
+
+ return DefInstr->getOperand(0).isReg() &&
DefInstr->getOperand(0).getReg() == Reg;
}