Make FMA code cope with redundant negates (PR89956)
This patch fixes a case in which, due to forced missed optimisations in earlier passes, we have: _1 = a * b _2 = -_1 _3 = -_1 _4 = _2 + _3 and treated _4 as two FNMA candidates, once via _2 and once via _3. 2019-04-05 Richard Sandiford <richard.sandiford@arm.com> gcc/ PR tree-optimization/89956 * tree-ssa-math-opts.c (convert_mult_to_fma): Protect against multiple negates of the same value. gcc/testsuite/ PR tree-optimization/89956 * gfortran.dg/pr89956.f90: New test. From-SVN: r270162
This commit is contained in:
parent
ce36ba09fe
commit
8d6b13da61
@ -1,3 +1,9 @@
|
||||
2019-04-05 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
PR tree-optimization/89956
|
||||
* tree-ssa-math-opts.c (convert_mult_to_fma): Protect against
|
||||
multiple negates of the same value.
|
||||
|
||||
2019-04-04 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR middle-end/89957
|
||||
|
@ -1,3 +1,8 @@
|
||||
2019-04-05 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
PR tree-optimization/89956
|
||||
* gfortran.dg/pr89956.f90: New test.
|
||||
|
||||
2019-04-04 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/89974
|
||||
|
16
gcc/testsuite/gfortran.dg/pr89956.f90
Normal file
16
gcc/testsuite/gfortran.dg/pr89956.f90
Normal file
@ -0,0 +1,16 @@
|
||||
! { dg-options "-O3 -fno-tree-forwprop -fno-tree-pre -fno-tree-dominator-opts -fno-code-hoisting -ffast-math" }
|
||||
|
||||
module de
|
||||
contains
|
||||
function zu (az, xx) result (q3)
|
||||
real :: az, xx, q3
|
||||
|
||||
q3 = 1.0 - lz (az, xx) - lz (xx, az)
|
||||
end function zu
|
||||
|
||||
function lz (ho, gh) result (ye)
|
||||
real :: ho, gh, ye
|
||||
|
||||
ye = sqrt (ho) - ho * gh
|
||||
end function lz
|
||||
end module de
|
@ -3094,6 +3094,7 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
|
||||
&& (tree_to_shwi (TYPE_SIZE (type))
|
||||
<= PARAM_VALUE (PARAM_AVOID_FMA_MAX_BITS)));
|
||||
bool defer = check_defer;
|
||||
bool seen_negate_p = false;
|
||||
/* Make sure that the multiplication statement becomes dead after
|
||||
the transformation, thus that all uses are transformed to FMAs.
|
||||
This means we assume that an FMA operation has the same cost
|
||||
@ -3127,6 +3128,12 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
|
||||
ssa_op_iter iter;
|
||||
use_operand_p usep;
|
||||
|
||||
/* If (due to earlier missed optimizations) we have two
|
||||
negates of the same value, treat them as equivalent
|
||||
to a single negate with multiple uses. */
|
||||
if (seen_negate_p)
|
||||
return false;
|
||||
|
||||
result = gimple_assign_lhs (use_stmt);
|
||||
|
||||
/* Make sure the negate statement becomes dead with this
|
||||
@ -3145,7 +3152,7 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
|
||||
if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
|
||||
return false;
|
||||
|
||||
negate_p = true;
|
||||
negate_p = seen_negate_p = true;
|
||||
}
|
||||
|
||||
tree cond, else_value, ops[3];
|
||||
|
Loading…
Reference in New Issue
Block a user