S/390: Fix pr67443.c.
authorDominik Vogt <vogt@linux.vnet.ibm.com>
Wed, 20 Jul 2016 17:11:37 +0000 (17:11 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Wed, 20 Jul 2016 17:11:37 +0000 (17:11 +0000)
The attached patch rewrites the pr67443.c testcase in a different way
so that the test still works with the changed allocation of globals
pinned to registers.  The test ist hopefully more robust now.

gcc/testsuite/ChangeLog:

2016-07-20  Dominik Vogt  <vogt@linux.vnet.ibm.com>

* gcc.target/s390/pr67443.c: Fix test case.

From-SVN: r238531

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/pr67443.c

index a57bb1c7794eb07c3193f06d27121ce81f341fda..ef0270ed6e12498fb1be513ec729e322e6ab7850 100644 (file)
@@ -1,3 +1,7 @@
+2016-07-20  Dominik Vogt  <vogt@linux.vnet.ibm.com>
+
+       * gcc.target/s390/pr67443.c: Fix test case.
+
 2016-07-20  Dominik Vogt  <vogt@linux.vnet.ibm.com>
 
        * gcc.target/s390/insv-1.c: Xfail some tests.
index e011a11882f029e0bed0aa2907db524b0e476c2e..771b56fc175e68cd106687aab759fc27bfaa02f2 100644 (file)
@@ -2,21 +2,10 @@
 
 /* { dg-do run { target s390*-*-* } } */
 /* { dg-prune-output "call-clobbered register used for global register variable" } */
-/* { dg-options "-march=z900 -fPIC -fomit-frame-pointer -O3" } */
+/* { dg-options "-march=z900 -fPIC -fomit-frame-pointer -O3 -save-temps" } */
 
 #include <assert.h>
 
-/* Block all registers except the first three argument registers.  */
-register long r0 asm ("r0");
-register long r1 asm ("r1");
-register long r5 asm ("r5");
-register long r6 asm ("r6");
-register long r7 asm ("r7");
-register long r8 asm ("r8");
-register long r9 asm ("r9");
-register long r10 asm ("r10");
-register long r11 asm ("r11");
-
 struct s_t
 {
   unsigned f1 : 8;
@@ -24,25 +13,40 @@ struct s_t
 };
 
 __attribute__ ((noinline))
-void foo (struct s_t *ps, int c, int i)
+int bar ()
 {
+  return 0;
+}
+
+__attribute__ ((noinline))
+void foo (struct s_t *ps, int c)
+{
+  int tmp;
+
   /* Uses r2 as address register.  */
   ps->f1 = c;
-  /* The calculation of the value is so expensive that it's cheaper to spill ps
-     to the stack and reload it later (into a different register).
-     ==> Uses r4 as address register.*/
-  ps->f2 = i + i % 3;
+  /* Clobber all registers that r2 could be stored into.  */
+  __asm__ __volatile__ ("" : : : "memory",
+                       "r0","r1","r6","r7","r8","r9","r10","r11");
+  /* Force that the pointer is evicted from r2 and stored on the stack.  */
+  tmp = bar ();
+  /* User the pointer again.  It gets reloaded to a different register because
+     r2 is already occupied.  */
+  ps->f2 = tmp;
   /* If dead store elimination fails to detect that the address in r2 during
-     the first assignment is an alias of the address in r4 during the second
+     the first assignment is an alias of the address in rX during the second
      assignment, it eliminates the first assignment and the f1 field is not
      written (bug).  */
 }
+/* Make sure that r2 is used only once as an address register for storing.
+   If this check fails, the test case needs to be fixed.
+   { dg-final { scan-assembler-times "\tst.\?\t.*,0\\(%r2\\)" 1 } } */
 
 int main (void)
 {
   struct s_t s = { 0x01u, 0x020304u };
 
-  foo (&s, 0, 0);
+  foo (&s, 0);
   assert (s.f1 == 0&& s.f2 == 0);
 
   return 0;