https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126412
--- Comment #12 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Philipp Tomsich <[email protected]>: https://gcc.gnu.org/g:fc96e933de8d29f91ad7ab9cf982ad498bc5c9d0 commit r17-4485-gfc96e933de8d29f91ad7ab9cf982ad498bc5c9d0 Author: Konstantinos Eleftheriou <[email protected]> Date: Tue Sep 1 16:04:28 2026 +0200 fold-mem-offsets: Group changes by shared fold insns [PR126412] Once a fold insn's constant is folded into the memory offsets computed from it, the pass zeroes that constant. This is only correct if every root reached through the insn takes the compensating offset, so roots whose def-chains share a fold insn must be committed, or cancelled, as a unit. The changes were grouped by the register defined by the last fold insn of the def-chain, which misses a base add shared between chains that end in different registers. In the testcase, g_13, g_590 and g_253 are all reached through one section-anchor add, r0 = r7 + 976. The g_590 loads reach it via a second add and are grouped under r3, so committing them zeroes the shared add. The g_253 load is grouped under r0 and needs offset 1008, outside LDRSB's range, so its group is cancelled, but the zeroing survives: the g_13 and g_253 accesses are left at r7 + {4, 32} instead of r7 + {980, 1008}. Group the changes by the connected components of the roots that share a fold insn, maintained as a union-find, so that a root that cannot be updated rolls back its whole component. Also commit all surviving groups in one change_insns call, which removes the sort over the group keys. PR rtl-optimization/126412 gcc/ChangeLog: * fold-mem-offsets.cc (change_in_vec_p): Move before fold_groups. (changes_map_t): New type. (class fold_groups): New class. (struct regno_changes): Remove. (sort_pairs): Likewise. (cancel_changes_for_group): Take the fold group to cancel. (find_groups_to_cancel): Rename from find_keys_to_remove. (update_insns): Group the changes by fold group instead of by the register defined by the last fold insn of the def-chain. (fold_mem_offsets_1): Use fold_groups and commit all groups in a single change_insns call. gcc/testsuite/ChangeLog: * gcc.target/arm/pr126412.c: New test.
