1 /* PR middle-end/27959 */
2 /* { dg-do run { target { int32plus } } } */
3 /* { dg-options "-O2" } */
4 /* { dg-options "-O2 -mtune=z990" { target s390*-*-* } } */
5 
6 extern void abort (void);
7 
8 struct B
9 {
10   unsigned int b1, b2, b3;
11   char b4;
12 };
13 
14 struct C
15 {
16   char c1;
17 };
18 
19 struct D
20 {
21   char *d1;
22   struct C **d2;
23   unsigned int d3;
24 };
25 
26 void
27 __attribute__((noinline))
foo(void * x,struct B * y,unsigned int * z)28 foo (void *x, struct B *y, unsigned int *z)
29 {
30   if (x)
31     abort ();
32   if (y->b1 != 7 || y->b2 != 5 || y->b3 != 3 || y->b4)
33     abort ();
34   if (*z != 2)
35     abort ();
36 }
37 
38 int
39 __attribute__((noinline))
baz(unsigned int * x,unsigned int y)40 baz (unsigned int *x, unsigned int y)
41 {
42   asm volatile ("" : : "r" (&x), "r" (&y) : "memory");
43   return *x + y;
44 }
45 
bar(unsigned int * x,unsigned int y)46 inline int bar (unsigned int *x, unsigned int y)
47 {
48   if (y < *x)
49     return 0;
50   return baz (x, y);
51 }
52 
53 unsigned int *
54 __attribute__((noinline))
test(struct D * x,unsigned int * y)55 test (struct D *x, unsigned int *y)
56 {
57   struct B b;
58   unsigned int c;
59 
60   bar (y, x->d3);
61   if ((*(x->d2))->c1)
62     c = ((unsigned char) x->d1[0]
63 	 + ((unsigned char) x->d1[1] << 8)
64 	 + ((unsigned char) x->d1[2] << 16)
65 	 + ((short) x->d1[3] << 24));
66   else
67     {
68       int d;
69       ((char *) &d)[0] = x->d1[0];
70       ((char *) &d)[1] = x->d1[1];
71       ((char *) &d)[2] = x->d1[2];
72       ((char *) &d)[3] = x->d1[3];
73       c = d;
74     }
75   b.b4 = 0;
76   b.b1 = c / 10000L % 10000;
77   b.b2 = c / 100 % 100;
78   b.b3 = c % 100;
79   foo (0, &b, y);
80   return y;
81 }
82 
83 int
main(void)84 main (void)
85 {
86   unsigned int x = 900070503;
87   unsigned int y = 2;
88   struct C c = { 0 }, *cptr = &c;
89   struct D d = { (char *) &x, &cptr, 0 };
90   if (test (&d, &y) != &y)
91     abort ();
92   return 0;
93 }
94