diff --git a/gcc/testsuite/gcc.dg/torture/pr103237.c b/gcc/testsuite/gcc.dg/torture/pr103237.c new file mode 100644 index 00000000000..f2399f9586e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr103237.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ftree-vectorize" } */ + +int g1; +unsigned int g2 = -1U; +static void __attribute__((noipa)) +func_1() +{ + int *l_1 = &g1; + for (int g3a = 0; g3a != 4; g3a++) + for (int l_2 = 0; l_2 <= 3; l_2++) + { + unsigned int *l_3 = &g2; + *l_1 = *l_3 ^= 1; + } +} +int +main() +{ + func_1(); + if (g1 != -1) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 1cd5dbcb6f7..73efdb96bad 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -3567,6 +3567,17 @@ vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info, return def_stmt_info; } + /* When the inner loop of a double reduction ends up with more than + one loop-closed PHI we have failed to classify alternate such + PHIs as double reduction, leading to wrong code. See PR103237. */ + if (inner_loop_of_double_reduc && lcphis.length () != 1) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "unhandle double reduction\n"); + return NULL; + } + /* If this isn't a nested cycle or if the nested cycle reduction value is used ouside of the inner loop we cannot handle uses of the reduction value. */