This should fix PR51782 - we need to look at the base address operand of MEM_REF and TARGET_MEM_REF to get at the address-space information as both can have an embedded VIEW_CONVERT_EXPR. This is then consistent with the gimple type system which keeps address-space changing conversions of pointers in the IL.
Note that set_mem_attributes_minus_bitpos also looks broken in this regard as it requires that even explicit VIEW_CONVERT_EXPRs have the address-space encoded (or COMPONENT_REFs, too). I'm not sure that you get a proper TYPE_ADDR_SPACE from even s.i for struct S { int i; } s; but somebody with a target available could check that. Pointless bootstrap & regtest running on x86_64-unknown-linux-gnu. Richard. 2012-01-17 Richard Guenther <rguent...@suse.de> PR middle-end/51782 * expr.c (expand_assignment): Take address-space information from the address operand of MEM_REF and TARGET_MEM_REF. (expand_expr_real_1): Likewise. Index: gcc/expr.c =================================================================== *** gcc/expr.c (revision 183205) --- gcc/expr.c (working copy) *************** expand_assignment (tree to, tree from, b *** 4590,4596 **** if (TREE_CODE (to) == MEM_REF) { addr_space_t as ! = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (to, 1)))); tree base = TREE_OPERAND (to, 0); address_mode = targetm.addr_space.address_mode (as); op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL); --- 4590,4596 ---- if (TREE_CODE (to) == MEM_REF) { addr_space_t as ! = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (to, 0)))); tree base = TREE_OPERAND (to, 0); address_mode = targetm.addr_space.address_mode (as); op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL); *************** expand_assignment (tree to, tree from, b *** 4608,4614 **** } else if (TREE_CODE (to) == TARGET_MEM_REF) { ! addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (to)); struct mem_address addr; get_address_description (to, &addr); --- 4608,4615 ---- } else if (TREE_CODE (to) == TARGET_MEM_REF) { ! addr_space_t as ! = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (to, 0)))); struct mem_address addr; get_address_description (to, &addr); *************** expand_expr_real_1 (tree exp, rtx target *** 9253,9259 **** case TARGET_MEM_REF: { ! addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp)); struct mem_address addr; enum insn_code icode; unsigned int align; --- 9254,9261 ---- case TARGET_MEM_REF: { ! addr_space_t as ! = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))); struct mem_address addr; enum insn_code icode; unsigned int align; *************** expand_expr_real_1 (tree exp, rtx target *** 9288,9294 **** case MEM_REF: { addr_space_t as ! = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1)))); enum machine_mode address_mode; tree base = TREE_OPERAND (exp, 0); gimple def_stmt; --- 9290,9296 ---- case MEM_REF: { addr_space_t as ! = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))); enum machine_mode address_mode; tree base = TREE_OPERAND (exp, 0); gimple def_stmt;