From 290dfd9bc7bea2f102f29723d20674f1b57332f1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 18 Feb 2019 12:20:43 +0100 Subject: [PATCH] re PR target/89369 (pseudo-RNG miscompiled on s390x-linux with -O2 -march=zEC12 -mtune=z13 starting with r266203) PR target/89369 * config/s390/s390.md (*rsbg__srl_bitmask, *rsbg__sll, *rsbg__srl): Don't construct pattern in a temporary buffer. (*rsbg_sidi_srl): Likewise. Always use 32 as I3 rather than 64-operands[2]. * gcc.c-torture/execute/pr89369.c: New test. * gcc.target/s390/md/rXsbg_mode_sXl.c (rosbg_si_srl, rxsbg_si_srl): Expect last 3 operands 32,63,62 rather than 34,63,62. From-SVN: r268984 --- gcc/ChangeLog | 7 ++ gcc/config/s390/s390.md | 25 +++---- gcc/testsuite/ChangeLog | 8 +++ gcc/testsuite/gcc.c-torture/execute/pr89369.c | 69 +++++++++++++++++++ .../gcc.target/s390/md/rXsbg_mode_sXl.c | 4 +- 5 files changed, 95 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr89369.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 45b5d5d0e98..f8cd9cfc28f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2019-02-18 Jakub Jelinek + PR target/89369 + * config/s390/s390.md (*rsbg__srl_bitmask, + *rsbg__sll, *rsbg__srl): Don't construct + pattern in a temporary buffer. + (*rsbg_sidi_srl): Likewise. Always use 32 as I3 rather + than 64-operands[2]. + PR target/89361 * config/s390/s390.c (s390_indirect_branch_attrvalue, s390_indirect_branch_settings): Define unconditionally. diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 377420c5af9..a307e33e9d7 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -4268,10 +4268,8 @@ && s390_extzv_shift_ok (, 64 - INTVAL (operands[3]), INTVAL (operands[2]))" { - static char buffer[256]; - sprintf (buffer, "rsbg\t%%0,%%1,%%2,%%2,%ld", - 64 - INTVAL (operands[3])); - return buffer; + operands[3] = GEN_INT (64 - INTVAL (operands[3])); + return "rsbg\t%0,%1,%2,%2,%3"; } [(set_attr "op_type" "RIE")]) @@ -4306,10 +4304,8 @@ (clobber (reg:CC CC_REGNUM))] "TARGET_Z10" { - static char buffer[256]; - sprintf (buffer, "rsbg\t%%0,%%1,,%ld,%%2", - 63 - INTVAL (operands[2])); - return buffer; + operands[3] = GEN_INT (63 - INTVAL (operands[2])); + return "rsbg\t%0,%1,,%3,%2"; } [(set_attr "op_type" "RIE")]) @@ -4327,10 +4323,9 @@ (clobber (reg:CC CC_REGNUM))] "TARGET_Z10" { - static char buffer[256]; - sprintf (buffer, "rsbg\t%%0,%%1,%ld,63,%ld", - INTVAL (operands[2]), 64 - INTVAL (operands[2])); - return buffer; + operands[3] = GEN_INT (64 - INTVAL (operands[2])); + operands[2] = GEN_INT ( INTVAL (operands[2])); + return "rsbg\t%0,%1,%2,63,%3"; } [(set_attr "op_type" "RIE")]) @@ -4348,10 +4343,8 @@ (clobber (reg:CC CC_REGNUM))] "TARGET_Z10" { - static char buffer[256]; - sprintf (buffer, "rsbg\t%%0,%%1,%ld,63,%ld", - 64 - INTVAL (operands[2]), 32 + INTVAL (operands[2])); - return buffer; + operands[2] = GEN_INT (32 + INTVAL (operands[2])); + return "rsbg\t%0,%1,32,63,%2"; } [(set_attr "op_type" "RIE")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9e274acbbd1..2ca40b00dab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-02-18 Jakub Jelinek + + PR target/89369 + * gcc.c-torture/execute/pr89369.c: New test. + * gcc.target/s390/md/rXsbg_mode_sXl.c (rosbg_si_srl, + rxsbg_si_srl): Expect last 3 operands 32,63,62 rather than + 34,63,62. + 2019-02-18 Martin Jambor PR tree-optimization/89209 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr89369.c b/gcc/testsuite/gcc.c-torture/execute/pr89369.c new file mode 100644 index 00000000000..a8f095e0b57 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr89369.c @@ -0,0 +1,69 @@ +/* PR target/89369 */ + +#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 && __CHAR_BIT__ == 8 +struct S { unsigned int u[4]; }; + +static void +foo (struct S *out, struct S const *in, int shift) +{ + unsigned long long th, tl, oh, ol; + th = ((unsigned long long) in->u[3] << 32) | in->u[2]; + tl = ((unsigned long long) in->u[1] << 32) | in->u[0]; + oh = th >> (shift * 8); + ol = tl >> (shift * 8); + ol |= th << (64 - shift * 8); + out->u[1] = ol >> 32; + out->u[0] = ol; + out->u[3] = oh >> 32; + out->u[2] = oh; +} + +static void +bar (struct S *out, struct S const *in, int shift) +{ + unsigned long long th, tl, oh, ol; + th = ((unsigned long long) in->u[3] << 32) | in->u[2]; + tl = ((unsigned long long) in->u[1] << 32) | in->u[0]; + oh = th << (shift * 8); + ol = tl << (shift * 8); + oh |= tl >> (64 - shift * 8); + out->u[1] = ol >> 32; + out->u[0] = ol; + out->u[3] = oh >> 32; + out->u[2] = oh; +} + +__attribute__((noipa)) static void +baz (struct S *r, struct S *a, struct S *b, struct S *c, struct S *d) +{ + struct S x, y; + bar (&x, a, 1); + foo (&y, c, 1); + r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> 11) & 0xdfffffefU) ^ y.u[0] ^ (d->u[0] << 18); + r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> 11) & 0xddfecb7fU) ^ y.u[1] ^ (d->u[1] << 18); + r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> 11) & 0xbffaffffU) ^ y.u[2] ^ (d->u[2] << 18); + r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> 11) & 0xbffffff6U) ^ y.u[3] ^ (d->u[3] << 18); +} + +int +main () +{ + struct S a[] = { { 0x000004d3, 0xbc5448db, 0xf22bde9f, 0xebb44f8f }, + { 0x03a32799, 0x60be8246, 0xa2d266ed, 0x7aa18536 }, + { 0x15a38518, 0xcf655ce1, 0xf3e09994, 0x50ef69fe }, + { 0x88274b07, 0xe7c94866, 0xc0ea9f47, 0xb6a83c43 }, + { 0xcd0d0032, 0x5d47f5d7, 0x5a0afbf6, 0xaea87b24 }, + { 0, 0, 0, 0 } }; + baz (&a[5], &a[0], &a[1], &a[2], &a[3]); + if (a[4].u[0] != a[5].u[0] || a[4].u[1] != a[5].u[1] + || a[4].u[2] != a[5].u[2] || a[4].u[3] != a[5].u[3]) + __builtin_abort (); + return 0; +} +#else +int +main () +{ + return 0; +} +#endif diff --git a/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c b/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c index 600914280e5..ede813818ff 100644 --- a/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c +++ b/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c @@ -46,7 +46,7 @@ rosbg_si_srl (unsigned int a, unsigned int b) { return a | (b >> 2); } -/* { dg-final { scan-assembler-times "rosbg\t%r.,%r.,34,63,62" 1 } } */ +/* { dg-final { scan-assembler-times "rosbg\t%r.,%r.,32,63,62" 1 } } */ __attribute__ ((noinline)) unsigned int rxsbg_si_sll (unsigned int a, unsigned int b) @@ -60,7 +60,7 @@ rxsbg_si_srl (unsigned int a, unsigned int b) { return a ^ (b >> 2); } -/* { dg-final { scan-assembler-times "rxsbg\t%r.,%r.,34,63,62" 1 } } */ +/* { dg-final { scan-assembler-times "rxsbg\t%r.,%r.,32,63,62" 1 } } */ __attribute__ ((noinline)) unsigned long long di_sll (unsigned long long x) -- 2.30.2