diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cfgcleanup.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr89634.c | 40 |
4 files changed, 56 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 564ad3e..5cac152 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-03-09 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/89634 + * cfgcleanup.c (thread_jump): Punt if registers mentioned in cond1 + are modified in BB_END (e->src) instruction. + 2019-03-08 David Malcolm <dmalcolm@redhat.com> PR target/79926 diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index fd27fd6..86b2627 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -308,6 +308,11 @@ thread_jump (edge e, basic_block b) || !rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1))) return NULL; + /* Punt if BB_END (e->src) is doloop-like conditional jump that modifies + the registers used in cond1. */ + if (modified_in_p (cond1, BB_END (e->src))) + return NULL; + /* Short circuit cases where block B contains some side effects, as we can't safely bypass it. */ for (insn = NEXT_INSN (BB_HEAD (b)); insn != NEXT_INSN (BB_END (b)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 02f2482..f32b5af 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-03-09 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/89634 + * gcc.c-torture/execute/pr89634.c: New test. + 2019-03-08 Jakub Jelinek <jakub@redhat.com> PR c/85870 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr89634.c b/gcc/testsuite/gcc.c-torture/execute/pr89634.c new file mode 100644 index 0000000..b633e61 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr89634.c @@ -0,0 +1,40 @@ +/* PR rtl-optimization/89634 */ + +static unsigned long * +foo (unsigned long *x) +{ + return x + (1 + *x); +} + +__attribute__((noipa)) unsigned long +bar (unsigned long *x) +{ + unsigned long c, d = 1, e, *f, g, h = 0, i; + for (e = *x - 1; e > 0; e--) + { + f = foo (x + 1); + for (i = 1; i < e; i++) + f = foo (f); + c = *f; + if (c == 2) + d *= 2; + else + { + i = (c - 1) / 2 - 1; + g = (2 * i + 1) * (d + 1) + (2 * d + 1); + if (g > h) + h = g; + d *= c; + } + } + return h; +} + +int +main () +{ + unsigned long a[18] = { 4, 2, -200, 200, 2, -400, 400, 3, -600, 0, 600, 5, -100, -66, 0, 66, 100, __LONG_MAX__ / 8 + 1 }; + if (bar (a) != 17) + __builtin_abort (); + return 0; +} |