aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/pr89956.f9016
-rw-r--r--gcc/tree-ssa-math-opts.c9
4 files changed, 35 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4e17249..c4693bf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 26c5637..af77f02 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gfortran.dg/pr89956.f90 b/gcc/testsuite/gfortran.dg/pr89956.f90
new file mode 100644
index 0000000..f850afd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr89956.f90
@@ -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
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 8902d85..1496520 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -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];