Hi, PR 51782 showed that COMPONENT_REFs created by SRA got expanded with a wrong address space because the address space was not specified in the type of the whole tree. This is however inconsistent with how we encode address spaces in MEM_REFs where they are supposed to be stored in the type of its address operand (as opposed to the type of the reference). Therefore the following patch changes the expansion to always look at the base address and look through MEM_REFs if necessary.
It fixes the issue for me on a cross compiler, a bootstrap and testsuite run on x86_64-linux showed only regressions described in PR 52297 so I consider it successful. My understanding is that Richi approved it in bugzilla. Georg-Johann Lay said he would test it on HW or simulator that actually uses address spaces and he has also already committed a testcase for this bug. Therefore I intend to commit the patch if his tests pass too. Thanks, Martin 2012-02-20 Martin Jambor <mjam...@suse.cz> PR tree-optimizaion/51782 * emit-rtl.c (set_mem_attributes_minus_bitpos): Set address space according to the base object. Index: src/gcc/emit-rtl.c =================================================================== --- src.orig/gcc/emit-rtl.c 2012-02-13 14:52:28.000000000 +0100 +++ src/gcc/emit-rtl.c 2012-02-20 18:35:03.000000000 +0100 @@ -1548,6 +1548,7 @@ set_mem_attributes_minus_bitpos (rtx ref HOST_WIDE_INT apply_bitpos = 0; tree type; struct mem_attrs attrs, *defattrs, *refattrs; + addr_space_t as; /* It can happen that type_for_mode was given a mode for which there is no language-level type. In which case it returns NULL, which @@ -1681,17 +1682,29 @@ set_mem_attributes_minus_bitpos (rtx ref MEM_NOTRAP_P (ref) = !tree_could_trap_p (t); base = get_base_address (t); - if (base && DECL_P (base) - && TREE_READONLY (base) - && (TREE_STATIC (base) || DECL_EXTERNAL (base)) - && !TREE_THIS_VOLATILE (base)) - MEM_READONLY_P (ref) = 1; - - /* Mark static const strings readonly as well. */ - if (base && TREE_CODE (base) == STRING_CST - && TREE_READONLY (base) - && TREE_STATIC (base)) - MEM_READONLY_P (ref) = 1; + if (base) + { + if (DECL_P (base) + && TREE_READONLY (base) + && (TREE_STATIC (base) || DECL_EXTERNAL (base)) + && !TREE_THIS_VOLATILE (base)) + MEM_READONLY_P (ref) = 1; + + /* Mark static const strings readonly as well. */ + if (TREE_CODE (base) == STRING_CST + && TREE_READONLY (base) + && TREE_STATIC (base)) + MEM_READONLY_P (ref) = 1; + + if (TREE_CODE (base) == MEM_REF + || TREE_CODE (base) == TARGET_MEM_REF) + as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (base, + 0)))); + else + as = TYPE_ADDR_SPACE (TREE_TYPE (base)); + } + else + as = TYPE_ADDR_SPACE (type); /* If this expression uses it's parent's alias set, mark it such that we won't change it. */ @@ -1830,6 +1843,8 @@ set_mem_attributes_minus_bitpos (rtx ref attrs.align = MAX (attrs.align, obj_align); } } + else + as = TYPE_ADDR_SPACE (type); /* If we modified OFFSET based on T, then subtract the outstanding bit position offset. Similarly, increase the size of the accessed @@ -1843,7 +1858,7 @@ set_mem_attributes_minus_bitpos (rtx ref } /* Now set the attributes we computed above. */ - attrs.addrspace = TYPE_ADDR_SPACE (type); + attrs.addrspace = as; set_mem_attrs (ref, &attrs); }