1/* { dg-do run } */
2/* { dg-options "-std=gnu99 -Os" } */
3
4/* This is a massively distilled test case based upon
5   mm/memory.c:unmap_vmas() in the Linux kernel when compiled
6   on sparc64 for SMP which uses a global register as the
7   base of the per-cpu variable area.
8
9   Because of a bug in global register handling in the dataflow
10   code, the loop-invariant pass would move 'expression(regval)'
11   outside of the loop.  */
12
13extern void exit(int);
14extern void abort(void);
15
16register unsigned long regval __asm__("g6");
17
18extern void cond_resched(void);
19
20unsigned int var;
21
22static unsigned long expression(unsigned long v)
23{
24  unsigned long ret;
25
26  __asm__("" : "=r" (ret) : "0" (0));
27  return ret + v;
28}
29
30void func(unsigned long *pp)
31{
32  int i;
33
34  for (i = 0; i < 56; i++) {
35    cond_resched();
36    *pp = expression(regval);
37  }
38}
39
40void __attribute__((noinline)) cond_resched(void)
41{
42	regval++;
43}
44
45int main(void)
46{
47  unsigned long val;
48
49  regval = 100;
50  func(&val);
51  if (val != 156)
52    abort();
53  exit(0);
54}
55