(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
store_merging_16.c
       1  /* Only test on some 64-bit targets which do have bswap{si,di}2 patterns and
       2     are either big or little endian (not pdp endian).  */
       3  /* { dg-do run { target { lp64 && { i?86-*-* x86_64-*-* powerpc*-*-* aarch64*-*-* } } } } */
       4  /* { dg-require-effective-target store_merge } */
       5  /* { dg-options "-O2 -fno-tree-vectorize -fdump-tree-store-merging" } */
       6  
       7  __attribute__((noipa)) void
       8  f1 (unsigned char *p, unsigned long long q)
       9  {
      10    p[0] = q;
      11    p[1] = q >> 8;
      12    p[2] = q >> 16;
      13    p[3] = q >> 24;
      14    p[4] = q >> 32;
      15    p[5] = q >> 40;
      16    p[6] = q >> 48;
      17    p[7] = q >> 56;
      18  }
      19  
      20  __attribute__((noipa)) void
      21  f2 (unsigned char *p, unsigned long long q)
      22  {
      23    p[0] = q >> 56;
      24    p[1] = q >> 48;
      25    p[2] = q >> 40;
      26    p[3] = q >> 32;
      27    p[4] = q >> 24;
      28    p[5] = q >> 16;
      29    p[6] = q >> 8;
      30    p[7] = q;
      31  }
      32  
      33  __attribute__((noipa)) void
      34  f3 (unsigned char *__restrict p, unsigned char *__restrict q)
      35  {
      36    unsigned char q3 = q[3];
      37    unsigned char q2 = q[2];
      38    unsigned char q1 = q[1];
      39    unsigned char q0 = q[0];
      40    p[0] = q3;
      41    p[1] = q2;
      42    p[2] = q1;
      43    p[3] = q0;
      44  }
      45  
      46  __attribute__((noipa)) void
      47  f4 (unsigned char *__restrict p, unsigned char *__restrict q)
      48  {
      49    p[0] = q[3];
      50    p[1] = q[2];
      51    p[2] = q[1];
      52    p[3] = q[0];
      53  }
      54  
      55  struct S { unsigned char a, b; unsigned short c; };
      56  
      57  __attribute__((noipa)) void
      58  f5 (struct S *__restrict p, struct S *__restrict q)
      59  {
      60  #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
      61    unsigned char pa = q->c >> 8;
      62    unsigned char pb = q->c;
      63    unsigned short pc = (q->a << 8) | q->b;
      64  #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
      65    unsigned char pa = q->c;
      66    unsigned char pb = q->c >> 8;
      67    unsigned short pc = q->a | (q->b << 8);
      68  #endif
      69    p->a = pa;
      70    p->b = pb;
      71    p->c = pc;
      72  }
      73  
      74  __attribute__((noipa)) void
      75  f6 (struct S *__restrict p, struct S *__restrict q)
      76  {
      77  #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
      78    p->a = q->c >> 8;
      79    p->b = q->c;
      80    p->c = (q->a << 8) | q->b;
      81  #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
      82    p->a = q->c;
      83    p->b = q->c >> 8;
      84    p->c = q->a | (q->b << 8);
      85  #endif
      86  }
      87  
      88  struct T { unsigned long long a : 8, b : 8, c : 8, d : 8, e : 8, f : 8, g : 8, h : 8; };
      89  
      90  __attribute__((noipa)) void
      91  f7 (struct T *__restrict p, struct T *__restrict q)
      92  {
      93    p->a = q->h;
      94    p->b = q->g;
      95    p->c = q->f;
      96    p->d = q->e;
      97    p->e = q->d;
      98    p->f = q->c;
      99    p->g = q->b;
     100    p->h = q->a;
     101  }
     102  
     103  struct S b = { 0x11, 0x12,
     104  #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     105  	       0x1413
     106  #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
     107  	       0x1314
     108  #endif
     109  	     };
     110  struct T e = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28 };
     111  
     112  int
     113  main ()
     114  {
     115    unsigned char a[8];
     116    int i;
     117    struct S c, d;
     118    f1 (a, 0x0102030405060708ULL);
     119    for (i = 0; i < 8; ++i)
     120      if (a[i] != 8 - i)
     121        __builtin_abort ();
     122    f2 (a, 0x0102030405060708ULL);
     123    for (i = 0; i < 8; ++i)
     124      if (a[i] != 1 + i)
     125        __builtin_abort ();
     126    f3 (a, a + 4);
     127    for (i = 0; i < 8; ++i)
     128      if (a[i] != (i < 4 ? 8 - i : 1 + i))
     129        __builtin_abort ();
     130    f2 (a, 0x090a0b0c0d0e0f10ULL);
     131    f4 (a + 4, a);
     132    for (i = 0; i < 8; ++i)
     133      if (a[i] != (i < 4 ? 9 + i : 16 - i))
     134        __builtin_abort ();
     135    f5 (&c, &b);
     136    if (c.a != 0x14 || c.b != 0x13
     137  #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     138        || c.c != 0x1112
     139  #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
     140        || c.c != 0x1211
     141  #endif
     142        )
     143      __builtin_abort ();
     144    f6 (&d, &c);
     145    if (d.a != 0x11 || d.b != 0x12 || d.c != b.c)
     146      __builtin_abort ();
     147    struct T f;
     148    f7 (&f, &e);
     149    if (f.a != 0x28 || f.b != 0x27 || f.c != 0x26 || f.d != 0x25
     150        || f.e != 0x24 || f.f != 0x23 || f.g != 0x22 || f.h != 0x21)
     151      __builtin_abort ();
     152    return 0;
     153  }
     154  
     155  /* { dg-final { scan-tree-dump-times "Merging successful" 7 "store-merging" } } */
     156  /* { dg-final { scan-tree-dump-times "__builtin_bswap64" 2 "store-merging" } } */
     157  /* { dg-final { scan-tree-dump-times "__builtin_bswap32" 4 "store-merging" } } */