(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
arc/
builtin_arc_aligned-3.c
       1  /* { dg-do run } */
       2  /* { dg-options "-O" } */
       3  
       4  extern void abort (void);
       5  
       6  typedef struct {
       7    int b, c;
       8  }
       9  __attribute__((aligned(32))) inner_t; // data type is 32 byte aligned
      10  
      11  typedef struct {
      12    inner_t *inner;
      13    int a;
      14  } outer_t;
      15  
      16  void __attribute__  ((noinline,weak))
      17  somefunc (int a, int b, int c)
      18  {
      19    if (!a || !b || c)
      20      abort ();
      21  };
      22  
      23  __attribute__  ((noinline,weak))
      24  outer_t *
      25  some_alloc_1 ()
      26  {
      27    static outer_t x;
      28    return &x;
      29  }
      30  
      31  __attribute__  ((noinline,weak))
      32  inner_t *
      33  some_alloc_2 ()
      34  {
      35    static inner_t x;
      36    return &x;
      37  }
      38  
      39  int main (void)
      40  {
      41    int y, y2, y3;
      42    // @p_out is pointing to instance of outer_t, naturally aligned to 4+4 = 8
      43    // and not gauranteed be 32 byte aligned.
      44    outer_t *p_out = some_alloc_1( ); // returns 8 byte aligned ptr
      45  
      46    // @ptr is pointing to instance of inner_t which is naturally aligned to 32.
      47    // It is assigned to p_out->inner which is of type inner_t thus 32 byte
      48    // aligned as well
      49    // Note that gcc can deduce p_out->inner is 32b aligned, not at runtime,
      50    // because it was assigned @ptr, but even at compile time, because it's data
      51    // type is naturally 32 byte aligned.
      52    inner_t *ptr = some_alloc_2(); // returns 32 byte aligned ptr
      53    p_out->inner = ptr; // this ptr will also be 32 byte aligned
      54  
      55    y = __builtin_arc_aligned(ptr, 32); // this shd return 1
      56    y2 = __builtin_arc_aligned(p_out->inner, 32); // this also shd return 1
      57    // Although p_out->inner ptr is 32 byte aligned,
      58    // it's container &(p_out->inner) need not be.
      59    // That is because the hoister has no relation to contents.
      60    // p_out is not gauranteed to be 32 byte
      61    // aligned, so it's member @inner in p_out need not be.
      62    y3 = __builtin_arc_aligned(&(p_out->inner), 32);
      63    // compiler not sure, so must return 0
      64  
      65    somefunc(y, y2, y3);
      66    return 0;
      67  }