From: Andreas Krebbel Date: Wed, 17 Jun 2020 15:10:05 +0000 (+0200) Subject: IBM Z: Prevent mach optimization on doloop patterns X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=914eadfe86a0400e0e378819001c785ecb30aab2;p=gcc.git IBM Z: Prevent mach optimization on doloop patterns 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. 2020-06-17 Andreas Krebbel gcc/ * config/s390/s390.c (s390_fix_long_loop_prediction): Exit early for PARALLELs. gcc/testsuite/ * gcc.target/s390/20200617.c: New test. --- 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; + } +}