1 /* PR target/55940 */
2 /* { dg-do run } */
3 /* { dg-options "-Os" } */
4 /* { dg-additional-options "-mpreferred-stack-boundary=2" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
5 
6 struct S { int s; unsigned long t; };
7 
8 __attribute__ ((noinline, noclone)) unsigned long long
bar(struct S * x,unsigned long y)9 bar (struct S *x, unsigned long y)
10 {
11   asm volatile ("" : : "r" (x), "r" (y) : "memory");
12   return x->s + y;
13 }
14 
15 __attribute__ ((noinline, noclone)) unsigned long long
foo(struct S * x,unsigned long y)16 foo (struct S *x, unsigned long y)
17 {
18   unsigned long a;
19   if (__builtin_expect (((__UINTPTR_TYPE__) (x) + 0x1000U < 0x2000U), 0))
20     return ~0ULL;
21   if (__builtin_expect (x->s <= 0 || x->s > 9, 0))
22     return ~0ULL;
23   a = x->t >> 12;
24   if (y == a)
25     return ~0ULL;
26   if (x->s == 3)
27     return x->t + y * 4096;
28   return bar (x, y);
29 }
30 
31 int va, vb, vc, vd;
32 
33 int
main()34 main ()
35 {
36   struct S s;
37   asm volatile ("" : : : "memory");
38   int a = va, b = vb, c = vc, d = vd;
39   asm volatile ("" : : : "memory");
40   int i;
41   for (i = 0; i < 64; i++)
42     if (foo ((struct S *) 0, 0) != ~0ULL)
43       __builtin_abort ();
44   s.s = 3;
45   s.t = 2 << 12;
46   if (foo (&s, 2) != ~0ULL)
47     __builtin_abort ();
48   if (foo (&s, 3) != (2 << 12) + 3 * 4096)
49     __builtin_abort ();
50   asm volatile ("" : : : "memory");
51   va = a; vb = b; vc = c; vd = d;
52   asm volatile ("" : : : "memory");
53   return 0;
54 }
55