From 01bc5f275b3dab47d9a094947de3f49719ba0f8b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 17 Mar 2014 14:38:55 +0000 Subject: [PATCH] backport: [multiple changes] 2014-03-17 Richard Biener Backport from mainline 2013-05-21 Richard Biener PR tree-optimization/57303 * tree-ssa-sink.c (statement_sink_location): Properly handle self-assignments. * gcc.dg/torture/pr57303.c: New testcase. 2013-12-02 Richard Biener PR tree-optimization/59139 * tree-ssa-loop-niter.c (chain_of_csts_start): Properly match code in get_val_for. (get_val_for): Use gcc_checking_asserts. * gcc.dg/torture/pr59139.c: New testcase. 2014-02-14 Richard Biener PR tree-optimization/60183 * tree-ssa-phiprop.c (propagate_with_phi): Avoid speculating loads. (tree_ssa_phiprop): Calculate and free post-dominators. * gcc.dg/torture/pr60183.c: New testcase. From-SVN: r208618 --- gcc/ChangeLog | 23 +++++++++++++++ gcc/testsuite/ChangeLog | 18 ++++++++++++ gcc/testsuite/gcc.dg/torture/pr57303.c | 33 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr59139.c | 20 +++++++++++++ gcc/testsuite/gcc.dg/torture/pr60183.c | 39 ++++++++++++++++++++++++++ gcc/tree-ssa-loop-niter.c | 7 +++-- gcc/tree-ssa-phiprop.c | 9 ++++++ gcc/tree-ssa-sink.c | 10 ++++++- 8 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr57303.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr59139.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr60183.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73d19db37753..974814a0dbbf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2014-03-17 Richard Biener + + Backport from mainline + 2013-05-21 Richard Biener + + PR tree-optimization/57303 + * tree-ssa-sink.c (statement_sink_location): Properly handle + self-assignments. + + 2013-12-02 Richard Biener + + PR tree-optimization/59139 + * tree-ssa-loop-niter.c (chain_of_csts_start): Properly match + code in get_val_for. + (get_val_for): Use gcc_checking_asserts. + + 2014-02-14 Richard Biener + + PR tree-optimization/60183 + * tree-ssa-phiprop.c (propagate_with_phi): Avoid speculating + loads. + (tree_ssa_phiprop): Calculate and free post-dominators. + 2014-03-14 Georg-Johann Lay Backport from 2014-03-14 trunk r208562. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ca7f17992026..2cd6e12618f0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2014-03-17 Richard Biener + + Backport from mainline + 2013-05-21 Richard Biener + + PR tree-optimization/57303 + * gcc.dg/torture/pr57303.c: New testcase. + + 2013-12-02 Richard Biener + + PR tree-optimization/59139 + * gcc.dg/torture/pr59139.c: New testcase. + + 2014-02-14 Richard Biener + + PR tree-optimization/60183 + * gcc.dg/torture/pr60183.c: New testcase. + 2014-03-15 Jerry DeLisle Backport from mainline diff --git a/gcc/testsuite/gcc.dg/torture/pr57303.c b/gcc/testsuite/gcc.dg/torture/pr57303.c new file mode 100644 index 000000000000..1ddb5a8aab34 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57303.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ + +void abort (void); + +struct S0 +{ + int f0; +}; +struct S1 +{ + struct S0 f0; +}; + +struct S1 x = { {0} }; +struct S1 y = { {1} }; + +static void +foo (struct S0 p) +{ + struct S0 *l = &y.f0; + *l = x.f0; + if (p.f0) + *l = *l; +} + +int +main () +{ + foo(y.f0); + if (y.f0.f0 != 0) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr59139.c b/gcc/testsuite/gcc.dg/torture/pr59139.c new file mode 100644 index 000000000000..4ec9177ffe73 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr59139.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +int a, b, c, d, e; +int fn1(p1, p2) { return p2 == 0 ? p1 : 1 % p2; } + +void fn2() +{ + c = 0; + for (;; c = (unsigned short)c) + { + b = 2; + for (; b; b = a) + { + e = fn1(2, c && 1); + d = c == 0 ? e : c; + if (d) + return; + } + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr60183.c b/gcc/testsuite/gcc.dg/torture/pr60183.c new file mode 100644 index 000000000000..3f676637ba8c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr60183.c @@ -0,0 +1,39 @@ +/* { dg-do run } */ +/* { dg-require-effective-target size32plus } */ + +/* Large so an out-of-bound read will crash. */ +unsigned char c[0x30001] = { 1 }; +int j = 2; + +static void +foo (unsigned long *x, unsigned char *y) +{ + int i; + unsigned long w = x[0]; + for (i = 0; i < j; i++) + { + w += *y; + y += 0x10000; + w += *y; + y += 0x10000; + } + x[1] = w; +} + +__attribute__ ((noinline, noclone)) void +bar (unsigned long *x) +{ + foo (x, c); +} + +int +main () +{ + unsigned long a[2] = { 0, -1UL }; + asm volatile (""::"r" (c):"memory"); + c[0] = 0; + bar (a); + if (a[1] != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 15ea06b8b9bd..9c02122295f5 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -2068,7 +2068,8 @@ chain_of_csts_start (struct loop *loop, tree x) return NULL; } - if (gimple_code (stmt) != GIMPLE_ASSIGN) + if (gimple_code (stmt) != GIMPLE_ASSIGN + || gimple_assign_rhs_class (stmt) == GIMPLE_TERNARY_RHS) return NULL; code = gimple_assign_rhs_code (stmt); @@ -2136,7 +2137,7 @@ get_val_for (tree x, tree base) { gimple stmt; - gcc_assert (is_gimple_min_invariant (base)); + gcc_checking_assert (is_gimple_min_invariant (base)); if (!x) return base; @@ -2145,7 +2146,7 @@ get_val_for (tree x, tree base) if (gimple_code (stmt) == GIMPLE_PHI) return base; - gcc_assert (is_gimple_assign (stmt)); + gcc_checking_assert (is_gimple_assign (stmt)); /* STMT must be either an assignment of a single SSA name or an expression involving an SSA name and a constant. Try to fold that diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c index 306443725644..7dd94a4f5667 100644 --- a/gcc/tree-ssa-phiprop.c +++ b/gcc/tree-ssa-phiprop.c @@ -314,6 +314,12 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn, gimple def_stmt; tree vuse; + /* Only replace loads in blocks that post-dominate the PHI node. That + makes sure we don't end up speculating loads. */ + if (!dominated_by_p (CDI_POST_DOMINATORS, + bb, gimple_bb (use_stmt))) + continue; + /* Check whether this is a load of *ptr. */ if (!(is_gimple_assign (use_stmt) && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME @@ -385,6 +391,7 @@ tree_ssa_phiprop (void) size_t n; calculate_dominance_info (CDI_DOMINATORS); + calculate_dominance_info (CDI_POST_DOMINATORS); n = num_ssa_names; phivn = XCNEWVEC (struct phiprop_d, n); @@ -402,6 +409,8 @@ tree_ssa_phiprop (void) VEC_free (basic_block, heap, bbs); free (phivn); + free_dominance_info (CDI_POST_DOMINATORS); + return 0; } diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c index d42b46a18013..19cacfc56eaa 100644 --- a/gcc/tree-ssa-sink.c +++ b/gcc/tree-ssa-sink.c @@ -412,7 +412,15 @@ statement_sink_location (gimple stmt, basic_block frombb, && gimple_vdef (use_stmt) && operand_equal_p (gimple_assign_lhs (stmt), gimple_assign_lhs (use_stmt), 0)) - continue; + { + /* If use_stmt is or might be a nop assignment then USE_STMT + acts as a use as well as definition. */ + if (stmt != use_stmt + && ref_maybe_used_by_stmt_p (use_stmt, + gimple_assign_lhs (stmt))) + return false; + continue; + } if (gimple_code (use_stmt) != GIMPLE_PHI) return false; -- 2.47.2