diff mbox

Fix PR 65109 - [5 Regression] r220674 causes FAIL: gcc.target/powerpc/ppc64-abi-1.c execution test

Message ID 54E8F260.3090400@redhat.com
State New
Headers show

Commit Message

Martin Sebor Feb. 21, 2015, 9:02 p.m. UTC
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
diff mbox

Patch

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  <msebor@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  <jakub@redhat.com>

  	PR gcov-profile/64634