https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64715
--- Comment #19 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #14) > Or, as discussed on IRC we can consider MEM_REFs where first operand isn't > just > SSA_NAME or ADDR_EXPR of a decl, but allow also ADDR_EXPR of > handled_component_p (with base being a decl or MEM_REF with SSA_NAME first > operand). > > Or add a new tree code, like OFFSETTED_ADDR_EXPR which would be like > ADDR_EXPR, but with integer offset address to the ADDR_EXPR. Thinking about this some more we already have the ability to combine _2 = &a.b[i].c; _3 = _2 + 8; by using handled-components: &ARRAY_REF <VIEW_CONVERT_EXPR <(__typeof__ (a.b[i].c)[])&a.b[i].c>, 8 / __sizeof__(a.b[i].c)> that is, we could attack this by implementing pointer arithmetic as represented by the frontend in the way it is defined by the C standard (in terms of array indexing). ptr + idx would be lowered as &ARRAY_REF <VIEW_CONVERT_EXPR <(__typeof__ (*ptr) []) *ptr>, idx> thereby also avoiding the need to apply promotion of idx to sizetype to avoid the possible overflow of the multiplication by sizeof (*ptr). Of course it would be nice to avoid the "awkward" VIEW_CONVERT_EXPR here, but adding a new kind of handled-component isn't exactly non-intrusive either. Btw, there is an alternative to the array-ref/view-convert-expr form that is less restrictive on the actual 'idx'. We could simply use COMPONENT_REF <*ptr, <NULL field-decl>, explicit-offset> though the fact that COMPONENT_REFs have alias analysis effects and that the lowered offset is measured in DECL_OFFSET_ALIGN units of the field-decl makes that non-trivial to support as well. That said, the alternative is to add a new handled-component, say, OFFSET_VIEW_CONVERT_EXPR <type, base, offset>, that would have the same effect as doing _ptr = &base + offset; MEM [_ptr, offset]; thus offset carries type-based alias information and 'type' carries alignment info. Type-based alias analysis would stop at OFFSET_VIEW_CONVERT_EXPR as it stops now at VIEW_CONVERT_EXPRs. Now we could also simply change VIEW_CONVERT_EXPR to take an (optional?) offset parameter. I like all of the above choices more than special-casing an address-only variant for offsets. All of the above enable us to avoid making variable-indexed indirect references addressable like we have to do now because of the restrictions of MEM_REF bases / offsets. The ARRAY_REF variant allows to handle non-constant pointer offsets as well while the offsetted VIEW_CONVERT_EXPR would handle only constant offsets (but allow non-"element"-size increments and arbitrary effective alias sets on the memory reference). We should already handle the ARRAY_REF <VIEW_CONVERT_EXPR <...> ...> form correctly today, we just don't create it.