diff --git a/llvm/lib/Target/PowerPC/PPCPreEmitPeephole.cpp b/llvm/lib/Target/PowerPC/PPCPreEmitPeephole.cpp --- a/llvm/lib/Target/PowerPC/PPCPreEmitPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCPreEmitPeephole.cpp @@ -365,6 +365,7 @@ // Initially, none of the acc registers are candidates. SmallVector Candidates( PPC::UACCRCRegClass.getNumRegs(), nullptr); + SmallVector VsrDefined(32, false); for (MachineInstr &BBI : MBB.instrs()) { unsigned Opc = BBI.getOpcode(); @@ -382,10 +383,15 @@ Register Acc = BBI.getOperand(0).getReg(); assert(PPC::ACCRCRegClass.contains(Acc) && "Unexpected register for XXMFACC"); - if (!Candidates[Acc - PPC::ACC0]) + unsigned Offset = Acc - PPC::ACC0; + if (!Candidates[Offset]) continue; - InstrsToErase.insert(&BBI); - InstrsToErase.insert(Candidates[Acc - PPC::ACC0]); + if (std::all_of(VsrDefined.begin() + Offset * 4, + VsrDefined.begin() + (Offset + 1) * 4, + [](bool Defined) { return Defined; })) { + InstrsToErase.insert(&BBI); + InstrsToErase.insert(Candidates[Acc - PPC::ACC0]); + } } // If we are visiting an instruction using an accumulator register // as operand, we remove it from the candidate set. @@ -396,6 +402,19 @@ Register Reg = Operand.getReg(); if (PPC::ACCRCRegClass.contains(Reg)) Candidates[Reg - PPC::ACC0] = nullptr; + + if (Operand.isDef()) { + if (PPC::ACCRCRegClass.contains(Reg)) { + for (int Index = 0; Index < 4; ++Index) + VsrDefined[Reg - PPC::ACC0 + Index] = true; + } else if (PPC::VSRpRCRegClass.contains(Reg) && + Reg < PPC::VSRp16) { + VsrDefined[Reg - PPC::VSRp0] = true; + VsrDefined[Reg - PPC::VSRp0 + 1] = true; + } else if (PPC::VSLRCRegClass.contains(Reg)) { + VsrDefined[Reg - PPC::VSL0] = true; + } + } } } } diff --git a/llvm/test/CodeGen/PowerPC/ppc64-acc-regalloc-bugfix.ll b/llvm/test/CodeGen/PowerPC/ppc64-acc-regalloc-bugfix.ll --- a/llvm/test/CodeGen/PowerPC/ppc64-acc-regalloc-bugfix.ll +++ b/llvm/test/CodeGen/PowerPC/ppc64-acc-regalloc-bugfix.ll @@ -1,14 +1,15 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -verify-machineinstrs -mtriple powerpc64le-unknown-linux-gnu \ ; RUN: -mcpu=pwr10 -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s \ -; RUN: | FileCheck %s +; RUN: -ppc-track-subreg-liveness | FileCheck %s define void @copy_novsrp() local_unnamed_addr { ; CHECK-LABEL: copy_novsrp: ; CHECK: # %bb.0: # %dmblvi_entry -; CHECK-NEXT: xxlxor v2, v2, v2 +; CHECK-NEXT: xxlxor vs3, vs3, vs3 ; CHECK-NEXT: xxlxor vs0, vs0, vs0 -; CHECK-NEXT: xxlor vs3, v2, v2 +; CHECK-NEXT: xxmtacc acc0 +; CHECK-NEXT: xxmfacc acc0 ; CHECK-NEXT: stxv vs1, 0(0) dmblvi_entry: %0 = tail call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> zeroinitializer, <16 x i8> undef, <16 x i8> undef, <16 x i8> zeroinitializer)