(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
sparc/
globalreg-1.c
       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  
      13  extern void exit(int);
      14  extern void abort(void);
      15  
      16  register unsigned long regval __asm__("g6");
      17  
      18  extern void cond_resched(void);
      19  
      20  unsigned int var;
      21  
      22  static unsigned long expression(unsigned long v)
      23  {
      24    unsigned long ret;
      25  
      26    __asm__("" : "=r" (ret) : "0" (0));
      27    return ret + v;
      28  }
      29  
      30  void 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  
      40  void __attribute__((noinline)) cond_resched(void)
      41  {
      42  	regval++;
      43  }
      44  
      45  int main(void)
      46  {
      47    unsigned long val;
      48  
      49    regval = 100;
      50    func(&val);
      51    if (val != 156)
      52      abort();
      53    exit(0);
      54  }