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

Reply via email to