diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-02-03 09:00:19 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-02-03 09:03:12 +0100 |
commit | f626ae5478887b0cec886160dcfc4d59bf6fda07 (patch) | |
tree | 766b78d2bb74aa6109d4696637e07943be27c89e | |
parent | c3ccce5b47f85d70127f5bb894bc5e83f8d2510e (diff) | |
download | gcc-f626ae5478887b0cec886160dcfc4d59bf6fda07.zip gcc-f626ae5478887b0cec886160dcfc4d59bf6fda07.tar.gz gcc-f626ae5478887b0cec886160dcfc4d59bf6fda07.tar.bz2 |
s390x: Fix popcounthi2_z196 expander [PR93533]
The following testcase started to ICE when .POPCOUNT matching has been added
to match.pd; we had __builtin_popcount*, but nothing would use the
popcounthi2 expander before.
The problem is that the popcounthi2_z196 expander doesn't emit valid RTL:
error: unrecognizable insn:
(insn 138 137 139 27 (set (reg:SI 190)
(ashift:SI (reg:HI 95 [ _105 ])
(const_int 8 [0x8]))) -1
(nil))
during RTL pass: vregs
The following patch is an attempt to fix that, furthermore I've tried to
slightly simplify it as well, it makes no sense to me to perform
(x + (x << 8)) >> 8 when we need to either zero extend or mask the result
at the end in order to avoid bits from above HImode to affect it, when we
can do
(x + (x >> 8)) & 0xff (or zero extension).
2020-02-03 Jakub Jelinek <jakub@redhat.com>
PR target/93533
* config/s390/s390.md (popcounthi2_z196): Fix up expander to emit
valid RTL to sum up the lowest and second lowest bytes of the popcnt
result.
* gcc.c-torture/compile/pr93533.c: New test.
* gcc.target/s390/pr93533.c: New test.
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr93533.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/pr93533.c | 5 |
5 files changed, 45 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c0f117..2cb1b9f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2020-02-03 Jakub Jelinek <jakub@redhat.com> + + PR target/93533 + * config/s390/s390.md (popcounthi2_z196): Fix up expander to emit + valid RTL to sum up the lowest and second lowest bytes of the popcnt + result. + 2020-02-02 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/91333 diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 2959d8c..e37ba49 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -11670,21 +11670,28 @@ }) (define_expand "popcounthi2_z196" - [; popcnt op0, op1 - (parallel [(set (match_operand:HI 0 "register_operand" "") + [; popcnt op2, op1 + (parallel [(set (match_dup 2) (unspec:HI [(match_operand:HI 1 "register_operand")] UNSPEC_POPCNT)) (clobber (reg:CC CC_REGNUM))]) - ; sllk op2, op0, 8 - (set (match_dup 2) - (ashift:SI (match_dup 0) (const_int 8))) - ; ar op0, op2 - (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) + ; lr op3, op2 + (set (match_dup 3) (subreg:SI (match_dup 2) 0)) + ; srl op4, op3, 8 + (set (match_dup 4) (lshiftrt:SI (match_dup 3) (const_int 8))) + ; ar op3, op4 + (parallel [(set (match_dup 3) (plus:SI (match_dup 3) (match_dup 4))) (clobber (reg:CC CC_REGNUM))]) - ; srl op0, op0, 8 - (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))] + ; llgc op0, op3 + (parallel [(set (match_operand:HI 0 "register_operand" "") + (and:HI (subreg:HI (match_dup 3) 2) (const_int 255))) + (clobber (reg:CC CC_REGNUM))])] "TARGET_Z196" - "operands[2] = gen_reg_rtx (SImode);") +{ + operands[2] = gen_reg_rtx (HImode); + operands[3] = gen_reg_rtx (SImode); + operands[4] = gen_reg_rtx (SImode); +}) (define_expand "popcounthi2" [(set (match_dup 2) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5471778..86b9edc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,10 @@ -2020-02-03 Jun Ma <JunMa@linux.alibaba.com> +2020-02-03 Jakub Jelinek <jakub@redhat.com> + + PR target/93533 + * gcc.c-torture/compile/pr93533.c: New test. + * gcc.target/s390/pr93533.c: New test. + +2020-02-03 Jun Ma <JunMa@linux.alibaba.com> * g++.dg/coroutines/co-await-04-control-flow.C: Add label. diff --git a/gcc/testsuite/gcc.c-torture/compile/pr93533.c b/gcc/testsuite/gcc.c-torture/compile/pr93533.c new file mode 100644 index 0000000..8b9b1be --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr93533.c @@ -0,0 +1,9 @@ +/* PR target/93533 */ + +unsigned +foo (unsigned short a) +{ + a = a - (a >> 1 & 21845); + a = (a & 13107) + (a >> 2 & 13107); + return (unsigned short) ((a + (a >> 4) & 3855) * 257) >> 8; +} diff --git a/gcc/testsuite/gcc.target/s390/pr93533.c b/gcc/testsuite/gcc.target/s390/pr93533.c new file mode 100644 index 0000000..1a49c73 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr93533.c @@ -0,0 +1,5 @@ +/* PR target/93533 */ +/* { dg-do compile } */ +/* { dg-options "-march=z196 -O2" } */ + +#include "../../gcc.c-torture/compile/pr93533.c" |