public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug rtl-optimization/105395] New: Invalid reload of atomic operation
@ 2022-04-26 12:25 rsandifo at gcc dot gnu.org
  0 siblings, 0 replies; only message in thread
From: rsandifo at gcc dot gnu.org @ 2022-04-26 12:25 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105395

            Bug ID: 105395
           Summary: Invalid reload of atomic operation
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rsandifo at gcc dot gnu.org
  Target Milestone: ---
            Target: aarch64*-*-*

There is an element of “doctor it hurts if I do this” here, but:
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 combine opportunity with
a following hard-register move.  But it could happen in other
cases too.

Brute-force test case that doesn't rely on RA:

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)))
)
}

which with -O2 gives:

f1:
        sub     sp, sp, #16
        ldr     w0, [x0]
        add     x4, sp, 12
        mov     w1, 0
        str     w0, [sp, 12]
.L3:
        ldxr    w0, [x4]
        add     w2, w0, w1
        stlxr   w3, w2, [x4]
        cbnz    w3, .L3
        dmb     ish
        ldr     w1, [sp, 12]
        str     w1, [x0]
        add     sp, sp, 16
        ret

I think the problem is that lra-constraints.c only sets offmemok
if the memory doesn't “win” (i.e. if the memory doesn't satisfy
the constraints in its original form).  The memory here is OK
in its original form.  Later on the function detects the conflict
and marks 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 is false, this leads to a reload of the full memory
rather than its address.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-04-26 12:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-26 12:25 [Bug rtl-optimization/105395] New: Invalid reload of atomic operation rsandifo at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).