https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80304

--- Comment #22 from Chinoune <chinoune.mehdi at hotmail dot com> ---
Created attachment 41163
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41163&action=edit
the test program in c

This is an equivalent program written in c.

--- Comment #23 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue is that safelen (and IVDEP, as that uses safelen) is quite aggressive
and does not only apply to what is "memory" in the language specific sense but
also to what ends up as memory to the middle-end.  In this case dependencies
of the not inlined add2 calls which get i and j by reference are not accounted
for which makes i and j suitable to store-motion.

Now all would be fine but the call arguments are not updated by store-motion.

So using IVDEP on loops with calls with reference passing is dangerous.

There's still one bug in LIM, namely it fails to recurse to handle
UNANALYZABLE_MEM_ID for safelen.  The following testcase fixes the
last testcase.

Index: gcc/tree-ssa-loop-im.c
===================================================================
--- gcc/tree-ssa-loop-im.c      (revision 246797)
+++ gcc/tree-ssa-loop-im.c      (working copy)
@@ -2145,9 +2145,21 @@ ref_indep_loop_p_1 (int safelen, struct
          fprintf (dump_file, "\n");
        }

+      /* We need to recurse to properly handle UNANALYZABLE_MEM_ID.  */
+      struct loop *inner = loop->inner;
+      while (inner)
+       {
+         if (!ref_indep_loop_p_1 (safelen, inner, ref, stored_p, ref_loop))
+           {
+             indep_p = false;
+             break;
+           }
+         inner = inner->next;
+       }
+
       /* Avoid caching here as safelen depends on context and refs
          are shared between different contexts.  */
-      return true;
+      return indep_p;
     }
   else
     {

Reply via email to