From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7810) id A7BA43858D35; Fri, 9 Jun 2023 11:18:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A7BA43858D35 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686309485; bh=pTLFVubKkVnbYb6B/0dH3NsosuTNo5sGfYCA6iJ4o6g=; h=From:To:Subject:Date:From; b=fbTsp+Vc10ndyu3cdyNU5Igg6ZD2R6RjKq8avE5OqI9XKE87Ixj9l65BiSAcT1wW/ WnZEiDiD75e/EOU/GuBp7+iaRI9xy01feXJYWk9Ku2bZNQmt9BP8baaV5U4E3CnCdk +l7SIcp8yLFExou/HsqCvxxzCwuQ6iREucm9X3D0= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Alex Coplan To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-10852] arm: Fix ICE due to infinite splitting [PR109800] X-Act-Checkin: gcc X-Git-Author: Alex Coplan X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: 92293d71135f8a4ad4097e971122ce3153de73a8 X-Git-Newrev: 2d3b72cbbfe7fb38b0e3b8ef2119156cbce57488 Message-Id: <20230609111805.A7BA43858D35@sourceware.org> Date: Fri, 9 Jun 2023 11:18:05 +0000 (GMT) List-Id: https://gcc.gnu.org/g:2d3b72cbbfe7fb38b0e3b8ef2119156cbce57488 commit r11-10852-g2d3b72cbbfe7fb38b0e3b8ef2119156cbce57488 Author: Alex Coplan Date: Thu May 25 13:34:46 2023 +0100 arm: Fix ICE due to infinite splitting [PR109800] In r11-966-g9a182ef9ee011935d827ab5c6c9a7cd8e22257d8 we introduce a simplification to emit_move_insn that attempts to simplify moves of the form: (set (subreg:M1 (reg:M2 ...)) (constant C)) where M1 and M2 are of equal mode size. That is problematic for the splitter vfp.md:no_literal_pool_df_immediate in the arm backend, which tries to pun an lvalue DFmode pseudo into DImode and assign a constant to it with emit_move_insn, as the new transformation simply undoes this, and we end up splitting indefinitely. This patch changes things around in the arm backend so that we use a DImode temporary (instead of DFmode) and first load the DImode constant into the pseudo, and then pun the pseudo into DFmode as an rvalue in a reg -> reg move. I believe this should be semantically equivalent but avoids the pathalogical behaviour seen in the PR. gcc/ChangeLog: PR target/109800 * config/arm/arm.md (movdf): Generate temporary pseudo in DImode instead of DFmode. * config/arm/vfp.md (no_literal_pool_df_immediate): Rather than punning an lvalue DFmode pseudo into DImode, use a DImode pseudo and pun it into DFmode as an rvalue. gcc/testsuite/ChangeLog: PR target/109800 * gcc.target/arm/pure-code/pr109800.c: New test. (cherry picked from commit f5298d9969b4fa34ff3aecd54b9630e22b2984a5) Diff: --- gcc/config/arm/arm.md | 2 +- gcc/config/arm/vfp.md | 7 ++++--- gcc/testsuite/gcc.target/arm/pure-code/pr109800.c | 4 ++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 5d3f21b91c4..6b833d2cc10 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -7466,7 +7466,7 @@ && !arm_const_double_rtx (operands[1]) && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1]))) { - rtx clobreg = gen_reg_rtx (DFmode); + rtx clobreg = gen_reg_rtx (DImode); emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1], clobreg)); DONE; diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index c9f2f12b51e..374630d26f6 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -2128,7 +2128,7 @@ (define_insn_and_split "no_literal_pool_df_immediate" [(set (match_operand:DF 0 "s_register_operand" "=w") (match_operand:DF 1 "const_double_operand" "F")) - (clobber (match_operand:DF 2 "s_register_operand" "=r"))] + (clobber (match_operand:DI 2 "s_register_operand" "=r"))] "arm_disable_literal_pool && TARGET_VFP_BASE && !arm_const_double_rtx (operands[1]) @@ -2143,8 +2143,9 @@ unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32); ival |= (zext_hwi (buf[1 - order], 32) << 32); rtx cst = gen_int_mode (ival, DImode); - emit_move_insn (simplify_gen_subreg (DImode, operands[2], DFmode, 0), cst); - emit_move_insn (operands[0], operands[2]); + emit_move_insn (operands[2], cst); + emit_move_insn (operands[0], + simplify_gen_subreg (DFmode, operands[2], DImode, 0)); DONE; } ) diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr109800.c b/gcc/testsuite/gcc.target/arm/pure-code/pr109800.c new file mode 100644 index 00000000000..d797b790232 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pure-code/pr109800.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_hard_ok } */ +/* { dg-options "-O2 -march=armv7-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mbig-endian -mpure-code" } */ +double f() { return 5.0; }