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 {