From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id 24062383AB59; Fri, 16 Dec 2022 09:20:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 24062383AB59 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1671182435; bh=BeFXJi4s1/2wI2BtE2rQwdgBc1SAlGF4XEP9e5Y1KI4=; h=From:To:Subject:Date:From; b=qmYHgHBzUGbPah8OhhQHUsxwIvu5l46E0zGMAoPMPIE/b6Ttaaik2Kp2IiGILO/g6 y3hMw3uJONQKpaBeleamz7CjcCNFYh5oU9tWlIV7DDrSmZgTWHu8ijlIMovrbEUK4V OKRaUChLvsVpipTSVpxC7TdHf9C68ZKqVKpZCouA= 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 r13-4739] loop-invariant: Split preheader edge if the preheader bb ends with jump [PR106751] X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/master X-Git-Oldrev: 711e0acdbb2645f5a8aa89014488c24e89ccb0f7 X-Git-Newrev: ddcaa60983b50378bde1b7e327086fe0ce101795 Message-Id: <20221216092035.24062383AB59@sourceware.org> Date: Fri, 16 Dec 2022 09:20:35 +0000 (GMT) List-Id: https://gcc.gnu.org/g:ddcaa60983b50378bde1b7e327086fe0ce101795 commit r13-4739-gddcaa60983b50378bde1b7e327086fe0ce101795 Author: Jakub Jelinek Date: Fri Dec 16 10:19:22 2022 +0100 loop-invariant: Split preheader edge if the preheader bb ends with jump [PR106751] The RTL loop passes only request simple preheaders, but don't require fallthru preheaders, while move_invariant_reg apparently assumes the latter, that it can just append instruction(s) to the end of the preheader basic block. The following patch fixes that by splitting the preheader edge if the preheader bb ends with a JUMP_INSN (asm goto in this case). Without that we get control flow in the middle of a bb. 2022-12-16 Jakub Jelinek PR rtl-optimization/106751 * loop-invariant.cc (move_invariant_reg): If preheader bb ends with a JUMP_INSN, split the preheader edge and emit invariants into the new preheader basic block. * gcc.c-torture/compile/pr106751.c: New test. Diff: --- gcc/loop-invariant.cc | 2 ++ gcc/testsuite/gcc.c-torture/compile/pr106751.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/gcc/loop-invariant.cc b/gcc/loop-invariant.cc index f3248540fb1..9b5f6cd3223 100644 --- a/gcc/loop-invariant.cc +++ b/gcc/loop-invariant.cc @@ -1837,6 +1837,8 @@ move_invariant_reg (class loop *loop, unsigned invno) else if (dump_file) fprintf (dump_file, "Invariant %d moved without introducing a new " "temporary register\n", invno); + if (JUMP_P (BB_END (preheader))) + preheader = split_edge (loop_preheader_edge (loop)); reorder_insns (inv->insn, inv->insn, BB_END (preheader)); df_recompute_luids (preheader); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106751.c b/gcc/testsuite/gcc.c-torture/compile/pr106751.c new file mode 100644 index 00000000000..5fbf93bd332 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr106751.c @@ -0,0 +1,17 @@ +/* PR rtl-optimization/106751 */ + +int *foo (void); + +void +bar (void) +{ + asm goto ("" : : : : lab); + __builtin_unreachable (); +lab: + while (1) + { + int o; + asm ("" : "=r" (o) : "g" (1)); + *foo () = o; + } +}