https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84503
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The bug is in the way we handle overlapping stores. The problem is that all we do if there is overlap is: if (IN_RANGE (info->bitpos, merged_store->start, merged_store->start + merged_store->width - 1)) { /* Only allow overlapping stores of constants. */ if (info->rhs_code == INTEGER_CST && merged_store->stores[0]->rhs_code == INTEGER_CST) { merged_store->merge_overlapping (info); continue; } } otherwise we: /* |---store 1---| <gap> |---store 2---|. Gap between stores or the rhs not compatible. Start a new group. */ /* Try to apply all the stores recorded for the group to determine the bitpattern they write and discard it if that fails. This will also reject single-store groups. */ if (!merged_store->apply_stores ()) delete merged_store; else m_merged_store_groups.safe_push (merged_store); merged_store = new merged_store_group (info); But the statements here are sorted primarily by bitpos and we emit statements for the group at the location of the last statement (highest order) in the merged store group. So I think we need to check before adding another store if it is not rhs_code INTEGER_CST, whether there is any overlap with following stores. Overlap is fine if the order of all the overlapping statements is higher than MAX (merged_store->last_order, info->order), because then we know we'll start a new group right after info and the merged stores of the current group will come before any overlapping stores (whether merged successfully with something or not), but otherwise we just shouldn't add info into the current group.