[Bug middle-end/83487] [8 Regression] ICE in expand_call, at calls.c:4098

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Dec 21 13:21:00 GMT 2017


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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hjl.tools at gmail dot com,
                   |                            |hubicka at gcc dot gnu.org,
                   |                            |jason at gcc dot gnu.org,
                   |                            |matz at gcc dot gnu.org

--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Anyway, have the TYPE_EMPTY_P changes been cross-checked with the x86-64 psABI
and other compilers?  The psABI is at least vague in this regard.
One thing is that we consider TYPE_EMPTY_P even aggregates larger than 16
bytes, like C++
struct B {};
struct C { struct B c[128]; };
where the psABI says it is passed in MEMORY.
I presume it has been intentional change, but will the psABI be updated here so
that other compilers know that they need to change too?
Another thing is for aggregates <= 16 bytes, the psABI algorithm is that it is
NO_CLASS for both 8byte halves if it is TYPE_EMPTY_P aggregate, and doesn't say
where it is passed.

Testcase for compiler compatibility:

pr83487.h:

#ifdef ALIGNED
struct __attribute__ ((aligned (ALIGNED))) A {};
#else
struct A {};
#endif
struct B {};
#ifdef LARGE
struct C { struct B c[128]; };
#else
struct C {};
#endif

pr83487-1.C:

#include "pr83487.h"
extern
#ifdef __cplusplus
"C"
#endif
void abort ();

void
f1 (int i, int j, int k, int l, int m, int n, int o, struct A)
{
  if (i != 6 || j != 0 || k != 1 || l != 2 || m != 3 || n != 4 || o != 5)
    abort ();
}

void
f3 (int i, int j, int k, int l, int m, int n, int o, struct A, int p, int q)
{
  if (i != 6 || j != 0 || k != 1 || l != 2 || m != 3 || n != 4 || o != 5 || p
!= 7 || q != 8)
    abort ();
}

void
f5 (int i, int j, int k, int l, int m, int n, int o, struct B, int p, int q)
{
  if (i != 6 || j != 0 || k != 1 || l != 2 || m != 3 || n != 4 || o != 5 || p
!= 7 || q != 8)
    abort ();
}

void
f7 (int i, int j, int k, int l, int m, int n, int o, struct C, int p, int q)
{
  if (i != 6 || j != 0 || k != 1 || l != 2 || m != 3 || n != 4 || o != 5 || p
!= 7 || q != 8)
    abort ();
}

void
f9 (int o, struct A)
{
  if (o != 5)
    abort ();
}

void
f11 (int o, struct A, int p, int q)
{
  if (o != 5 || p != 7 || q != 8)
    abort ();
}

void
f13 (int o, struct B, int p, int q)
{
  if (o != 5 || p != 7 || q != 8)
    abort ();
}

void
f15 (int o, struct C, int p, int q)
{
  if (o != 5 || p != 7 || q != 8)
    abort ();
}

pr83487-2.C:

#include "pr83487.h"
struct A a;
struct B b;
struct C c;

extern void f1 (int i, int j, int k, int l, int m, int n, int o, struct A);
extern void f3 (int i, int j, int k, int l, int m, int n, int o, struct A, int
p, int q);
extern void f5 (int i, int j, int k, int l, int m, int n, int o, struct B, int
p, int q);
extern void f7 (int i, int j, int k, int l, int m, int n, int o, struct C, int
p, int q);
extern void f9 (int o, struct A);
extern void f11 (int o, struct A, int p, int q);
extern void f13 (int o, struct B, int p, int q);
extern void f15 (int o, struct C, int p, int q);

int
main ()
{
  f1 (6, 0, 1, 2, 3, 4, 5, a);
  f3 (6, 0, 1, 2, 3, 4, 5, a, 7, 8);
  f5 (6, 0, 1, 2, 3, 4, 5, b, 7, 8);
  f7 (6, 0, 1, 2, 3, 4, 5, c, 7, 8);
  f9 (5, a);
  f11 (5, a, 7, 8);
  f13 (5, b, 7, 8);
  f15 (5, c, 7, 8);
  return 0;
}

Now, comparing clang r319307 with g++ with the above patch, without any
#defines it seems the two compilers are compatible, ditto with -DALIGNED=16,
with -DALIGNED=128 or -DLARGE they are not, because the aggregates then are >
16 bytes long and are passed in MEMORY by clang++ and in NO_CLASS by g++ (and
it honors alignment).

So, I think the #c13 change is correct, but we need to decide if TYPE_EMPTY_P
should be set on > 16 byte types or not and if it should be, adjust the psABI
to say so.


More information about the Gcc-bugs mailing list