]> granicus.if.org Git - llvm/commit
[DAGCombiner] do not fold (fmul (fadd X, 1), Y) -> (fmad X, Y, Y) by default
authorNicolai Haehnle <nhaehnle@gmail.com>
Fri, 2 Dec 2016 16:06:18 +0000 (16:06 +0000)
committerNicolai Haehnle <nhaehnle@gmail.com>
Fri, 2 Dec 2016 16:06:18 +0000 (16:06 +0000)
commit42285f5cb739b1e2433fa9cd6e762ab77be87b80
tree6a2d7d6609e661c16a3205e419da172d1541e003
parent7ac6b09c0fc5312f928b849b7763d4cbfad0c993
[DAGCombiner] do not fold (fmul (fadd X, 1), Y) -> (fmad X, Y, Y) by default

Summary:
When X = 0 and Y = inf, the original code produces inf, but the transformed
code produces nan. So this transform (and its relatives) should only be
used when the no-infs-fp-math flag is explicitly enabled.

Also disable the transform using fmad (intermediate rounding) when unsafe-math
is not enabled, since it can reduce the precision of the result; consider this
example with binary floating point numbers with two bits of mantissa:

  x = 1.01
  y = 111

  x * (y + 1) = 1.01 * 1000 = 1010 (this is the exact result; no rounding occurs at any step)

  x * y + x = 1000.11 + 1.01 =r 1000 + 1.01 = 1001.01 =r 1000 (with rounding towards zero)

The example relies on rounding towards zero at least in the second step.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98578

Reviewers: RKSimon, tstellarAMD, spatel, arsenm

Subscribers: wdng, llvm-commits

Differential Revision: https://reviews.llvm.org/D26602

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288506 91177308-0d34-0410-b5e6-96231b3b80d8
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
test/CodeGen/AMDGPU/fma-combine.ll
test/CodeGen/X86/fma_patterns.ll
test/CodeGen/X86/fma_patterns_wide.ll