The patch below tweaks the ppc64-abi-1.c test to make it less prone to volatile registers getting clobbered before the test has had a chance to save them for later comparison to their expected values. This resolves the test failure discussed in PR 65109.
Martin Index: gcc.target/powerpc/ppc64-abi-1.c =================================================================== --- gcc.target/powerpc/ppc64-abi-1.c (revision 220801) +++ gcc.target/powerpc/ppc64-abi-1.c (working copy) @@ -1,10 +1,11 @@ /* { dg-do run { target { powerpc*-*-* && lp64 } } } */ /* { dg-skip-if "" { *-*-darwin* } { "*" } { "" } } */ /* { dg-options "-O2" } */ -#include <stdarg.h> -#include <signal.h> -#include <stdio.h> +typedef __builtin_va_list va_list; +#define va_start(ap, arg) __builtin_va_start (ap, arg) +#define va_arg(ap, type) __builtin_va_arg (ap, type) + /* Testcase to check for ABI compliance of parameter passing for the PowerPC64 ABI. Parameter passing of integral and floating point is tested. */ @@ -17,11 +18,16 @@ typedef struct double fprs[13]; } reg_parms_t; -reg_parms_t gparms; +volatile reg_parms_t gparms; -/* Testcase could break on future gcc's, if parameter regs - are changed before this asm. */ +/* Testcase could break on future gcc's, if parameter regs are changed + before this asm. To minimize the risk of that happening the test + consists of two sets of functions wih identical signatures: + foo, which does nothing except save function argument registers + to prevent them from getting clobbered (see PR65109), + foo_check, which verifies that the values of function registers + saved by foo match those passed to foo_check by the caller. */ #ifndef __MACH__ #define save_parms(lparms) \ @@ -46,8 +52,7 @@ typedef struct "stfd 10,136(11)\n\t" \ "stfd 11,144(11)\n\t" \ "stfd 12,152(11)\n\t" \ - "stfd 13,160(11)\n\t":::"11", "memory"); \ - lparms = gparms; + "stfd 13,160(11)\n\t":::"11", "memory") #else #define save_parms(lparms) \ asm volatile ("ld r11,gparms@got(r2)\n\t" \ @@ -71,8 +76,7 @@ typedef struct "stfd f10,136(r11)\n\t" \ "stfd f11,144(r11)\n\t" \ "stfd f12,152(r11)\n\t" \ - "stfd f13,160(r11)\n\t":::"r11", "memory"); \ - lparms = gparms; + "stfd f13,160(r11)\n\t":::"r11", "memory") #endif /* Stackframe structure relevant for parameter passing. */ @@ -104,16 +108,18 @@ typedef struct sf */ void __attribute__ ((noinline)) fcld (char *s, long l, double d) { - reg_parms_t lparms; - save_parms (lparms); + save_parms (); - if (s != (char *) lparms.gprs[0]) +} +void __attribute__ ((noinline)) fcld_check (char *s, long l, double d) +{ + if (s != (char *) gparms.gprs[0]) abort (); - if (l != lparms.gprs[1]) + if (l != gparms.gprs[1]) abort (); - if (d != lparms.fprs[0]) + if (d != gparms.fprs[0]) abort (); } @@ -126,19 +132,22 @@ void __attribute__ ((noinline)) fcld (char *s, lon void __attribute__ ((noinline)) fcldi (char *s, long l, double d, signed int i) { - reg_parms_t lparms; - save_parms (lparms); + save_parms (); +} - if (s != (char *) lparms.gprs[0]) +void __attribute__ ((noinline)) +fcldi_check (char *s, long l, double d, signed int i) +{ + if (s != (char *) gparms.gprs[0]) abort (); - if (l != lparms.gprs[1]) + if (l != gparms.gprs[1]) abort (); - if (d != lparms.fprs[0]) + if (d != gparms.fprs[0]) abort (); - if ((signed long) i != lparms.gprs[3]) + if ((signed long) i != gparms.gprs[3]) abort (); } @@ -151,19 +160,22 @@ fcldi (char *s, long l, double d, signed int i) void __attribute__ ((noinline)) fcldu (char *s, long l, float d, unsigned int i) { - reg_parms_t lparms; - save_parms (lparms); + save_parms (); +} - if (s != (char *) lparms.gprs[0]) +void __attribute__ ((noinline)) +fcldu_check (char *s, long l, float d, unsigned int i) +{ + if (s != (char *) gparms.gprs[0]) abort (); - if (l != lparms.gprs[1]) + if (l != gparms.gprs[1]) abort (); - if ((double) d != lparms.fprs[0]) + if ((double) d != gparms.fprs[0]) abort (); - if ((unsigned long) i != lparms.gprs[3]) + if ((unsigned long) i != gparms.gprs[3]) abort (); } @@ -172,19 +184,21 @@ fcldu (char *s, long l, float d, unsigned int i) l : slot 1 d : slot 2 */ - void __attribute__ ((noinline)) fceld (char *s, ...) { + save_parms (); +} + +void __attribute__ ((noinline)) fceld_check (char *s, ...) +{ stack_frame_t *sp; - reg_parms_t lparms; va_list arg; double d; long l; - save_parms (lparms); va_start (arg, s); - if (s != (char *) lparms.gprs[0]) + if (s != (char *) gparms.gprs[0]) abort (); l = va_arg (arg, long); @@ -210,22 +224,25 @@ void __attribute__ ((noinline)) fceld (char *s, .. */ void __attribute__ ((noinline)) fciiedl (char *s, int i, int j, ...) { + save_parms (); +} + +void __attribute__ ((noinline)) fciiedl_check (char *s, int i, int j, ...) +{ stack_frame_t *sp; - reg_parms_t lparms; va_list arg; double d; long l; - save_parms (lparms); va_start (arg, j); - if (s != (char *) lparms.gprs[0]) + if (s != (char *) gparms.gprs[0]) abort (); - if ((long) i != lparms.gprs[1]) + if ((long) i != gparms.gprs[1]) abort (); - if ((long) j != lparms.gprs[2]) + if ((long) j != gparms.gprs[2]) abort (); d = va_arg (arg, double); @@ -287,35 +304,39 @@ void __attribute__ ((noinline)) fididisdsid (int c, double ff, int d, double ld, int f, sparm s, double gg, sparm t, int e, double hh) { + save_parms (); +} + +void +fididisdsid_check (int c, double ff, int d, double ld, int f, + sparm s, double gg, sparm t, int e, double hh) +{ stack_frame_t *sp; - reg_parms_t lparms; double_t dx, dy; - save_parms (lparms); - /* Parm 0: int. */ - if ((long) c != lparms.gprs[0]) + if ((long) c != gparms.gprs[0]) abort (); /* Parm 1: double. */ - if (ff != lparms.fprs[0]) + if (ff != gparms.fprs[0]) abort (); /* Parm 2: int. */ - if ((long) d != lparms.gprs[2]) + if ((long) d != gparms.gprs[2]) abort (); /* Parm 3: double. */ - if (ld != lparms.fprs[1]) + if (ld != gparms.fprs[1]) abort (); /* Parm 4: int. */ - if ((long) f != lparms.gprs[4]) + if ((long) f != gparms.gprs[4]) abort (); /* Parm 5: struct sparm. */ - dx.l = lparms.gprs[5]; - dy.l = lparms.gprs[6]; + dx.l = gparms.gprs[5]; + dy.l = gparms.gprs[6]; if (s.a != dx.i[0]) abort (); @@ -323,11 +344,10 @@ fididisdsid (int c, double ff, int d, double ld, i abort (); /* Parm 6: double. */ - if (gg != lparms.fprs[2]) + if (gg != gparms.fprs[2]) abort (); - sp = __builtin_frame_address (0); - sp = sp->backchain; + sp = ((stack_frame_t*)__builtin_frame_address (0))->backchain; /* Parm 7: struct sparm. */ dx.l = sp->slot[8].l; @@ -343,7 +363,7 @@ fididisdsid (int c, double ff, int d, double ld, i /* Parm 9: double. */ - if (hh != lparms.fprs[3]) + if (hh != gparms.fprs[3]) abort (); } @@ -352,15 +372,17 @@ main () { char *s = "ii"; - fcld (s, 1, 1.0); - fcldi (s, 1, 1.0, -2); - fcldu (s, 1, 1.0, 2); - fceld (s, 1, 1.0); - fciiedl (s, 1, 2, 1.0, 3); - fididisdsid (1, 1.0, 2, 2.0, -1, (sparm) - { - 3, 3.0}, 4.0, (sparm) - { - 5, 5.0}, 6, 7.0); +#define ABI_CHECK(func, args) \ + func args, func ## _check args + + ABI_CHECK (fcld, (s, 1, 1.0)); + ABI_CHECK (fcldi, (s, 1, 1.0, -2)); + ABI_CHECK (fcldu, (s, 1, 1.0, 2)); + ABI_CHECK (fceld, (s, 1, 1.0)); + ABI_CHECK (fciiedl, (s, 1, 2, 1.0, 3)); + ABI_CHECK (fididisdsid, (1, 1.0, 2, 2.0, -1, + (sparm){3, 3.0}, 4.0, (sparm){5, 5.0}, + 6, 7.0)); + return 0; } Index: ChangeLog =================================================================== --- ChangeLog (revision 220801) +++ ChangeLog (working copy) @@ -1,3 +1,11 @@ +2015-02-21 Martin Sebor <mse...@redhat.com> + + PR target/65109 + * gcc.target/powerpc/ppc64-abi-1.c: Split test functions into + two parts. One to save registers, the other to verify the + registers have the right values. Save register state into + static data rather than on the stack. + 2015-02-18 Jakub Jelinek <ja...@redhat.com> PR gcov-profile/64634