From: Jingyue Wu Date: Tue, 11 Aug 2015 19:21:46 +0000 (+0000) Subject: SelectionDAG: Prefer to combine multiplication with less uses for fma X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d1ff8a7f6e7ff783a5096ef40f11397ebcf3a8f9;p=oota-llvm.git SelectionDAG: Prefer to combine multiplication with less uses for fma Summary: For example: s6 = s0*s5; s2 = s6*s6 + s6; ... s4 = s6*s3; We notice that it is possible for s2 is folded to fma (s0, s5, fmul (s6 s6)). This only happens when Aggressive is true, otherwise hasOneUse() check already prevents from folding the multiplication with more uses. Test Plan: test/CodeGen/NVPTX/fma-assoc.ll Patch by Xuetian Weng Reviewers: hfinkel, apazos, jingyue, ohsallen, arsenm Subscribers: arsenm, jholewinski, llvm-commits Differential Revision: http://reviews.llvm.org/D11855 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244649 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 2c87d120cb7..c4cbeb00766 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -7426,6 +7426,14 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) { bool Aggressive = TLI.enableAggressiveFMAFusion(VT); bool LookThroughFPExt = TLI.isFPExtFree(VT); + // If we have two choices trying to fold (fadd (fmul u, v), (fmul x, y)), + // prefer to fold the multiply with fewer uses. + if (Aggressive && N0.getOpcode() == ISD::FMUL && + N1.getOpcode() == ISD::FMUL) { + if (N0.getNode()->use_size() > N1.getNode()->use_size()) + std::swap(N0, N1); + } + // fold (fadd (fmul x, y), z) -> (fma x, y, z) if (N0.getOpcode() == ISD::FMUL && (Aggressive || N0->hasOneUse())) { diff --git a/test/CodeGen/NVPTX/fma-assoc.ll b/test/CodeGen/NVPTX/fma-assoc.ll index fc04c61dd69..80a08a86316 100644 --- a/test/CodeGen/NVPTX/fma-assoc.ll +++ b/test/CodeGen/NVPTX/fma-assoc.ll @@ -23,3 +23,16 @@ define ptx_device double @t1_f64(double %x, double %y, double %z, %d = fadd double %c, %z ret double %d } + +define double @two_choices(double %val1, double %val2) { +; CHECK-LABEL: two_choices( +; CHECK: mul.f64 +; CHECK-NOT: mul.f64 +; CHECK: fma.rn.f64 + %1 = fmul double %val1, %val2 + %2 = fmul double %1, %1 + %3 = fadd double %1, %2 + + ret double %3 +} +