aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-06-07 10:10:00 +0000
committerRichard Biener <rguenther@suse.de>2018-06-07 10:10:00 +0000
commita72ac91b71c91ec22f27720d84ab1627b0eedb5c (patch)
tree48a11bc3b8facdf71382d80a612b2781b0a6a383
parent345786faaf664bc5fcd10301078b9b6967c359a1 (diff)
2018-06-07 Richard Biener <rguenther@suse.de>
Backport from mainline 2018-05-04 Richard Biener <rguenther@suse.de> PR middle-end/85588 * fold-const.c (negate_expr_p): Restrict negation of operand zero of a division to when we know that can happen without overflow. (fold_negate_expr_1): Likewise. * gcc.dg/torture/pr85588.c: New testcase. * gcc.dg/torture/pr57656.c: Use dg-additional-options. 2018-05-02 Richard Biener <rguenther@suse.de> PR middle-end/85567 * gimplify.c (gimplify_save_expr): When in SSA form allow SAVE_EXPRs to compute to SSA vars. * gcc.dg/torture/pr85567.c: New testcase. 2018-05-02 Richard Biener <rguenther@suse.de> PR tree-optimization/85597 * tree-vect-stmts.c (vectorizable_operation): For ternary SLP do not use split vect_get_vec_defs call but call vect_get_slp_defs directly. * gcc.dg/vect/pr85597.c: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@261269 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/fold-const.c14
-rw-r--r--gcc/gimplify.c7
-rw-r--r--gcc/testsuite/ChangeLog19
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57656.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr85567.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr85588.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr85597.c26
-rw-r--r--gcc/tree-vect-stmts.c27
9 files changed, 128 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 534bc9b91af..2f52cbcae0d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2018-06-07 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2018-05-04 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/85588
+ * fold-const.c (negate_expr_p): Restrict negation of operand
+ zero of a division to when we know that can happen without
+ overflow.
+ (fold_negate_expr_1): Likewise.
+
+ 2018-05-02 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/85567
+ * gimplify.c (gimplify_save_expr): When in SSA form allow
+ SAVE_EXPRs to compute to SSA vars.
+
+ 2018-05-02 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/85597
+ * tree-vect-stmts.c (vectorizable_operation): For ternary SLP
+ do not use split vect_get_vec_defs call but call vect_get_slp_defs
+ directly.
+
2018-06-05 Andreas Krebbel <krebbel@linux.ibm.com>
Backport from mainline
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0781f4212b7..8e1b0623763 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -473,12 +473,15 @@ negate_expr_p (tree t)
case EXACT_DIV_EXPR:
if (TYPE_UNSIGNED (type))
break;
- if (negate_expr_p (TREE_OPERAND (t, 0)))
+ /* In general we can't negate A in A / B, because if A is INT_MIN and
+ B is not 1 we change the sign of the result. */
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
+ && negate_expr_p (TREE_OPERAND (t, 0)))
return true;
/* In general we can't negate B in A / B, because if A is INT_MIN and
B is 1, we may turn this into INT_MIN / -1 which is undefined
and actually traps on some architectures. */
- if (! INTEGRAL_TYPE_P (TREE_TYPE (t))
+ if (! ANY_INTEGRAL_TYPE_P (TREE_TYPE (t))
|| TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
|| (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
&& ! integer_onep (TREE_OPERAND (t, 1))))
@@ -652,14 +655,17 @@ fold_negate_expr_1 (location_t loc, tree t)
case EXACT_DIV_EXPR:
if (TYPE_UNSIGNED (type))
break;
- if (negate_expr_p (TREE_OPERAND (t, 0)))
+ /* In general we can't negate A in A / B, because if A is INT_MIN and
+ B is not 1 we change the sign of the result. */
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
+ && negate_expr_p (TREE_OPERAND (t, 0)))
return fold_build2_loc (loc, TREE_CODE (t), type,
negate_expr (TREE_OPERAND (t, 0)),
TREE_OPERAND (t, 1));
/* In general we can't negate B in A / B, because if A is INT_MIN and
B is 1, we may turn this into INT_MIN / -1 which is undefined
and actually traps on some architectures. */
- if ((! INTEGRAL_TYPE_P (TREE_TYPE (t))
+ if ((! ANY_INTEGRAL_TYPE_P (TREE_TYPE (t))
|| TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
|| (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
&& ! integer_onep (TREE_OPERAND (t, 1))))
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 15fc7c9ae8f..5535604d837 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -5773,8 +5773,11 @@ gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
}
else
/* The temporary may not be an SSA name as later abnormal and EH
- control flow may invalidate use/def domination. */
- val = get_initialized_tmp_var (val, pre_p, post_p, false);
+ control flow may invalidate use/def domination. When in SSA
+ form then assume there are no such issues and SAVE_EXPRs only
+ appear via GENERIC foldings. */
+ val = get_initialized_tmp_var (val, pre_p, post_p,
+ gimple_in_ssa_p (cfun));
TREE_OPERAND (*expr_p, 0) = val;
SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7a8d45f2381..df89b1f06c9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,22 @@
+2018-06-07 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2018-05-04 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/85588
+ * gcc.dg/torture/pr85588.c: New testcase.
+ * gcc.dg/torture/pr57656.c: Use dg-additional-options.
+
+ 2018-05-02 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/85567
+ * gcc.dg/torture/pr85567.c: New testcase.
+
+ 2018-05-02 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/85597
+ * gcc.dg/vect/pr85597.c: New testcase.
+
2018-06-05 Andreas Krebbel <krebbel@linux.ibm.com>
Backport from mainline
diff --git a/gcc/testsuite/gcc.dg/torture/pr57656.c b/gcc/testsuite/gcc.dg/torture/pr57656.c
index 4f3645e4693..02490140105 100644
--- a/gcc/testsuite/gcc.dg/torture/pr57656.c
+++ b/gcc/testsuite/gcc.dg/torture/pr57656.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-fstrict-overflow" } */
+/* { dg-additional-options "-fstrict-overflow" } */
int main (void)
{
diff --git a/gcc/testsuite/gcc.dg/torture/pr85567.c b/gcc/testsuite/gcc.dg/torture/pr85567.c
new file mode 100644
index 00000000000..f20c69f4201
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr85567.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+extern void sincos(double x, double *sinx, double *cosx);
+
+void apply(void (*f)(double, double *, double *),
+ double x, double *sinx, double *cosx)
+{
+ f(x, sinx, cosx);
+ return;
+}
+
+void apply_sincos(double x, double *sinx, double *cosx)
+{
+ apply(sincos, x, sinx, cosx);
+ return;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr85588.c b/gcc/testsuite/gcc.dg/torture/pr85588.c
new file mode 100644
index 00000000000..5d95c96bc35
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr85588.c
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fwrapv" } */
+
+#include "pr57656.c"
diff --git a/gcc/testsuite/gcc.dg/vect/pr85597.c b/gcc/testsuite/gcc.dg/vect/pr85597.c
new file mode 100644
index 00000000000..cf615f9c464
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr85597.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-additional-options "-mfma" { target { x86_64-*-* i?86-*-* } } } */
+
+extern double fma (double, double, double);
+
+static inline void
+bar (int i, double *D, double *S)
+{
+ while (i-- > 0)
+ {
+ D[0] = fma (1, S[0], D[0]);
+ D[1] = fma (1, S[1], D[1]);
+ D[2] = fma (1, S[2], D[2]);
+ D[3] = fma (1, S[3], D[3]);
+ D += 4;
+ S += 4;
+ }
+}
+
+void
+foo (double *d, double *s)
+{
+ bar (10, d, s);
+}
+
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index b5601727c53..04237dbb9fe 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -5479,15 +5479,34 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
/* Handle uses. */
if (j == 0)
{
- if (op_type == binary_op || op_type == ternary_op)
+ if (op_type == binary_op)
vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1,
slp_node, -1);
+ else if (op_type == ternary_op)
+ {
+ if (slp_node)
+ {
+ auto_vec<tree> ops(3);
+ ops.quick_push (op0);
+ ops.quick_push (op1);
+ ops.quick_push (op2);
+ auto_vec<vec<tree> > vec_defs(3);
+ vect_get_slp_defs (ops, slp_node, &vec_defs, -1);
+ vec_oprnds0 = vec_defs[0];
+ vec_oprnds1 = vec_defs[1];
+ vec_oprnds2 = vec_defs[2];
+ }
+ else
+ {
+ vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1,
+ NULL, -1);
+ vect_get_vec_defs (op2, NULL_TREE, stmt, &vec_oprnds2, NULL,
+ NULL, -1);
+ }
+ }
else
vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
slp_node, -1);
- if (op_type == ternary_op)
- vect_get_vec_defs (op2, NULL_TREE, stmt, &vec_oprnds2, NULL,
- slp_node, -1);
}
else
{