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.

Reply via email to