From 4c07fd98b80242f8d4fd30e6264150826c21cee6 Mon Sep 17 00:00:00 2001 From: Dominik Vogt Date: Wed, 20 Jul 2016 17:11:37 +0000 Subject: [PATCH] S/390: Fix pr67443.c. 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 * gcc.target/s390/pr67443.c: Fix test case. From-SVN: r238531 --- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/s390/pr67443.c | 42 ++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a57bb1c..ef0270e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2016-07-20 Dominik Vogt + * gcc.target/s390/pr67443.c: Fix test case. + +2016-07-20 Dominik Vogt + * gcc.target/s390/insv-1.c: Xfail some tests. * gcc.target/s390/insv-2.c: Likewise. diff --git a/gcc/testsuite/gcc.target/s390/pr67443.c b/gcc/testsuite/gcc.target/s390/pr67443.c index e011a11..771b56f 100644 --- a/gcc/testsuite/gcc.target/s390/pr67443.c +++ b/gcc/testsuite/gcc.target/s390/pr67443.c @@ -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 -/* 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; -- 2.7.4