This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR78413
- From: Bill Schmidt <wschmidt at linux dot vnet dot ibm dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Richard Biener <richard dot guenther at gmail dot com>
- Date: Fri, 18 Nov 2016 10:27:29 -0600
- Subject: [PATCH] Fix PR78413
- Authentication-results: sourceware.org; auth=none
Hi,
The if-conversion patch for PR77848 missed a case where an outer loop
should not be versioned for vectorization; this was caught by an assert
in tests recorded in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78413.
This patch fixes the problem by ensuring that both inner and outer loop
latches have a single predecessor before versioning an outer loop.
Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
regressions. Is this ok for trunk?
Thanks,
Bill
[gcc]
2016-11-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR tree-optimization/78413
* tree-if-conv.c (versionable_outer_loop_p): Require that both
inner and outer loop latches have single predecessors.
[gcc/testsuite]
2016-11-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR tree-optimization/78413
* gcc.dg/tree-ssa/pr78413.c: New test.
Index: gcc/testsuite/gcc.dg/tree-ssa/pr78413.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr78413.c (revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr78413.c (working copy)
@@ -0,0 +1,35 @@
+/* PR78413. These previously failed in tree if-conversion due to a loop
+ latch with multiple predecessors that the code did not anticipate. */
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math" } */
+
+extern long long int llrint(double x);
+int a;
+double b;
+__attribute__((cold)) void decode_init() {
+ int c, d = 0;
+ for (; d < 12; d++) {
+ if (d)
+ b = 0;
+ c = 0;
+ for (; c < 6; c++)
+ a = b ? llrint(b) : 0;
+ }
+}
+
+struct S {
+ _Bool bo;
+};
+int a, bb, c, d;
+void fn1() {
+ do
+ do
+ do {
+ struct S *e = (struct S *)1;
+ do
+ bb = a / (e->bo ? 2 : 1);
+ while (bb);
+ } while (0);
+ while (d);
+ while (c);
+}
Index: gcc/tree-if-conv.c
===================================================================
--- gcc/tree-if-conv.c (revision 242551)
+++ gcc/tree-if-conv.c (working copy)
@@ -2575,6 +2575,8 @@ version_loop_for_if_conversion (struct loop *loop)
- The loop has a single exit.
- The loop header has a single successor, which is the inner
loop header.
+ - Each of the inner and outer loop latches have a single
+ predecessor.
- The loop exit block has a single predecessor, which is the
inner loop's exit block. */
@@ -2586,7 +2588,9 @@ versionable_outer_loop_p (struct loop *loop)
|| loop->inner->next
|| !single_exit (loop)
|| !single_succ_p (loop->header)
- || single_succ (loop->header) != loop->inner->header)
+ || single_succ (loop->header) != loop->inner->header
+ || !single_pred_p (loop->latch)
+ || !single_pred_p (loop->inner->latch))
return false;
basic_block outer_exit = single_pred (loop->latch);