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