diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c new file mode 100644 index 0000000000000000000000000000000000000000..903fe7be6621e81db6f29441e4309fa213d027c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-add-options vect_early_break } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ + +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */ + +long tar_atol256_max, tar_atol256_size, tar_atosl_min; +char tar_atol256_s; +void __errno_location(); + + +inline static long tar_atol256(long min) { + char c; + int sign; + c = tar_atol256_s; + sign = c; + while (tar_atol256_size) { + if (c != sign) + return sign ? min : tar_atol256_max; + c = tar_atol256_size--; + } + if ((c & 128) != (sign & 128)) + return sign ? min : tar_atol256_max; + return 0; +} + +inline static long tar_atol(long min) { + return tar_atol256(min); +} + +long tar_atosl() { + long n = tar_atol(-1); + if (tar_atosl_min) { + __errno_location(); + return 0; + } + if (n > 0) + return 0; + return n; +} diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index 1066ea17c5674e03412b3dcd8a62ddf4dd54cf31..3810983a80c8b989be9fd9a9993642069fd39b99 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -1716,8 +1716,6 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, /* Now link the alternative exits. */ if (multiple_exits_p) { - set_immediate_dominator (CDI_DOMINATORS, new_preheader, - main_loop_exit_block); for (auto gsi_from = gsi_start_phis (loop->header), gsi_to = gsi_start_phis (new_preheader); !gsi_end_p (gsi_from) && !gsi_end_p (gsi_to); @@ -1751,12 +1749,26 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit, /* Finally after wiring the new epilogue we need to update its main exit to the original function exit we recorded. Other exits are already - correct. */ + correct. Because of versioning, skip vectors and others we must update + the dominators of every node reachable by the new exits. */ if (multiple_exits_p) { update_loop = new_loop; - for (edge e : get_loop_exit_edges (loop)) - doms.safe_push (e->dest); + hash_set visited; + auto_vec workset; + edge ev; + edge_iterator ei; + workset.safe_splice (get_loop_exit_edges (loop)); + while (!workset.is_empty ()) + { + auto bb = workset.pop ()->dest; + if (visited.add (bb)) + continue; + doms.safe_push (bb); + FOR_EACH_EDGE (ev, ei, bb->succs) + workset.safe_push (ev); + } + visited.empty (); doms.safe_push (exit_dest); /* Likely a fall-through edge, so update if needed. */