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

            Bug ID: 128154
           Summary: gcc.c-torture/execute/20000603-1.c aborts when f() is
                    not inlined early (IPA-CP and IPA-SRA)
           Product: gcc
           Version: 16.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: ipa
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bernie at codewiz dot org
  Target Milestone: ---

I hit this while testing m68k-amigaos-gcc, but then I realized it's
reproducible also with my Fedora x86_64 GCC 16.2.1.

gcc.c-torture/execute/20000603-1.c aborts whenever f() reaches the IPA passes
without having been inlined early.

Reduced repro:

```c
struct s1 { double d; };
struct s2 { double d; };
union u { struct s1 x; struct s2 y; };

static __attribute__((noinline)) double f(struct s1 *a, struct s2 *b)
{
  a->d = 1.0;
  return b->d + 1.0;
}

int main()
{
  union u a;
  a.x.d = 0.0;
  if (f (&a.x, &a.y) != 2.0)
    __builtin_abort ();
  return 0;
}
```

With gcc 16.2.1 on x86_64, `gcc -O2 t.c && ./a.out` aborts, and main compiles
to a bare `call abort`.

It passes at -O1, with -fno-strict-aliasing, or with both -fno-ipa-cp and
-fno-ipa-sra. Either pass alone is enough to break it:

- IPA-CP propagates the known aggregate value `b->d == 0.0` from the call site,
because the store through `a` (a `struct s1`) is assumed not to clobber the
load through `b` (a `struct s2`).

- IPA-SRA turns `b` into a by-value `double` loaded in main before the call, on
the same assumption.

The unmodified test also aborts with `-O2 -flto -fno-early-inlining` on x86_64:
under LTO f becomes local, and the IPA passes then change it. Without -flto, f
stays global and they leave it alone.

I can't tell if the test is within the bounds of DR#236 or invalid C that
passes by accident in most cases.

Reply via email to