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

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
```
      /* To simplify debugging, compare IPA and local solutions.  */
      if (past_flags_known && summary)
        {
          size_t len = summary->arg_flags.length ();

          if (past_flags.length () > len)
            len = past_flags.length ();
          for (size_t i = 0; i < len; i++)
            {
              int old_flags = i < past_flags.length () ? past_flags[i] : 0;
              int new_flags = i < summary->arg_flags.length ()
                              ? summary->arg_flags[i] : 0;
              old_flags = remove_useless_eaf_flags
                (old_flags, flags_from_decl_or_type (current_function_decl),
                 VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
              if (old_flags != new_flags)
                {
                  if ((old_flags & ~new_flags) == 0
                      || (new_flags & EAF_UNUSED))
                    fprintf (dump_file, "  Flags for param %i improved:",
                             (int)i);
                  else
                    gcc_unreachable ();
                  dump_eaf_flags (dump_file, old_flags, false);
                  fprintf (dump_file, " -> ");
                  dump_eaf_flags (dump_file, new_flags, true);
                }
            }
```

(gdb) p old_flags
$1 = 960
(gdb) p new_flags
$2 = 828

(gdb) p dump_eaf_flags (dump_file, old_flags, true)
 not_returned_directly not_returned_indirectly no_direct_read no_indirect_read
$4 = void
(gdb) p dump_eaf_flags (dump_file, new_flags, true)
 no_direct_clobber no_indirect_clobber no_direct_escape no_indirect_escape
no_direct_read no_indirect_read


So what is happening is the `n/=0;` after modref1 is being turned into a
__builtin_trap and so basically modref1 and modref2 now disagree but only
because of the now it is unconditional trap.

Another testcase (fails at `-O1 -fno-tree-fre`):
```
int n;

__attribute__ ((noinline,noclone,returns_twice)) static int
bar (int)
{
  n = 1;
  if (n)
    __builtin_unreachable();

  return n;
}

int
foo (int x)
{
  return bar (x);
}
```

Same as above, modref1 disagrees with modref2 but only because we go from a
conditional __builtin_unreachable to an unconditional one (this is why
-fno-tree-fre is needed to get the disagreement happening).

Reply via email to