1/* PR rtl-optimization/9771 */
2/* { dg-do run } */
3/* { dg-require-effective-target ia32 } */
4/* { dg-options "-O2 -fomit-frame-pointer -ffixed-ebp" } */
5
6extern void abort(void);
7extern void exit(int);
8
9register long *B asm ("ebp");
10
11long x = 10;
12long y = 20;
13
14void bar(void)
15{
16  B = &y;
17}
18
19void foo()
20{
21  long *adr = B;
22  long save = *adr;
23
24  *adr = 123;
25
26  bar();
27
28  *adr = save;
29}
30
31/* This must not be inlined because main() requires the frame pointer
32   for stack alignment.  */
33void test(void) __attribute__((noinline));
34void test(void)
35{
36  B = &x;
37
38  foo();
39
40  if (x != 10 || y != 20)
41    abort();
42
43  /* We can't return, as our caller may assume %ebp is preserved!  */
44  /* We could save/restore it (like foo), but its easier to exit.  */
45  exit(0);
46}
47
48/* main usually performs dynamic realignment of the stack in case
49   _start would fail to properly align the stack, but for dynamic
50   stack realignment we need frame pointer which is incompatible
51   with -ffixed-ebp and the global register var.  So, cheat here
52   and hide from the compiler that main is really main.  */
53#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
54#define ASMNAME2(prefix, cname) STRING (prefix) cname
55#define STRING(x)    #x
56int real_main() __asm (ASMNAME ("main"));
57
58int real_main()
59{
60  test();
61  return 0;
62
63}
64