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

llvm-svn: 244649
This commit is contained in:
Jingyue Wu 2015-08-11 19:21:46 +00:00
parent 7752db61cc
commit 99eb4685ef
2 changed files with 21 additions and 0 deletions

View File

@ -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())) {

View File

@ -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
}