s390_fix_long_loop_prediction is used in machine dependent
reorg. There we use single_set to distingiush between conditional
jumps and branch on count patterns.  However, single_set returns a
non-NULL value also for PARALLELs in case one of the SETs is dead.

Bootstrapped and regression tested on IBM z15.
Committed to mainline.

2020-06-17  Andreas Krebbel  <kreb...@linux.ibm.com>

gcc/
        * config/s390/s390.c (s390_fix_long_loop_prediction): Exit early
        for PARALLELs.

gcc/testsuite/
        * gcc.target/s390/20200617.c: New test.
---
 gcc/config/s390/s390.c                   |  9 +++++++--
 gcc/testsuite/gcc.target/s390/20200617.c | 23 +++++++++++++++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/s390/20200617.c

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 758315c0c72..bd49a897c76 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -13957,8 +13957,13 @@ s390_fix_long_loop_prediction (rtx_insn *insn)
   int distance;
 
   /* This will exclude branch on count and branch on index patterns
-     since these are correctly statically predicted.  */
-  if (!set
+     since these are correctly statically predicted.
+
+     The additional check for a PARALLEL is required here since
+     single_set might be != NULL for PARALLELs where the set of the
+     iteration variable is dead.  */
+  if (GET_CODE (PATTERN (insn)) == PARALLEL
+      || !set
       || SET_DEST (set) != pc_rtx
       || GET_CODE (SET_SRC(set)) != IF_THEN_ELSE)
     return false;
diff --git a/gcc/testsuite/gcc.target/s390/20200617.c 
b/gcc/testsuite/gcc.target/s390/20200617.c
new file mode 100644
index 00000000000..067d2e1d90b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/20200617.c
@@ -0,0 +1,23 @@
+/* This ICE'd before f9e1ea10e657af9fb02fafecf1a600740fd34409 because
+   a doloop pattern with a dead set of the iteration variable was
+   generated and s390_fix_long_loop_prediction then failed to
+   recognize it as branch on count pattern.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z10" } */
+
+int a, d, e, f;
+long b;
+long *volatile c;
+void
+fn1() {
+  for (; e; ++e)
+    if (d)
+      ;
+    else {
+      a = 0;
+      for (; a != 14; ++a)
+       *c = b && f;
+      d = 8;
+    }
+}
-- 
2.17.1

Reply via email to