diff --git a/llvm/lib/Target/AMDGPU/SIFixSGPRCopies.cpp b/llvm/lib/Target/AMDGPU/SIFixSGPRCopies.cpp --- a/llvm/lib/Target/AMDGPU/SIFixSGPRCopies.cpp +++ b/llvm/lib/Target/AMDGPU/SIFixSGPRCopies.cpp @@ -697,7 +697,9 @@ void SIFixSGPRCopies::processPHINode(MachineInstr &MI) { unsigned numVGPRUses = 0; SetVector worklist; + SmallSet Visited; worklist.insert(&MI); + Visited.insert(&MI); while (!worklist.empty()) { const MachineInstr *Instr = worklist.pop_back_val(); unsigned Reg = Instr->getOperand(0).getReg(); @@ -709,7 +711,9 @@ !TRI->isSGPRReg(*MRI, UseMI->getOperand(0).getReg())) { numVGPRUses++; } - worklist.insert(UseMI); + if (Visited.insert(UseMI).second) + worklist.insert(UseMI); + continue; } diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -4227,6 +4227,8 @@ bool ImpDef = Def->isImplicitDef(); while (!ImpDef && Def && Def->isCopy()) { + if (Def->getOperand(1).getReg().isPhysical()) + break; Def = MRI.getUniqueVRegDef(Def->getOperand(1).getReg()); ImpDef = Def && Def->isImplicitDef(); } diff --git a/llvm/test/CodeGen/AMDGPU/fix-sgpr-copies.mir b/llvm/test/CodeGen/AMDGPU/fix-sgpr-copies.mir --- a/llvm/test/CodeGen/AMDGPU/fix-sgpr-copies.mir +++ b/llvm/test/CodeGen/AMDGPU/fix-sgpr-copies.mir @@ -60,3 +60,53 @@ 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 +...