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