Re: [PATCH 2/2] pair-fusion: Verify that a fused pair really is adjacent
Richard Biener <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
On Fri, 7 Aug 2026, [email protected] wrote: > From: Kyrylo Tkachov <[email protected]> > > fuse_pair addresses the second arm of a pair as the first plus the access size. > For a pair found through a MEM_EXPR base that distance comes from the MEM_EXPR > offsets rather than from the addresses, so two objects sharing one MEM_EXPR > read as adjacent when they are not, and the second access is redirected into > the first object. That is how PR121957, PR123625 and PR126405 each became > wrong code, in each case silently. > > When both accesses already use the same base register, which is what two stack > slots give, their offsets relative to that base are computed here anyway, so > compare them. A break in the invariant out-of-SSA maintains is then an ICE in > the pass that acts on it, whichever producer let it through. > > Bootstrapped and tested on aarch64-none-linux-gnu. > Ok for trunk? OK > Thanks, > Kyrill > > gcc/ChangeLog: > > * pair-fusion.cc (pair_fusion_bb_info::fuse_pair): Check that the > two arms of the pair are one access size apart. > > Signed-off-by: Kyrylo Tkachov <[email protected]> > --- > gcc/pair-fusion.cc | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/gcc/pair-fusion.cc b/gcc/pair-fusion.cc > index 915497c97d3..03a64c226ef 100644 > --- a/gcc/pair-fusion.cc > +++ b/gcc/pair-fusion.cc > @@ -1786,6 +1786,13 @@ pair_fusion_bb_info::fuse_pair (bool load_p, > gcc_checking_assert (base_regno == REGNO (base)); > } > > + // The pair insn addresses its second arm as the first plus ACCESS_SIZE, so > + // the two accesses have to be that far apart for real. A pair found through > + // a MEM_EXPR base is only as good as that base: two objects sharing one > + // MEM_EXPR look adjacent when they are not, and the second access then > + // lands in the first object. Catch that here rather than in the output. > + gcc_checking_assert (known_eq (offsets[1], offsets[0] + access_size)); > + > // If either of the original insns had writeback, but the resulting pair insn > // does not (can happen e.g. in the load pair edge case above, or if the > // writeback effects cancel out), then drop the def (s) of the base register > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)