http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52091
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|ASSIGNED |NEW CC| |irar at gcc dot gnu.org AssignedTo|jakub at gcc dot gnu.org |unassigned at gcc dot | |gnu.org --- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-02-02 12:06:27 UTC --- Executable testcase: /* PR tree-optimization/52091 */ int b, c, d, f; unsigned h; extern void abort (void); int main () { d = -1; h = 65; asm volatile ("" : : : "memory"); for (f = 0; f < 4; f++) { h &= (unsigned short) d; for (b = 0; b <= 1; b++) { c = 0; d &= 1; } } asm volatile ("" : : : "memory"); if (b != 2 || c != 0 || d != 1 || f != 4 || h != 1) abort (); return 0; } Following patch fixes the ICE: --- gcc/tree-vect-stmts.c.jj 2012-02-01 10:33:58.000000000 +0100 +++ gcc/tree-vect-stmts.c 2012-02-02 11:50:42.623948066 +0100 @@ -1294,7 +1294,11 @@ vect_get_vec_def_for_operand (tree op, g /* Get the def before the loop */ op = PHI_ARG_DEF_FROM_EDGE (def_stmt, loop_preheader_edge (loop)); - return get_initial_def_for_reduction (stmt, op, scalar_def); + vec_oprnd = get_initial_def_for_reduction (stmt, op, scalar_def); + if (!is_gimple_val (vec_oprnd)) + vec_oprnd = vect_init_vector (stmt, vec_oprnd, + TREE_TYPE (vec_oprnd), NULL); + return vec_oprnd; } /* Case 5: operand is defined by loop-header phi - induction. */ but just turns ice-on-valid-code into wrong-code, h is 65 when vectorizing. Ira, could you please look at this? Thanks. OT, it is strange that we are creating a reduction for a loop which loops exactly as many times as there are units in the vector, that doesn't seem to be profitable. My other attempt to fix the ICE was: --- gcc/tree-vect-loop.c.jj 2011-12-16 08:37:45.000000000 +0100 +++ gcc/tree-vect-loop.c 2012-02-02 11:57:25.354607843 +0100 @@ -3370,7 +3370,10 @@ get_initial_def_for_reduction (gimple st if (TREE_CONSTANT (init_val)) init_def = build_vector (vectype, t); else - init_def = build_constructor_from_list (vectype, t); + { + init_def = build_constructor_from_list (vectype, t); + init_def = vect_init_vector (stmt, init_def, vectype, NULL); + } break; but that ICEs on the testcase, because the other caller of get_initial_def_for_reduction is calling vect_init_vector immediately after it, with a different stmt than was passed to get_initial_def_for_reduction, and this resulted in definition not dominating the use. Wonder if that isn't another bug.