From d2dcbd00f7889debe5c9bb3691e9dfaf5e0fa5a2 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Fri, 17 Oct 2014 21:02:44 +0000 Subject: [PATCH] [PowerPC] Change liveness testing in VSX FMA mutation pass With VSX enabled, LLVM crashes when compiling test/CodeGen/PowerPC/fma.ll. I traced this to the liveness test that's revised in this patch. The interval test is designed to only work for virtual registers, but in this case the AddendSrcReg is physical. Since there is already a walk of the MIs between the AddendMI and the FMA, I added a check for def/kill of the AddendSrcReg in that loop. At Hal Finkel's request, I converted the liveness test to an assert restricted to virtual registers. I've changed the fma.ll test to have VSX and non-VSX variants so we can test both kinds of multiply-adds. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220090 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCInstrInfo.cpp | 28 +++++++++++++++------ test/CodeGen/PowerPC/fma.ll | 38 ++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 61adc4b30e0..3b0f1efbd02 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1622,6 +1622,7 @@ protected: bool Changed = false; MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); + const TargetRegisterInfo *TRI = &TII->getRegisterInfo(); for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end(); I != IE; ++I) { MachineInstr *MI = I; @@ -1687,16 +1688,26 @@ protected: // In theory, there could be other uses of the addend copy before this // fma. We could deal with this, but that would require additional // logic below and I suspect it will not occur in any relevant - // situations. - bool OtherUsers = false; + // situations. Additionally, check whether the copy source is killed + // prior to the fma. In order to replace the addend here with the + // source of the copy, it must still be live here. We can't use + // interval testing for a physical register, so as long as we're + // walking the MIs we may as well test liveness here. + bool OtherUsers = false, KillsAddendSrc = false; for (auto J = std::prev(I), JE = MachineBasicBlock::iterator(AddendMI); - J != JE; --J) + J != JE; --J) { if (J->readsVirtualRegister(AddendMI->getOperand(0).getReg())) { OtherUsers = true; break; } + if (J->modifiesRegister(AddendSrcReg, TRI) || + J->killsRegister(AddendSrcReg, TRI)) { + KillsAddendSrc = true; + break; + } + } - if (OtherUsers) + if (OtherUsers || KillsAddendSrc) continue; // Find one of the product operands that is killed by this instruction. @@ -1717,10 +1728,11 @@ protected: if (!KilledProdOp) continue; - // In order to replace the addend here with the source of the copy, - // it must still be live here. - if (!LIS->getInterval(AddendMI->getOperand(1).getReg()).liveAt(FMAIdx)) - continue; + // For virtual registers, verify that the addend source register + // is live here (as should have been assured above). + if (TargetRegisterInfo::isVirtualRegister(AddendSrcReg)) + assert(LIS->getInterval(AddendSrcReg).liveAt(FMAIdx) && + "Addend source register is not available!"); // Transform: (O2 * O3) + O1 -> (O2 * O1) + O3. diff --git a/test/CodeGen/PowerPC/fma.ll b/test/CodeGen/PowerPC/fma.ll index 6bef3acf64b..270c141fa91 100644 --- a/test/CodeGen/PowerPC/fma.ll +++ b/test/CodeGen/PowerPC/fma.ll @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=ppc32 -fp-contract=fast | FileCheck %s +; RUN: llc < %s -march=ppc32 -fp-contract=fast -mattr=-vsx | FileCheck %s +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -fp-contract=fast -mattr=+vsx | FileCheck -check-prefix=CHECK-VSX %s declare double @dummy1(double) #0 declare double @dummy2(double, double) #0 @@ -11,6 +12,10 @@ define double @test_FMADD1(double %A, double %B, double %C) { ; CHECK-LABEL: test_FMADD1: ; CHECK: fmadd ; CHECK-NEXT: blr + +; CHECK-VSX-LABEL: test_FMADD1: +; CHECK-VSX: xsmaddmdp +; CHECK-VSX-NEXT: blr } define double @test_FMADD2(double %A, double %B, double %C) { @@ -20,6 +25,10 @@ define double @test_FMADD2(double %A, double %B, double %C) { ; CHECK-LABEL: test_FMADD2: ; CHECK: fmadd ; CHECK-NEXT: blr + +; CHECK-VSX-LABEL: test_FMADD2: +; CHECK-VSX: xsmaddmdp +; CHECK-VSX-NEXT: blr } define double @test_FMSUB1(double %A, double %B, double %C) { @@ -29,6 +38,10 @@ define double @test_FMSUB1(double %A, double %B, double %C) { ; CHECK-LABEL: test_FMSUB1: ; CHECK: fmsub ; CHECK-NEXT: blr + +; CHECK-VSX-LABEL: test_FMSUB1: +; CHECK-VSX: xsmsubmdp +; CHECK-VSX-NEXT: blr } define double @test_FMSUB2(double %A, double %B, double %C, double %D) { @@ -40,6 +53,10 @@ define double @test_FMSUB2(double %A, double %B, double %C, double %D) { ; CHECK-LABEL: test_FMSUB2: ; CHECK: fmadd ; CHECK-NEXT: fmsub + +; CHECK-VSX-LABEL: test_FMSUB2: +; CHECK-VSX: xsmaddadp +; CHECK-VSX-NEXT: xsmsubmdp } define double @test_FNMADD1(double %A, double %B, double %C) { @@ -50,6 +67,10 @@ define double @test_FNMADD1(double %A, double %B, double %C) { ; CHECK-LABEL: test_FNMADD1: ; CHECK: fnmadd ; CHECK-NEXT: blr + +; CHECK-VSX-LABEL: test_FNMADD1: +; CHECK-VSX: xsnmaddmdp +; CHECK-VSX-NEXT: blr } define double @test_FNMADD2(double %A, double %B, double %C) { @@ -60,6 +81,10 @@ define double @test_FNMADD2(double %A, double %B, double %C) { ; CHECK-LABEL: test_FNMADD2: ; CHECK: fnmadd ; CHECK-NEXT: blr + +; CHECK-VSX-LABEL: test_FNMADD2: +; CHECK-VSX: xsnmaddmdp +; CHECK-VSX-NEXT: blr } define double @test_FNMSUB1(double %A, double %B, double %C) { @@ -69,6 +94,9 @@ define double @test_FNMSUB1(double %A, double %B, double %C) { ; CHECK-LABEL: test_FNMSUB1: ; CHECK: fnmsub ; CHECK-NEXT: blr + +; CHECK-VSX-LABEL: test_FNMSUB1: +; CHECK-VSX: xsnmsubmdp } define double @test_FNMSUB2(double %A, double %B, double %C) { @@ -79,6 +107,10 @@ define double @test_FNMSUB2(double %A, double %B, double %C) { ; CHECK-LABEL: test_FNMSUB2: ; CHECK: fnmsub ; CHECK-NEXT: blr + +; CHECK-VSX-LABEL: test_FNMSUB2: +; CHECK-VSX: xsnmsubmdp +; CHECK-VSX-NEXT: blr } define float @test_FNMSUBS(float %A, float %B, float %C) { @@ -89,4 +121,8 @@ define float @test_FNMSUBS(float %A, float %B, float %C) { ; CHECK-LABEL: test_FNMSUBS: ; CHECK: fnmsubs ; CHECK-NEXT: blr + +; CHECK-VSX-LABEL: test_FNMSUBS: +; CHECK-VSX: fnmsubs +; CHECK-VSX-NEXT: blr } -- 2.34.1