On Tue, Oct 13, 2026 at 10:44 AM Vineet Gupta <[email protected]> wrote:
>
> With -ffuse-ops-with-volatile-access general_operand accepts volatile
> MEMs during combine. For "int a = x; int b = y; return a < b;" with
> volatile x and y, combine first merges the load of y into the compare
> and then the load of x, giving (compare (mem/v x) (mem/v y)). The
> operands of one insn are unordered and LRA loads y first, so the two
> sequenced volatile reads are reordered. can_combine_p checks insns
> between INSN and I3 for volatile references, but not I3 itself.
>
> Refuse to combine an insn that reads volatile memory directly into an
> I3 whose source already reads volatile memory. A volatile store in I3
> is still allowed, so read-modify-write forms are unaffected.
>
> Bootstrapped and regression tested on x86_64-linux-gnu and aarch64-linux-gnu.
>
> PR rtl-optimization/127851
>
> gcc/ChangeLog:
>
> * combine.cc (can_combine_p): Don't combine an insn that reads
> volatile memory directly into an I3 whose source already reads
> volatile memory.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/aarch64/volatile-fuse-order-1.c: New test.
> * gcc.target/aarch64/volatile-fuse-order-2.c: New test.
> * gcc.target/i386/volatile-fuse-order-1.c: New test.
> * gcc.target/i386/volatile-fuse-order-2.c: New test.
> * gcc.target/i386/volatile-fuse-order-3.c: New test.
All x86 check function bodies can be generalized to also check bodies
on 32-bit targets. Mainly just "movl x(%rip), %eax" vs. "movl x,
%eax" and
movl (%eax), %edx
cmpl (%eax), %edx
vs.
movl (%rdi), %eax
cmpl (%rdi), %eax
Uros.