1/* Test case for PR/67443.  */
2
3/* { dg-do run { target s390*-*-* } } */
4/* { dg-prune-output "call-clobbered register used for global register variable" } */
5/* { dg-options "-march=z900 -fPIC -fomit-frame-pointer -O3" } */
6
7#include <assert.h>
8
9/* Block all registers except the first three argument registers.  */
10register long r0 asm ("r0");
11register long r1 asm ("r1");
12register long r5 asm ("r5");
13register long r6 asm ("r6");
14register long r7 asm ("r7");
15register long r8 asm ("r8");
16register long r9 asm ("r9");
17register long r10 asm ("r10");
18register long r11 asm ("r11");
19
20struct s_t
21{
22  unsigned f1 : 8;
23  unsigned f2 : 24;
24};
25
26__attribute__ ((noinline))
27void foo (struct s_t *ps, int c, int i)
28{
29  /* Uses r2 as address register.  */
30  ps->f1 = c;
31  /* The calculation of the value is so expensive that it's cheaper to spill ps
32     to the stack and reload it later (into a different register).
33     ==> Uses r4 as address register.*/
34  ps->f2 = i + i % 3;
35  /* If dead store elimination fails to detect that the address in r2 during
36     the first assignment is an alias of the address in r4 during the second
37     assignment, it eliminates the first assignment and the f1 field is not
38     written (bug).  */
39}
40
41int main (void)
42{
43  struct s_t s = { 0x01u, 0x020304u };
44
45  foo (&s, 0, 0);
46  assert (s.f1 == 0&& s.f2 == 0);
47
48  return 0;
49}
50