forked from OSchip/llvm-project
AMDGPU: Fix infinite searches in SIFixSGPRCopies
Summary: Two conditions could lead to infinite loops when processing PHI nodes in SIFixSGPRCopies. The first condition involves a REG_SEQUENCE that uses registers defined by both a PHI and a COPY. The second condition arises when a physical register is copied to a virtual register which is then used in a PHI node. If the same virtual register is copied to the same physical register, the result is an endless loop. %0:sgpr_64 = COPY $sgpr0_sgpr1 %2 = PHI %0, %bb.0, %1, %bb.1 $sgpr0_sgpr1 = COPY %0 Reviewers: alex-t, rampitec, arsenm Reviewed By: rampitec Subscribers: kzhuravl, jvesely, wdng, nhaehnle, yaxunl, dstuttard, tpr, t-tye, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D68970 llvm-svn: 374944
This commit is contained in:
parent
d498d606b9
commit
527e9f9a3f
|
@ -697,7 +697,9 @@ bool SIFixSGPRCopies::runOnMachineFunction(MachineFunction &MF) {
|
||||||
void SIFixSGPRCopies::processPHINode(MachineInstr &MI) {
|
void SIFixSGPRCopies::processPHINode(MachineInstr &MI) {
|
||||||
unsigned numVGPRUses = 0;
|
unsigned numVGPRUses = 0;
|
||||||
SetVector<const MachineInstr *> worklist;
|
SetVector<const MachineInstr *> worklist;
|
||||||
|
SmallSet<const MachineInstr *, 4> Visited;
|
||||||
worklist.insert(&MI);
|
worklist.insert(&MI);
|
||||||
|
Visited.insert(&MI);
|
||||||
while (!worklist.empty()) {
|
while (!worklist.empty()) {
|
||||||
const MachineInstr *Instr = worklist.pop_back_val();
|
const MachineInstr *Instr = worklist.pop_back_val();
|
||||||
unsigned Reg = Instr->getOperand(0).getReg();
|
unsigned Reg = Instr->getOperand(0).getReg();
|
||||||
|
@ -709,7 +711,9 @@ void SIFixSGPRCopies::processPHINode(MachineInstr &MI) {
|
||||||
!TRI->isSGPRReg(*MRI, UseMI->getOperand(0).getReg())) {
|
!TRI->isSGPRReg(*MRI, UseMI->getOperand(0).getReg())) {
|
||||||
numVGPRUses++;
|
numVGPRUses++;
|
||||||
}
|
}
|
||||||
worklist.insert(UseMI);
|
if (Visited.insert(UseMI).second)
|
||||||
|
worklist.insert(UseMI);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4289,6 +4289,8 @@ void SIInstrInfo::legalizeGenericOperand(MachineBasicBlock &InsertMBB,
|
||||||
|
|
||||||
bool ImpDef = Def->isImplicitDef();
|
bool ImpDef = Def->isImplicitDef();
|
||||||
while (!ImpDef && Def && Def->isCopy()) {
|
while (!ImpDef && Def && Def->isCopy()) {
|
||||||
|
if (Def->getOperand(1).getReg().isPhysical())
|
||||||
|
break;
|
||||||
Def = MRI.getUniqueVRegDef(Def->getOperand(1).getReg());
|
Def = MRI.getUniqueVRegDef(Def->getOperand(1).getReg());
|
||||||
ImpDef = Def && Def->isImplicitDef();
|
ImpDef = Def && Def->isImplicitDef();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,3 +60,53 @@ body: |
|
||||||
|
|
||||||
bb.8:
|
bb.8:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
# Avoid infinite loop in SIInstrInfo::legalizeGenericOperand when checking for ImpDef.
|
||||||
|
# GCN-LABEL: name: legalize-operand-search-each-def-once
|
||||||
|
# GCN-NOT: sreg_64 PHI
|
||||||
|
---
|
||||||
|
name: legalize-operand-search-each-def-once
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
successors: %bb.1, %bb.2
|
||||||
|
liveins: $sgpr0_sgpr1
|
||||||
|
|
||||||
|
%0:sgpr_64 = COPY $sgpr0_sgpr1
|
||||||
|
S_CBRANCH_VCCZ %bb.2, implicit undef $vcc
|
||||||
|
S_BRANCH %bb.1
|
||||||
|
|
||||||
|
bb.1:
|
||||||
|
%1:vreg_64 = IMPLICIT_DEF
|
||||||
|
S_BRANCH %bb.2
|
||||||
|
|
||||||
|
bb.2:
|
||||||
|
%2:sgpr_64 = PHI %0, %bb.0, %1, %bb.1
|
||||||
|
$sgpr0_sgpr1 = COPY %0
|
||||||
|
...
|
||||||
|
|
||||||
|
# A REG_SEQUENCE that uses registers defined by both a PHI and a COPY could
|
||||||
|
# result in an endless search.
|
||||||
|
# GCN-LABEL: name: process-phi-search-each-use-once
|
||||||
|
# GCN-NOT: sreg_32 PHI
|
||||||
|
---
|
||||||
|
name: process-phi-search-each-use-once
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
successors: %bb.1, %bb.2
|
||||||
|
liveins: $vgpr3
|
||||||
|
|
||||||
|
%0:vgpr_32 = COPY $vgpr3
|
||||||
|
S_CBRANCH_VCCZ %bb.2, implicit undef $vcc
|
||||||
|
S_BRANCH %bb.1
|
||||||
|
|
||||||
|
bb.1:
|
||||||
|
%1:sgpr_32 = IMPLICIT_DEF
|
||||||
|
S_BRANCH %bb.2
|
||||||
|
|
||||||
|
bb.2:
|
||||||
|
%2:sgpr_32 = PHI %0, %bb.0, %1, %bb.1
|
||||||
|
%3:vreg_64 = REG_SEQUENCE %2, %subreg.sub0, %0, %subreg.sub1
|
||||||
|
$vgpr3 = COPY %3.sub0
|
||||||
|
...
|
||||||
|
|
Loading…
Reference in New Issue