Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2017-04-06  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/80262
        * tree-sra.c (build_ref_for_offset): Preserve address-space
        information.
        * tree-ssa-sccvn.c (vn_reference_maybe_forwprop_address):
        Drop useless address-space information on MEM_REF offsets.

        * gcc.target/i386/pr80262.c: New testcase.

Index: gcc/tree-sra.c
===================================================================
*** gcc/tree-sra.c      (revision 246724)
--- gcc/tree-sra.c      (working copy)
*************** build_ref_for_offset (location_t loc, tr
*** 1638,1643 ****
--- 1638,1650 ----
    unsigned HOST_WIDE_INT misalign;
    unsigned int align;
  
+   /* Preserve address-space information.  */
+   addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base));
+   if (as != TYPE_ADDR_SPACE (exp_type))
+     exp_type = build_qualified_type (exp_type,
+                                    TYPE_QUALS (exp_type)
+                                    | ENCODE_QUAL_ADDR_SPACE (as));
+ 
    gcc_checking_assert (offset % BITS_PER_UNIT == 0);
    get_object_alignment_1 (base, &align, &misalign);
    base = get_addr_base_and_unit_offset (base, &base_offset);
Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c        (revision 246724)
--- gcc/tree-ssa-sccvn.c        (working copy)
*************** vn_reference_maybe_forwprop_address (vec
*** 1233,1240 ****
              && tem[tem.length () - 2].opcode == MEM_REF)
            {
              vn_reference_op_t new_mem_op = &tem[tem.length () - 2];
!             new_mem_op->op0 = fold_convert (TREE_TYPE (mem_op->op0),
!                                             new_mem_op->op0);
            }
          else
            gcc_assert (tem.last ().opcode == STRING_CST);
--- 1233,1240 ----
              && tem[tem.length () - 2].opcode == MEM_REF)
            {
              vn_reference_op_t new_mem_op = &tem[tem.length () - 2];
!             new_mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0),
!                                                 new_mem_op->op0);
            }
          else
            gcc_assert (tem.last ().opcode == STRING_CST);
Index: gcc/testsuite/gcc.target/i386/pr80262.c
===================================================================
*** gcc/testsuite/gcc.target/i386/pr80262.c     (nonexistent)
--- gcc/testsuite/gcc.target/i386/pr80262.c     (working copy)
***************
*** 0 ****
--- 1,26 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2" } */
+ 
+ typedef struct {
+   int v;
+ } S1;
+ S1 clearS1 () { S1 s1 = { 0 }; return s1; }
+  
+ typedef struct {
+   S1 s1[4];
+ } S2;
+ void clearS2 (__seg_gs S2* p, int n) {
+   for (int i = 0; i < n; ++i)
+     p->s1[i] = clearS1 ();
+ }
+  
+ typedef struct {
+   int pad;
+   S2 s2;
+ } S3;
+  
+ long int BASE;
+  
+ void fn1(int n) {
+   clearS2 (&(((__seg_gs S3*)(BASE))->s2), n);
+ }

Reply via email to