/* { dg-do run } */ /* { dg-options "-std=gnu99 -Os" } */ /* This is a massively distilled test case based upon mm/memory.c:unmap_vmas() in the Linux kernel when compiled on sparc64 for SMP which uses a global register as the base of the per-cpu variable area. Because of a bug in global register handling in the dataflow code, the loop-invariant pass would move 'expression(regval)' outside of the loop. */ extern void exit(int); extern void abort(void); register unsigned long regval __asm__("g6"); extern void cond_resched(void); unsigned int var; static unsigned long expression(unsigned long v) { unsigned long ret; __asm__("" : "=r" (ret) : "0" (0)); return ret + v; } void func(unsigned long *pp) { int i; for (i = 0; i < 56; i++) { cond_resched(); *pp = expression(regval); } } void __attribute__((noinline)) cond_resched(void) { regval++; } int main(void) { unsigned long val; regval = 100; func(&val); if (val != 156) abort(); exit(0); }