blob: 23d80edd4786249a1b6dcf15582e693fcc87921f [file] [log] [blame]
/* { dg-do run } */
/* { dg-options "-O" } */
extern void abort (void);
typedef struct {
int b, c;
}
__attribute__((aligned(32))) inner_t; // data type is 32 byte aligned
typedef struct {
inner_t *inner;
int a;
} outer_t;
void __attribute__ ((noinline,weak))
somefunc (int a, int b, int c)
{
if (!a || !b || c)
abort ();
};
__attribute__ ((noinline,weak))
outer_t *
some_alloc_1 ()
{
static outer_t x;
return &x;
}
__attribute__ ((noinline,weak))
inner_t *
some_alloc_2 ()
{
static inner_t x;
return &x;
}
int main (void)
{
int y, y2, y3;
// @p_out is pointing to instance of outer_t, naturally aligned to 4+4 = 8
// and not gauranteed be 32 byte aligned.
outer_t *p_out = some_alloc_1( ); // returns 8 byte aligned ptr
// @ptr is pointing to instance of inner_t which is naturally aligned to 32.
// It is assigned to p_out->inner which is of type inner_t thus 32 byte
// aligned as well
// Note that gcc can deduce p_out->inner is 32b aligned, not at runtime,
// because it was assigned @ptr, but even at compile time, because it's data
// type is naturally 32 byte aligned.
inner_t *ptr = some_alloc_2(); // returns 32 byte aligned ptr
p_out->inner = ptr; // this ptr will also be 32 byte aligned
y = __builtin_arc_aligned(ptr, 32); // this shd return 1
y2 = __builtin_arc_aligned(p_out->inner, 32); // this also shd return 1
// Although p_out->inner ptr is 32 byte aligned,
// it's container &(p_out->inner) need not be.
// That is because the hoister has no relation to contents.
// p_out is not gauranteed to be 32 byte
// aligned, so it's member @inner in p_out need not be.
y3 = __builtin_arc_aligned(&(p_out->inner), 32);
// compiler not sure, so must return 0
somefunc(y, y2, y3);
return 0;
}