https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79690
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- This is similar to PR66768 but is somewhat special because the vectorizer generates <mem_ref 0x7ffff69fcaf0 type <vector_type 0x7ffff69c3738 type <integer_type 0x7ffff68ba348 unsigned char public unsigned string-flag QI size <integer_cst 0x7ffff68a2dc8 constant 8> unit size <integer_cst 0x7ffff68a2de0 constant 1> align 8 symtab 0 alias set -1 canonical type 0x7ffff68ba348 precision 8 min <integer_cst 0x7ffff68a2df8 0> max <integer_cst 0x7ffff68a2d98 255>> unsigned V16QI size <integer_cst 0x7ffff68a2d20 constant 128> unit size <integer_cst 0x7ffff68a2d38 constant 16> align 128 symtab 0 alias set 0 canonical type 0x7ffff69c3738 nunits 16 pointer_to_this <pointer_type 0x7ffff69c3c78>> arg 0 <ssa_name 0x7ffff6a00828 type <pointer_type 0x7ffff69c31f8 type <vector_type 0x7ffff69c3150 address-space-2> thus the address-space is _only_ on the pointer operand (generally RTL expansion looks at the reference type, MEM_REF and TARGET_MEM_REF are special-cased though). And IVOPTs does: 7395 ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p), &aff, 7396 reference_alias_ptr_type (*use->op_p), 7397 iv, base_hint, data->speed); 7398 copy_ref_info (ref, *use->op_p); and TREE_TYPE (*use->op_p) is the type of the reference, not the pointer type of the base (and create_mem_ref builds a "bogus" pointer type from that). The issue is that addr-to-parts via move_hint_to_base builds a new pointer type, converting the pointer to the generic address-space. In this case it's a matter of preserving the correct info: Index: gcc/tree-ssa-address.c =================================================================== --- gcc/tree-ssa-address.c (revision 245681) +++ gcc/tree-ssa-address.c (working copy) @@ -435,7 +435,7 @@ move_fixed_address_to_symbol (struct mem /* If ADDR contains an instance of BASE_HINT, move it to PARTS->base. */ static void -move_hint_to_base (tree type, struct mem_address *parts, tree base_hint, +move_hint_to_base (struct mem_address *parts, tree base_hint, aff_tree *addr) { unsigned i; @@ -455,13 +455,7 @@ move_hint_to_base (tree type, struct mem if (i == addr->n) return; - /* Cast value to appropriate pointer type. We cannot use a pointer - to TYPE directly, as the back-end will assume registers of pointer - type are aligned, and just the base itself may not actually be. - We use void pointer to the type's address space instead. */ - qual = ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (type)); - type = build_qualified_type (void_type_node, qual); - parts->base = fold_convert (build_pointer_type (type), val); + parts->base = val; aff_combination_remove_elt (addr, i); } @@ -663,7 +657,7 @@ addr_to_parts (tree type, aff_tree *addr there is no reliable way how to distinguish between pointer and its offset, this is just a guess. */ if (!parts->symbol && base_hint) - move_hint_to_base (type, parts, base_hint, addr); + move_hint_to_base (parts, base_hint, addr); if (!parts->symbol && !parts->base) move_pointer_to_base (parts, addr);