From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id 171E0383800D; Tue, 10 May 2022 08:25:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 171E0383800D MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jakub Jelinek To: gcc-cvs@gcc.gnu.org Subject: [gcc r10-10694] ifcvt: Punt if not onlyjump_p for find_if_case_{1, 2} [PR104814] X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/releases/gcc-10 X-Git-Oldrev: 7a4db01ba8171e5f7b82cb5a36e0a6cbb6e996a0 X-Git-Newrev: 1ebc65fde4dd30678da10a17c6cc29bc4e1e041e Message-Id: <20220510082510.171E0383800D@sourceware.org> Date: Tue, 10 May 2022 08:25:10 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 May 2022 08:25:10 -0000 https://gcc.gnu.org/g:1ebc65fde4dd30678da10a17c6cc29bc4e1e041e commit r10-10694-g1ebc65fde4dd30678da10a17c6cc29bc4e1e041e Author: Jakub Jelinek Date: Tue Mar 15 09:12:03 2022 +0100 ifcvt: Punt if not onlyjump_p for find_if_case_{1,2} [PR104814] find_if_case_{1,2} implicitly assumes conditional jumps and rewrites them, so if they have extra side-effects or are say asm goto, things don't work well, either the side-effects are lost or we could ICE. In particular, the testcase below on s390x has there a doloop instruction that decrements a register in addition to testing it for non-zero and conditionally jumping based on that. The following patch fixes that by punting for !onlyjump_p case, i.e. if there are side-effects in the jump instruction or it isn't a plain PC setter. Also, it assumes BB_END (test_bb) will be always non-NULL, because basic blocks with 2 non-abnormal successor edges should always have some instruction at the end that determines which edge to take. 2022-03-15 Jakub Jelinek PR rtl-optimization/104814 * ifcvt.c (find_if_case_1, find_if_case_2): Punt if test_bb doesn't end with onlyjump_p. Assume BB_END (test_bb) is always non-NULL. * gcc.c-torture/execute/pr104814.c: New test. (cherry picked from commit a2645cd8fb33b36d737b310e26f4c47401305c7b) Diff: --- gcc/ifcvt.c | 14 ++++++++---- gcc/testsuite/gcc.c-torture/execute/pr104814.c | 30 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 4baf07a7e97..5fcd09fc78f 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -4903,14 +4903,17 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge) if ((BB_END (then_bb) && JUMP_P (BB_END (then_bb)) && CROSSING_JUMP_P (BB_END (then_bb))) - || (BB_END (test_bb) - && JUMP_P (BB_END (test_bb)) + || (JUMP_P (BB_END (test_bb)) && CROSSING_JUMP_P (BB_END (test_bb))) || (BB_END (else_bb) && JUMP_P (BB_END (else_bb)) && CROSSING_JUMP_P (BB_END (else_bb)))) return FALSE; + /* Verify test_bb ends in a conditional jump with no other side-effects. */ + if (!onlyjump_p (BB_END (test_bb))) + return FALSE; + /* THEN has one successor. */ if (!single_succ_p (then_bb)) return FALSE; @@ -5024,14 +5027,17 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) if ((BB_END (then_bb) && JUMP_P (BB_END (then_bb)) && CROSSING_JUMP_P (BB_END (then_bb))) - || (BB_END (test_bb) - && JUMP_P (BB_END (test_bb)) + || (JUMP_P (BB_END (test_bb)) && CROSSING_JUMP_P (BB_END (test_bb))) || (BB_END (else_bb) && JUMP_P (BB_END (else_bb)) && CROSSING_JUMP_P (BB_END (else_bb)))) return FALSE; + /* Verify test_bb ends in a conditional jump with no other side-effects. */ + if (!onlyjump_p (BB_END (test_bb))) + return FALSE; + /* ELSE has one successor. */ if (!single_succ_p (else_bb)) return FALSE; diff --git a/gcc/testsuite/gcc.c-torture/execute/pr104814.c b/gcc/testsuite/gcc.c-torture/execute/pr104814.c new file mode 100644 index 00000000000..7d4f8ab4b8c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr104814.c @@ -0,0 +1,30 @@ +/* PR rtl-optimization/104814 */ + +short a = 0; +static long b = 0; +int c = 7; +char d = 0; +short *e = &a; +long f = 0; + +unsigned long +foo (unsigned long h, long j) +{ + return j == 0 ? h : h / j; +} + +int +main () +{ + long k = f; + for (; c; --c) + { + for (int i = 0; i < 7; ++i) + ; + long m = foo (f, --b); + d = ((char) m | *e) <= 43165; + } + if (b != -7) + __builtin_abort (); + return 0; +}