[Bug middle-end/108031] riscv: Access of members of a global structure is not optimized in atomic operations

"cvs-commit at gcc dot gnu.org via Gcc-bugs" <[email protected]> Tue, 04 Aug 2026 13:20:25 +0000
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D108031

--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jeff Law <[email protected]>:

https://gcc.gnu.org/g:097d4a9311cfc4c41cd885ee63285ef072a0e8fa

commit r17-2932-g097d4a9311cfc4c41cd885ee63285ef072a0e8fa
Author: Shreya Munnangi <[email protected]>
Date:   Tue Aug 4 07:16:37 2026 -0600

    [RISC-V][PR target/108031] Expose address computations for atomic memory
operations

    This is a patch from Shreya that takes a step towards fixing pr108031.

    Access to objects in static storage requires a high/lo_sum pair on RISC=
-V.
    Often, but not always, the lo_sum expression can be folded into the act=
ual
    memory reference.  One of the common cases where it can *not* fold in is
atomic
    memory operations.  So if (for example) we access nearby fields in a
structure
    in static memory we'll often see

            lui     a5,%hi(s)
            li      a4,1
            addi    a5,a5,%lo(s)
            amoadd.w a0,a4,0(a5)
            lui     a5,%hi(s+4) <-- this should be: addi a5, a5, 4
            addi    a5,a5,%lo(s+4) <-- this should be removed
            amoadd.w a3,a4,0(a5)
            add     a0,a0,a3

    We'd like to replace the second lui+addi pair with a single addi.  That=
's
    normally a job for CSE, but due to implementation details of the RISC-V
atomics
    we're failing to even expose those addresses to CSE.

    The core issue is the predicates on these instructions are wider than t=
he
    constraints and as a result the lo_sum stays folded into the memory
reference
    until LRA realizes the constraints don't match and the lo_sum part of t=
he
    address computation gets reloaded.

    The fix is straightforward.  Tighten the operand predicates.  RISC-V on=
ly
    allows simple memory indirect operands for these instructions, yet
surprisingly
    we didn't have a predicate for that kind of address.  This patch adds an
    appropriate predicate, then uses it on the dozen or so relevant
    patterns/expanders.

    That's enough to expose the address calculation to CSE, schedulers, etc=
.=20
In my
    (Jeff's) opinion the patch stands as an independent improvement, even
though it
    doesn't fix 108031.  The next (and final) step to fix 108031 will most
likely
    be a costing model fix.  ie, CSE will do the right thing with the addre=
sses
are
    fully exposed, but it rejects the changes because the RISC-V cost model=
 is
    broken.

    This has been bootstrapped and regression tested on the c920.  K3 boots=
trap
&
    regression test was just about done when a cat went crazy behind my desk
and
    ultimately dislodged the power cable from the wall.   It's restarted, b=
ut
    results are now 9 hours out :(  riscv32-elf and riscv64-elf both worked
fine,
    of course.

    I'm pushing this to the trunk of Shreya's behalf.

            PR target/108031
    gcc
            * config/riscv/predicates.md (riscv_atomic_memory_operand): New
            predicate.
            * config/riscv/sync.md (<atomic_optab><mode> pattern and expand=
er):
            Use riscv_atomic_memory_operand.
            (amo_atomic_<atomic_optab><mode>): Likewise.
            (lrsc_atomic_<atomic_optab><mode>): Likewise.
            (atomic_fetch_<atomic_optab><mode): Likewise.
            (amo_atomic_fetch_<atomic_optab><mode>): Likewise.
            (lrsc_atomic_fetch_<atomic_optab><mode>): Likewise.
            (subword_atomic_fetch_strong_<atomic_optab>): Likewise.
            (atomic_fetch_nand<mode>): Likewise.
            (subword_atomic_fetch_strong_nand): Likewise.
            (zabha_atomic_fetch_<atomic_optab><mode>): Likewise.
            (lrsc_atomic_fetch_<atomic_optab><mode>): Likewise.
            (atomic_exchange<mode>): Likewise.
            (amo_atomic_exchange<mode>): Likewise.
            (amo_atomic_exchange<mode>_extended): Likewise.
            (lrsc_atomic_exchange<mode>): Likewise.
            (subword_atomic_exchange_strong): Likewise.
            (zacas_atomic_cas_value_strong<mode>): Likewise.
            (zalrsc_atomic_cas_value_strong<mode>): Likewise.
            (subword_atomic_cas_strong): Likewise.
            (atomic_test_and_set): Likewise.

    gcc/testsuite
            * gcc.target/riscv/pr108031.c: New test.=