http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47559
Richard Guenther <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |wrong-code Status|UNCONFIRMED |NEW Last reconfirmed| |2011.02.01 12:03:49 CC| |rakdver at gcc dot gnu.org Component|middle-end |tree-optimization Ever Confirmed|0 |1 --- Comment #1 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-02-01 12:03:49 UTC --- LIM produces void foo(int*) (int * k) Eh tree: 1 must_not_throw { int k__lsm.1; <bb 2>: k__lsm.1_4 = MEM[(int *)k_1(D)]; <bb 3>: [MNT 1] k__lsm.1_5 = 0; <bb 4>: goto <bb 3>; } failing to move the EH info. I think it should just give up here - it tries to, but only if loop exits via EH edges appear - which is not the case for must-not-throw. There is also no exit in that endless loop anyway - which shows the transform isn't valid as if *k points to readonly memory the testcase now will fail to trap as the store never happens. Which means this is wrong-code as well (should we simply not do store-motion for loops without exits?). Thus, the following would fix the wrong-code issue (but probably not the ICE in a more generalized test): Index: gcc/tree-ssa-loop-im.c =================================================================== --- gcc/tree-ssa-loop-im.c (revision 169434) +++ gcc/tree-ssa-loop-im.c (working copy) @@ -2368,6 +2368,9 @@ loop_suitable_for_sm (struct loop *loop unsigned i; edge ex; + if (VEC_empty (edge, exits)) + return false; + FOR_EACH_VEC_ELT (edge, exits, i, ex) if (ex->flags & (EDGE_ABNORMAL | EDGE_EH)) return false; I am testing that change now.