From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2049) id BED0A3838008; Fri, 6 May 2022 14:43:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BED0A3838008 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="utf-8" From: Matthew Malcomson To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/morello)] lra: Fix reloading of addresses in atomic ops [PR105395] X-Act-Checkin: gcc X-Git-Author: Richard Sandiford X-Git-Refname: refs/vendors/ARM/heads/morello X-Git-Oldrev: d2006d5de48b5e3c1d6062e095c0eef5e8e23242 X-Git-Newrev: 0e772ce07fca9e57503dbbc47914280bb727fe72 Message-Id: <20220506144324.BED0A3838008@sourceware.org> Date: Fri, 6 May 2022 14:43:24 +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: Fri, 06 May 2022 14:43:24 -0000 https://gcc.gnu.org/g:0e772ce07fca9e57503dbbc47914280bb727fe72 commit 0e772ce07fca9e57503dbbc47914280bb727fe72 Author: Richard Sandiford Date: Tue Apr 26 12:34:15 2022 +0100 lra: Fix reloading of addresses in atomic ops [PR105395] If the result of an atomic operation becomes a hard register before reload, and if that hard register conflicts with the allocated address of the atomic operation, we can end up reloading the whole atomic memory instead of the address. I saw this “in the wild” with some later changes, because a combine opportunity on the input triggered a three-way combination with a following hard-register move. The problem was that lra-constraints.c only set offmemok if the memory didn't “win” (i.e. if the memory didn't satisfy the constraints in its original form). The memory here is OK in its original form. Later on the function detected the conflict and marked the memory as no longer winning: if (HARD_REGISTER_P (operand_reg[i]) || (first_conflict_j == last_conflict_j && operand_reg[last_conflict_j] != NULL_RTX && !curr_alt_match_win[last_conflict_j] && !HARD_REGISTER_P (operand_reg[last_conflict_j]))) { curr_alt_win[last_conflict_j] = false; But because offmemok was false, this led to a reload of the full memory rather than its address. Diff: --- gcc/lra-constraints.c | 5 +-- gcc/testsuite/gcc.dg/rtl/aarch64/atomic-reload-1.c | 45 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index a4d975fb210..54753b54d0d 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -2051,7 +2051,6 @@ process_alt_operands (int only_alternative) enum reg_class this_alternative, this_costly_alternative; HARD_REG_SET this_alternative_set, this_costly_alternative_set; bool this_alternative_match_win, this_alternative_win; - bool this_alternative_offmemok; bool scratch_p; machine_mode mode; enum constraint_num cn; @@ -2088,7 +2087,6 @@ process_alt_operands (int only_alternative) CLEAR_HARD_REG_SET (this_costly_alternative_set); this_alternative_win = false; this_alternative_match_win = false; - this_alternative_offmemok = false; this_alternative_matches = -1; /* An empty constraint should be excluded by the fast @@ -2579,7 +2577,6 @@ process_alt_operands (int only_alternative) reject -= 3; } - this_alternative_offmemok = offmemok; if (this_costly_alternative != NO_REGS) { if (lra_dump_file != NULL) @@ -2920,7 +2917,7 @@ process_alt_operands (int only_alternative) curr_alt_set[nop] = this_alternative_set; curr_alt_win[nop] = this_alternative_win; curr_alt_match_win[nop] = this_alternative_match_win; - curr_alt_offmemok[nop] = this_alternative_offmemok; + curr_alt_offmemok[nop] = offmemok; curr_alt_matches[nop] = this_alternative_matches; if (this_alternative_matches >= 0 diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/atomic-reload-1.c b/gcc/testsuite/gcc.dg/rtl/aarch64/atomic-reload-1.c new file mode 100644 index 00000000000..76ab15f93d3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/rtl/aarch64/atomic-reload-1.c @@ -0,0 +1,45 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2 -fdisable-rtl-dse1 -fdisable-rtl-dse2 -mno-fake-capability" } */ + +int __RTL (startwith ("vregs")) f1 (int *ptr, int val) +{ +(function "f1" + (param "ptr" + (DECL_RTL (reg/v:DI <1> [ ptr ])) + (DECL_RTL_INCOMING (reg:DI x0 [ ptr ])) + ) + (param "val" + (DECL_RTL (reg/v:SI <2> [ val ])) + (DECL_RTL_INCOMING (reg:SI x1 [ val ])) + ) + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 1 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cnote 2 NOTE_INSN_FUNCTION_BEG) + (cinsn 3 + (parallel + [(set (reg:SI x0) (mem/v:SI (reg:DI x0) [-1 S4 A32])) + (set (mem/v:SI (reg:DI x0) [-1 S4 A32]) + (unspec_volatile:SI + [(plus:SI (mem/v:SI (reg:DI x0) [-1 S4 A32]) + (reg:SI <2>)) + (const_int 32773)] + UNSPECV_ATOMIC_OP)) + (clobber (reg:CC cc)) + (clobber (scratch:SI)) + (clobber (scratch:SI))] + ) + ) + (cinsn 4 (use (reg:SI x0))) + (edge-to exit (flags "FALLTHRU")) + ) + ) + (crtl (return_rtx (reg:SI x0))) +) +} + +/* { dg-final { scan-assembler-not {\tldr\t} } } */ +/* { dg-final { scan-assembler-not {\tstr\t} } } */ +/* { dg-final { scan-assembler-not {sp, } } } */