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);