https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109720
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- We complain about the m_num_bits read. While PRE isolates it to BB3 even before PRE that happens unconditionally: <bb 2> [local count: 118111600]: nbits ={v} {CLOBBER}; _25 = MEM[(const struct DynamicBitSet &)&set]._size; nbits._size = _25; if (_25 <= 64) goto <bb 3>; [67.00%] else goto <bb 4>; [33.00%] <bb 3> [local count: 79134772]: _162 = MEM[(const struct DynamicBitSet &)&set].D.151332._fixedSizeBitSet; nbits.D.151332._fixedSizeBitSet = _162; goto <bb 13>; [100.00%] ... <bb 12> [local count: 56691384]: _46 = (long unsigned int) _40; _47 = iftmp.2_49 + _46; MEM[(struct vector *)&nbits + 8B].D.150855._M_impl.D.150172._M_finish = _47; _29 = MEM[(const struct dynamic_bitset &)&set + 8].m_num_bits; MEM[(struct dynamic_bitset *)&nbits + 8B].m_num_bits = _29; _60 = boost::dynamic_bitset<>::m_do_find_from (&nbits.D.151332._dynamicBitSet, 0); if (_60 != 18446744073709551615) goto <bb 13>; [66.92%] else goto <bb 33>; [33.08%] <bb 13> [local count: 103222856]: # _63 = PHI <_60(12), _25(3)> _68 = MEM[(const struct dynamic_bitset *)&nbits + 8B].m_num_bits; PRE just sees the partial redundancy on the edge from BB12. The read is from dynamic_bitset<Block, Allocator>::to_ulong(). It _looks_ like that maybe the range-for handling code exposes this in a way that doesn't properly short-cut this read (or that GCC short-circuits a test there). Difficult to identify in the preprocessed sources.