diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -2097,13 +2097,17 @@ BBInfo &MInfo = MBBInfoMap[MI->getParent()]; set_union(MInfo.regsKilled, regsKilled); set_subtract(regsLive, regsKilled); regsKilled.clear(); - // Kill any masked registers. - while (!regMasks.empty()) { - const uint32_t *Mask = regMasks.pop_back_val(); - for (RegSet::iterator I = regsLive.begin(), E = regsLive.end(); I != E; ++I) - if (Register::isPhysicalRegister(*I) && - MachineOperand::clobbersPhysReg(Mask, *I)) - regsDead.push_back(*I); + // Kill any masked registers, unless the instruction is a predicated return, + // in which case either it returns (so we don't care about liveness after + // it), or it doesn't actually clobber any registers. + if (!(TII->isPredicated(*MI) && MI->isReturn())) { + while (!regMasks.empty()) { + const uint32_t *Mask = regMasks.pop_back_val(); + for (RegSet::iterator I = regsLive.begin(), E = regsLive.end(); I != E; ++I) + if (Register::isPhysicalRegister(*I) && + MachineOperand::clobbersPhysReg(Mask, *I)) + regsDead.push_back(*I); + } } set_subtract(regsLive, regsDead); regsDead.clear(); set_union(regsLive, regsDefined); regsDefined.clear(); diff --git a/llvm/test/MachineVerifier/predicated-call.mir b/llvm/test/MachineVerifier/predicated-call.mir new file mode 100644 --- /dev/null +++ b/llvm/test/MachineVerifier/predicated-call.mir @@ -0,0 +1,35 @@ +# RUN: llc -o - %s -mtriple=armv7a-none-eabi --run-pass none +# REQUIRES: arm-registered-target + +# It looks like r0 is clobbered by the register mask of the first tTAILJMPd, so +# the second tTAILJMPd uses a dead register ($r0). However, the first +# instruction is predicated, so there are two possible executions: +# - If the predicate is true, then the tail call will be executed, and the +# second will never be reached, so the liveness of r0 there doesn't matter. +# - If the predicate is false, the first call won't be executed, so $r0 will +# remain live until the second call. + +--- | + declare void @bar(i32) + declare void @baz(i32) + define void @foo() { + entry: + ret void + } +... + +--- +name: foo +tracksRegLiveness: true +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $lr + + $r0 = IMPLICIT_DEF + $cpsr = IMPLICIT_DEF + + tTAILJMPd @bar, 1 /* CC::ne */, killed $cpsr, csr_aapcs, implicit $sp, implicit $r0 + tTAILJMPd @baz, 14 /* CC::al */, $noreg, csr_aapcs, implicit $sp, implicit $r0 + +...