https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259
--- Comment #30 from Martin Sebor <msebor at gcc dot gnu.org> --- (In reply to Bernd Edlinger from comment #28) > > Can someone explain why the example in comment #21 works when > pointer arithmentic instead of integer arithmetic is used? Because the optimization (making use of the size of the referenced array) doesn't apply in the pointer case. In the integer case, ccp simplifies the strlen argument to a COMPONENT_REF: Visiting statement: _2 = sp_ip_9 + 4; which is likely CONSTANT Match-and-simplified sp_ip_9 + 4 to bp.0_1 Lattice value changed to CONSTANT bp.0_1. Adding SSA edges to worklist. marking stmt to be not simulated again Visiting statement: _3 = (const char *) _2; which is likely CONSTANT Match-and-simplified (const char *) _2 to &u.s.b Lattice value changed to CONSTANT &u.s.b. Adding SSA edges to worklist. marking stmt to be not simulated again The COMPONENT_REF fully describes the structure of an access to a member and so lends itself to interesting analysis which then opens up opportunities for both optimization and bug detection (e.g., buffer overflow). In the pointer case ccp replaces the argument with with a MEM_REF: Visiting statement: _1 = sp_ip_7 + 4; which is likely CONSTANT Lattice value changed to CONSTANT &MEM[(void *)&u + 4B]. Adding SSA edges to worklist. marking stmt to be not simulated again A ME_REF is a concise but low-level way of referencing memory via a base address an an offset. It doesn't include reliable information about the structure of the referenced memory. It's easier to do some basic things with but much harder to use for interesting, higher level analysis. By folding expressions into MEM_REF early on, GCC effectively disables subsequent optimizations that are designed to do interesting things at a higher level.