Hi, On Tue, Apr 03, 2012 at 11:02:11AM +0200, Eric Botcazou wrote: > > Yeah, that sounds reasonable. > > There is a further subtlety in the second temp allocation when the expression > doesn't use the alias set of its type. In that case, we cannot pass the type > to set_mem_attributes. In fact, since assign_stack_temp_for_type already > calls the appropriate set_mem_* routines, the best thing to do might be to > remove the call to set_mem_attributes altogether in that case. >
So, something like this? Bootstrapped and tested on x86_64-linux and ia64-linux, I'm currently having problems bootsrapping sparc64 which is what I need this mainly for but those are unelated and this should help. Thanks, Martin 2012-04-03 Martin Jambor <mjam...@suse.cz> * expr.c (expand_expr_real_1): Pass type, not the expression, to set_mem_attributes for a memory temporary. Do not call the function for temporaries with a different alias set. Index: src/gcc/expr.c =================================================================== --- src.orig/gcc/expr.c +++ src/gcc/expr.c @@ -9572,6 +9572,7 @@ expand_expr_real_1 (tree exp, rtx target tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1, &unsignedp, &volatilep, true); rtx orig_op0, memloc; + bool mem_attrs_from_type = false; /* If we got back the original object, something is wrong. Perhaps we are evaluating an expression too early. In any event, don't @@ -9677,6 +9678,7 @@ expand_expr_real_1 (tree exp, rtx target memloc = assign_temp (nt, 1, 1, 1); emit_move_insn (memloc, op0); op0 = memloc; + mem_attrs_from_type = true; } if (offset) @@ -9849,7 +9851,6 @@ expand_expr_real_1 (tree exp, rtx target emit_move_insn (new_rtx, op0); op0 = copy_rtx (new_rtx); PUT_MODE (op0, BLKmode); - set_mem_attributes (op0, exp, 1); } return op0; @@ -9870,7 +9871,14 @@ expand_expr_real_1 (tree exp, rtx target if (op0 == orig_op0) op0 = copy_rtx (op0); - set_mem_attributes (op0, exp, 0); + /* If op0 is a temporary because of forcing to memory, pass only the + type to set_mem_attributes so that the original expression is never + marked as ADDRESSABLE through MEM_EXPR of the temporary. */ + if (mem_attrs_from_type) + set_mem_attributes (op0, TREE_TYPE (exp), 0); + else + set_mem_attributes (op0, exp, 0); + if (REG_P (XEXP (op0, 0))) mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));