(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
pr47893.c
       1  /* PR middle-end/47893 */
       2  /* { dg-do run } */
       3  /* { dg-options "-O2" } */
       4  /* { dg-additional-options "-mtune=atom -fno-omit-frame-pointer -fno-strict-aliasing" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
       5  /* { dg-skip-if "Too much RAM needed" { "avr-*-*" } } */
       6  
       7  extern void abort (void);
       8  
       9  struct S
      10  {
      11    unsigned s1:4, s2:2, s3:2, s4:2, s5:2, s6:1, s7:1, s8:1, s9:1, s10:1;
      12    int s11:16; unsigned s12:4; int s13:16; unsigned s14:2;
      13    int s15:16; unsigned s16:4; int s17:16; unsigned s18:2;
      14  };
      15  
      16  struct T
      17  {
      18    unsigned t[3];
      19  };
      20  
      21  struct U
      22  {
      23    unsigned u1, u2;
      24  };
      25  
      26  struct V;
      27  
      28  struct W
      29  {
      30    char w1[24]; struct V *w2; unsigned w3; char w4[28912];
      31    unsigned int w5; char w6[60];
      32  };
      33  
      34  struct X
      35  {
      36    unsigned int x[2];
      37  };
      38  
      39  struct V
      40  {
      41    int v1;
      42    struct X v2[3];
      43    char v3[28];
      44  };
      45  
      46  struct Y
      47  {
      48    void *y1;
      49    char y2[3076];
      50    struct T y3[32];
      51    char y4[1052];
      52  };
      53  
      54  volatile struct S v1 = { .s15 = -1, .s16 = 15, .s17 = -1, .s18 = 3 };
      55  
      56  __attribute__ ((noinline, noclone))
      57  int
      58  fn1 (int x)
      59  {
      60    int r;
      61    __asm__ volatile ("" : "=r" (r) : "0" (1), "r" (x) : "memory");
      62    return r;
      63  }
      64  
      65  volatile int cnt;
      66  
      67  __attribute__ ((noinline, noclone))
      68  #ifdef __i386__
      69  __attribute__ ((regparm (2)))
      70  #endif
      71  struct S
      72  fn2 (struct Y *x, const struct X *y)
      73  {
      74    if (++cnt > 1)
      75      abort ();
      76    __asm__ volatile ("" : : "r" (x), "r" (y) : "memory");
      77    return v1;
      78  }
      79  
      80  __attribute__ ((noinline, noclone))
      81  void fn3 (void *x, unsigned y, const struct S *z, unsigned w)
      82  {
      83    __asm__ volatile ("" : : "r" (x), "r" (y), "r" (z), "r" (w) : "memory");
      84  }
      85  
      86  volatile struct U v2;
      87  
      88  __attribute__ ((noinline, noclone))
      89  struct U
      90  fn4 (void *x, unsigned y)
      91  {
      92    __asm__ volatile ("" : : "r" (x), "r" (y) : "memory");
      93    return v2;
      94  }
      95  
      96  __attribute__ ((noinline, noclone))
      97  struct S
      98  fn5 (void *x)
      99  {
     100    __asm__ volatile ("" : : "r" (x) : "memory");
     101    return v1;
     102  }
     103  
     104  volatile struct T v3;
     105  
     106  __attribute__ ((noinline, noclone))
     107  struct T fn6 (void *x)
     108  {
     109    __asm__ volatile ("" : : "r" (x) : "memory");
     110    return v3;
     111  }
     112  
     113  __attribute__ ((noinline, noclone))
     114  struct T fn7 (void *x, unsigned y, unsigned z)
     115  {
     116    __asm__ volatile ("" : : "r" (x), "r" (y), "r" (z) : "memory");
     117    return v3;
     118  }
     119  
     120  static void
     121  fn8 (struct Y *x, const struct V *y)
     122  {
     123    void *a = x->y1;
     124    struct S b[4];
     125    unsigned i, c;
     126    c = fn1 (y->v1);
     127    for (i = 0; i < c; i++)
     128      b[i] = fn2 (x, &y->v2[i]);
     129    fn3 (a, y->v1, b, c);
     130  }
     131  
     132  static inline void
     133  fn9 (void *x, struct S y __attribute__((unused)))
     134  {
     135    fn4 (x, 8);
     136  }
     137  
     138  static void
     139  fn10 (struct Y *x)
     140  {
     141    void *a = x->y1;
     142    struct T b __attribute__((unused)) = fn6 (a);
     143    fn9 (a, fn5 (a));
     144  }
     145  
     146  __attribute__((noinline, noclone))
     147  int
     148  fn11 (unsigned int x, void *y, const struct W *z,
     149        unsigned int w, const char *v, const char *u)
     150  {
     151    struct Y a, *t;
     152    unsigned i;
     153    t = &a;
     154    __builtin_memset (t, 0, sizeof *t);
     155    t->y1 = y;
     156    if (x == 0)
     157      {
     158        if (z->w3 & 1)
     159  	fn10 (t);
     160        for (i = 0; i < w; i++)
     161  	{
     162  	  if (v[i] == 0)
     163  	    t->y3[i] = fn7 (y, 0, u[i]);
     164  	  else
     165  	    return 0;
     166  	}
     167      }
     168    else
     169      for (i = 0; i < w; i++)
     170        t->y3[i] = fn7 (y, v[i], u[i]);
     171    for (i = 0; i < z->w5; i++)
     172      fn8 (t, &z->w2[i]);
     173    return 0;
     174  }
     175  
     176  volatile int i;
     177  const char *volatile p = "";
     178  
     179  int
     180  main ()
     181  {
     182    struct V v = { .v1 = 0 };
     183    struct W w = { .w5 = 1, .w2 = &v };
     184    fn11 (i + 1, (void *) p, &w, i, (const char *) p, (const char *) p);
     185    if (cnt != 1)
     186      abort ();
     187    return 0;
     188  }