summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/i386/pr9771-1.c
blob: 37ec4902201832aab67671192e4c15b54d045067 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/* PR rtl-optimization/9771 */
/* { dg-do run } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -fomit-frame-pointer -ffixed-ebp" } */

extern void abort(void);
extern void exit(int);

register long *B asm ("ebp");

long x = 10;
long y = 20;

void bar(void)
{
  B = &y;
}

void foo()
{
  long *adr = B;
  long save = *adr;

  *adr = 123;

  bar();

  *adr = save;
}

/* This must not be inlined becuase main() requires the frame pointer
   for stack alignment.  */
void test(void) __attribute__((noinline));
void test(void)
{
  B = &x;

  foo();

  if (x != 10 || y != 20)
    abort();

  /* We can't return, as our caller may assume %ebp is preserved!  */
  /* We could save/restore it (like foo), but its easier to exit.  */
  exit(0);
}

int main()
{
  test();
  return 0;

}