aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-02-03 09:00:19 +0100
committerJakub Jelinek <jakub@redhat.com>2020-02-03 09:03:12 +0100
commitf626ae5478887b0cec886160dcfc4d59bf6fda07 (patch)
tree766b78d2bb74aa6109d4696637e07943be27c89e
parentc3ccce5b47f85d70127f5bb894bc5e83f8d2510e (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/config/s390/s390.md27
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr93533.c9
-rw-r--r--gcc/testsuite/gcc.target/s390/pr93533.c5
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"