This is an automated email from the git hooks/post-receive script.
unknown user pushed a commit to branch aoliva/pr64164 in repository gcc.
commit 143090f5c0071e0de9118748c4d7611bd6e01e31 Author: Alexandre Oliva aoliva@redhat.com Date: Wed Jul 29 14:34:34 2015 -0300
incremental fixes
* emit-rtl.c: Include stor-layout.h. (set_reg_attrs_for_decl_rtl): Take mode from expression if it's not a DECL. * stmt.c (emit_case_decision_tree): Pass it the SSA_NAME rather than its possibly-NULL DECL. PR bootstrap/66978 * function.c (expand_function_start): Convert static chain to Pmode if needed. From H.J. Lu hongjiu.lu@intel.com. PR middle-end/66983 PR middle-end/67035 * cfgexpand.c (align_local_variable, add_stack_var): Support anonymous SSA names. (defer_stack_allocation): Likewise. Declare earlier. (expand_one_ssa_partition): Record alignment before expanding stack vars. Support deferred allocation. (set_rtl): Do no record deferred-allocation marker in SA.partition_to_pseudo. (expand_stack_vars): Adjust check for the marker in it. (adjust_one_expanded_partition_var): Skip deferred-alloc vars. PR middle-end/67034 * cfgexpand.c (parm_maybe_byref_p): New. (expand_one_ssa_partition): Call it. Expand maybe-byref parms' default defs with a placeholder for the mem addr. (ssa_default_def_partition): New. (get_rtl_for_parm_ssa_default_def): Use it. * function.c (assign_parm_setup_block): Replace the placeholder with the address of the newly-allocated block. (assign_parm_setup_reg): Replace the placeholder with a newly-created pseudo. Arrange for the pseudo to be initialized from the incoming passed pointer. Make sure passed_pointer parms don't need conversion. Don't copy from validated_mem if parmreg is the value expression from expand and validated_mem is the passed pointer. For passed pointers, copy from the mem referenced by validated_mem when using the expand-chosen rtl. * cfgexpand.h (parm_maybe_byref_p): Declare. * tree-ssa-coalesce.c: Include cfgexpand.h. (gimple_can_coalesce_p): Do not coalesce maybe-byref parms with SSA_NAMEs of other variables, or anonymous SSA_NAMEs. PR rtl-optimization/67000 * expr.c (read_complex_part): Export. * expr.h (read_complex_part): Declare. * function.c (split_complex_args): Use it. Reset complex parm before fetching its default decl rtl. (assign_parms_unsplit_complex): Use the preexisting complex parm rtl if it matches the components. (assign_parm_setup_reg): Drop assert on from_expand mode. Adjust it to the promoted_mode, if not byref. --- gcc/cfgexpand.c | 129 ++++++++++++++++++++++++++++++++++++++---------- gcc/cfgexpand.h | 1 + gcc/emit-rtl.c | 5 +- gcc/expr.c | 2 +- gcc/expr.h | 1 + gcc/function.c | 88 +++++++++++++++++++++++++-------- gcc/stmt.c | 2 +- gcc/tree-ssa-coalesce.c | 12 +++-- 8 files changed, 186 insertions(+), 54 deletions(-)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 0b19953..8f6caf6 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -97,6 +97,8 @@ gimple currently_expanding_gimple_stmt;
static rtx expand_debug_expr (tree);
+static bool defer_stack_allocation (tree, bool); + /* Return an expression tree corresponding to the RHS of GIMPLE statement STMT. */
@@ -170,6 +172,39 @@ leader_merge (tree cur, tree next) return cur; }
+/* Return true if VAR is a PARM_DECL or a RESULT_DECL of type BLKmode. + Such parameters are likely passed as a pointer to the value, rather + than as a value, and so we must not coalesce them, nor allocate + stack space for them before determining the calling conventions for + them. For their SSA_NAMEs, expand_one_ssa_partition emits RTL as + MEMs with pc_rtx as the address, and then it replaces the pc_rtx + with NULL so as to make sure the MEM is not used before it is + adjusted in assign_parm_setup_reg. */ + +bool +parm_maybe_byref_p (tree var) +{ + if (!var || VAR_P (var)) + return false; + + gcc_assert (TREE_CODE (var) == PARM_DECL + || TREE_CODE (var) == RESULT_DECL); + + return TYPE_MODE (TREE_TYPE (var)) == BLKmode; +} + +/* Return the partition of the default SSA_DEF for decl VAR. */ + +static int +ssa_default_def_partition (tree var) +{ + tree name = ssa_default_def (cfun, var); + + if (!name) + return NO_PARTITION; + + return var_to_partition (SA.map, name); +}
/* Return the RTL for the default SSA def of a PARM or RESULT, if there is one. */ @@ -198,12 +233,7 @@ get_rtl_for_parm_ssa_default_def (tree var) return DECL_RTL (var); }
- tree name = ssa_default_def (cfun, var); - - if (!name) - return NULL_RTX; - - int part = var_to_partition (SA.map, name); + int part = ssa_default_def_partition (var); if (part == NO_PARTITION) return NULL_RTX;
@@ -253,7 +283,7 @@ set_rtl (tree t, rtx x) { if (SA.partition_to_pseudo[part]) gcc_assert (SA.partition_to_pseudo[part] == x); - else + else if (x != pc_rtx) SA.partition_to_pseudo[part] = x; } /* For the benefit of debug information at -O0 (where @@ -348,8 +378,15 @@ static bool has_short_buffer; static unsigned int align_local_variable (tree decl) { - unsigned int align = LOCAL_DECL_ALIGNMENT (decl); - DECL_ALIGN (decl) = align; + unsigned int align; + + if (TREE_CODE (decl) == SSA_NAME) + align = TYPE_ALIGN (TREE_TYPE (decl)); + else + { + align = LOCAL_DECL_ALIGNMENT (decl); + DECL_ALIGN (decl) = align; + } return align / BITS_PER_UNIT; }
@@ -415,12 +452,15 @@ add_stack_var (tree decl) decl_to_stack_part->put (decl, stack_vars_num);
v->decl = decl; - v->size = tree_to_uhwi (DECL_SIZE_UNIT (SSAVAR (decl))); + tree size = TREE_CODE (decl) == SSA_NAME + ? TYPE_SIZE_UNIT (TREE_TYPE (decl)) + : DECL_SIZE_UNIT (decl); + v->size = tree_to_uhwi (size); /* Ensure that all variables have size, so that &a != &b for any two variables that are simultaneously live. */ if (v->size == 0) v->size = 1; - v->alignb = align_local_variable (SSAVAR (decl)); + v->alignb = align_local_variable (decl); /* An alignment of zero can mightily confuse us later. */ gcc_assert (v->alignb != 0);
@@ -1051,9 +1091,9 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_d [...] /* Skip variables that have already had rtl assigned. See also add_stack_var where we perpetrate this pc_rtx hack. */ decl = stack_vars[i].decl; - if ((TREE_CODE (decl) == SSA_NAME - ? SA.partition_to_pseudo[var_to_partition (SA.map, decl)] - : DECL_RTL (decl)) != pc_rtx) + if (TREE_CODE (decl) == SSA_NAME + ? SA.partition_to_pseudo[var_to_partition (SA.map, decl)] != NULL_RTX + : DECL_RTL (decl) != pc_rtx) continue;
large_size += alignb - 1; @@ -1082,9 +1122,9 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_d [...] /* Skip variables that have already had rtl assigned. See also add_stack_var where we perpetrate this pc_rtx hack. */ decl = stack_vars[i].decl; - if ((TREE_CODE (decl) == SSA_NAME - ? SA.partition_to_pseudo[var_to_partition (SA.map, decl)] - : DECL_RTL (decl)) != pc_rtx) + if (TREE_CODE (decl) == SSA_NAME + ? SA.partition_to_pseudo[var_to_partition (SA.map, decl)] != NULL_RTX + : DECL_RTL (decl) != pc_rtx) continue;
/* Check the predicate to see whether this variable should be @@ -1290,12 +1330,6 @@ expand_one_ssa_partition (tree var) if (SA.partition_to_pseudo[part]) return;
- if (!use_register_for_decl (var)) - { - expand_one_stack_var_1 (var); - return; - } - unsigned int align = MINIMUM_ALIGNMENT (TREE_TYPE (var), TYPE_MODE (TREE_TYPE (var)), TYPE_ALIGN (TREE_TYPE (var))); @@ -1307,6 +1341,27 @@ expand_one_ssa_partition (tree var)
record_alignment_for_reg_var (align);
+ if (!use_register_for_decl (var)) + { + if (parm_maybe_byref_p (SSA_NAME_VAR (var)) + && ssa_default_def_partition (SSA_NAME_VAR (var)) == part) + { + expand_one_stack_var_at (var, pc_rtx, 0, 0); + rtx x = SA.partition_to_pseudo[part]; + gcc_assert (GET_CODE (x) == MEM); + gcc_assert (GET_MODE (x) == BLKmode); + gcc_assert (XEXP (x, 0) == pc_rtx); + /* Reset the address, so that any attempt to use it will + ICE. It will be adjusted in assign_parm_setup_reg. */ + XEXP (x, 0) = NULL_RTX; + } + else if (defer_stack_allocation (var, true)) + add_stack_var (var); + else + expand_one_stack_var_1 (var); + return; + } + machine_mode reg_mode = promote_ssa_mode (var, NULL);
rtx x = gen_reg_rtx (reg_mode); @@ -1331,6 +1386,13 @@ adjust_one_expanded_partition_var (tree var)
rtx x = SA.partition_to_pseudo[part];
+ if (!x) + { + /* This var will get a stack slot later. */ + gcc_assert (defer_stack_allocation (var, true)); + return; + } + set_rtl (var, x);
if (!REG_P (x)) @@ -1409,10 +1471,14 @@ expand_one_error_var (tree var) static bool defer_stack_allocation (tree var, bool toplevel) { + tree size_unit = TREE_CODE (var) == SSA_NAME + ? TYPE_SIZE_UNIT (TREE_TYPE (var)) + : DECL_SIZE_UNIT (var); + /* Whether the variable is small enough for immediate allocation not to be a problem with regard to the frame size. */ bool smallish - = ((HOST_WIDE_INT) tree_to_uhwi (DECL_SIZE_UNIT (var)) + = ((HOST_WIDE_INT) tree_to_uhwi (size_unit) < PARAM_VALUE (PARAM_MIN_SIZE_FOR_STACK_SHARING));
/* If stack protection is enabled, *all* stack variables must be deferred, @@ -1421,16 +1487,24 @@ defer_stack_allocation (tree var, bool toplevel) if (flag_stack_protect || ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK)) return true;
+ unsigned int align = TREE_CODE (var) == SSA_NAME + ? TYPE_ALIGN (TREE_TYPE (var)) + : DECL_ALIGN (var); + /* We handle "large" alignment via dynamic allocation. We want to handle this extra complication in only one place, so defer them. */ - if (DECL_ALIGN (var) > MAX_SUPPORTED_STACK_ALIGNMENT) + if (align > MAX_SUPPORTED_STACK_ALIGNMENT) return true;
+ bool ignored = TREE_CODE (var) == SSA_NAME + ? !SSAVAR (var) || DECL_IGNORED_P (SSA_NAME_VAR (var)) + : DECL_IGNORED_P (var); + /* When optimization is enabled, DECL_IGNORED_P variables originally scoped might be detached from their block and appear at toplevel when we reach here. We want to coalesce them with variables from other blocks when the immediate contribution to the frame size would be noticeable. */ - if (toplevel && optimize > 0 && DECL_IGNORED_P (var) && !smallish) + if (toplevel && optimize > 0 && ignored && !smallish) return true;
/* Variables declared in the outermost scope automatically conflict @@ -6135,7 +6209,8 @@ pass_expand::execute (function *fun) if (part == NO_PARTITION) continue;
- gcc_assert (SA.partition_to_pseudo[part]); + gcc_assert (SA.partition_to_pseudo[part] + || defer_stack_allocation (name, true));
/* If this decl was marked as living in multiple places, reset this now to NULL. */ diff --git a/gcc/cfgexpand.h b/gcc/cfgexpand.h index 602579d..987cf356 100644 --- a/gcc/cfgexpand.h +++ b/gcc/cfgexpand.h @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
extern tree gimple_assign_rhs_to_tree (gimple); extern HOST_WIDE_INT estimated_stack_frame_size (struct cgraph_node *); +extern bool parm_maybe_byref_p (tree); extern rtx get_rtl_for_parm_ssa_default_def (tree var);
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 0648af6..3b95c5d 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "builtins.h" #include "rtl-iter.h" +#include "stor-layout.h"
struct target_rtl default_target_rtl; #if SWITCHABLE_TARGET @@ -1243,7 +1244,9 @@ set_reg_attrs_for_decl_rtl (tree t, rtx x) if (REG_P (x)) REG_ATTRS (x) = get_reg_attrs (t, byte_lowpart_offset (GET_MODE (x), - DECL_MODE (tdecl))); + DECL_P (tdecl) + ? DECL_MODE (tdecl) + : TYPE_MODE (TREE_TYPE (tdecl)))); if (GET_CODE (x) == CONCAT) { if (REG_P (XEXP (x, 0))) diff --git a/gcc/expr.c b/gcc/expr.c index d601129..fc49f92 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -3022,7 +3022,7 @@ write_complex_part (rtx cplx, rtx val, bool imag_p) /* Extract one of the components of the complex value CPLX. Extract the real part if IMAG_P is false, and the imaginary part if it's true. */
-static rtx +rtx read_complex_part (rtx cplx, bool imag_p) { machine_mode cmode, imode; diff --git a/gcc/expr.h b/gcc/expr.h index 32d1707..a2c8e1d 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -210,6 +210,7 @@ extern rtx_insn *emit_move_insn_1 (rtx, rtx);
extern rtx_insn *emit_move_complex_push (machine_mode, rtx, rtx); extern rtx_insn *emit_move_complex_parts (rtx, rtx); +extern rtx read_complex_part (rtx, bool); extern void write_complex_part (rtx, rtx, bool); extern rtx emit_move_resolve_push (machine_mode, rtx);
diff --git a/gcc/function.c b/gcc/function.c index c3d00cd..16708e9 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -152,6 +152,7 @@ static void prepare_function_start (void); static void do_clobber_return_reg (rtx, void *); static void do_use_return_reg (rtx, void *); static rtx rtl_for_parm (struct assign_parm_data_all *, tree); +static void maybe_reset_rtl_for_parm (tree);
/* Stack of nested functions. */ @@ -2321,12 +2322,12 @@ split_complex_args (struct assign_parm_data_all *all, vec<t [...] from resetting their RTL. */ if (currently_expanding_to_rtl) { + maybe_reset_rtl_for_parm (cparm); rtx rtl = rtl_for_parm (all, cparm); - gcc_assert (!rtl || GET_CODE (rtl) == CONCAT); if (rtl) { - SET_DECL_RTL (p, XEXP (rtl, 0)); - SET_DECL_RTL (decl, XEXP (rtl, 1)); + SET_DECL_RTL (p, read_complex_part (rtl, false)); + SET_DECL_RTL (decl, read_complex_part (rtl, true));
DECL_CONTEXT (p) = cparm; DECL_CONTEXT (decl) = cparm; @@ -2954,16 +2955,27 @@ assign_parm_setup_block (struct assign_parm_data_all *all, if (stack_parm == 0) { DECL_ALIGN (parm) = MAX (DECL_ALIGN (parm), BITS_PER_WORD); - stack_parm = rtl_for_parm (all, parm); - if (stack_parm) - stack_parm = copy_rtx (stack_parm); + rtx from_expand = rtl_for_parm (all, parm); + if (from_expand && (!parm_maybe_byref_p (parm) + || XEXP (from_expand, 0) != NULL_RTX)) + stack_parm = copy_rtx (from_expand); else { stack_parm = assign_stack_local (BLKmode, size_stored, DECL_ALIGN (parm)); if (GET_MODE_SIZE (GET_MODE (entry_parm)) == size) PUT_MODE (stack_parm, GET_MODE (entry_parm)); - set_mem_attributes (stack_parm, parm, 1); + if (from_expand) + { + gcc_assert (GET_CODE (stack_parm) == MEM); + gcc_assert (GET_CODE (from_expand) == MEM); + gcc_assert (XEXP (from_expand, 0) == NULL_RTX); + XEXP (from_expand, 0) = XEXP (stack_parm, 0); + PUT_MODE (from_expand, GET_MODE (stack_parm)); + stack_parm = copy_rtx (from_expand); + } + else + set_mem_attributes (stack_parm, parm, 1); } }
@@ -3102,23 +3114,34 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tr [...] = promote_function_mode (data->nominal_type, data->nominal_mode, &unsignedp, TREE_TYPE (current_function_decl), 2);
- rtx from_expand = rtl_for_parm (all, parm); + rtx from_expand = parmreg = rtl_for_parm (all, parm);
if (from_expand && !data->passed_pointer) { - parmreg = from_expand; - gcc_assert (GET_MODE (parmreg) == promoted_nominal_mode); + if (GET_MODE (parmreg) != promoted_nominal_mode) + parmreg = gen_lowpart (promoted_nominal_mode, parmreg); } - else + else if (!from_expand || parm_maybe_byref_p (parm)) { parmreg = gen_reg_rtx (promoted_nominal_mode); if (!DECL_ARTIFICIAL (parm)) mark_user_reg (parmreg); + + if (from_expand) + { + gcc_assert (data->passed_pointer); + gcc_assert (GET_CODE (from_expand) == MEM + && GET_MODE (from_expand) == BLKmode + && XEXP (from_expand, 0) == NULL_RTX); + XEXP (from_expand, 0) = parmreg; + } }
/* If this was an item that we received a pointer to, set DECL_RTL appropriately. */ - if (data->passed_pointer) + if (from_expand) + SET_DECL_RTL (parm, from_expand); + else if (data->passed_pointer) { rtx x = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data->passed_type)), parmreg); set_mem_attributes (x, parm, 1); @@ -3139,6 +3162,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
need_conversion = (data->nominal_mode != data->passed_mode || promoted_nominal_mode != data->promoted_mode); + gcc_assert (!(need_conversion && data->passed_pointer)); moved = false;
if (need_conversion @@ -3270,7 +3294,9 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
did_conversion = true; } - else + /* We don't want to copy the incoming pointer to a parmreg expected + to hold the value rather than the pointer. */ + else if (!data->passed_pointer || parmreg != from_expand) emit_move_insn (parmreg, validated_mem);
/* If we were passed a pointer but the actual value can safely live @@ -3278,12 +3304,16 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tr [...] if (data->passed_pointer && (from_expand || TYPE_MODE (TREE_TYPE (parm)) != BLKmode)) { + rtx src = DECL_RTL (parm); + /* We can't use nominal_mode, because it will have been set to Pmode above. We must use the actual mode of the parm. */ if (from_expand) { parmreg = from_expand; gcc_assert (GET_MODE (parmreg) == TYPE_MODE (TREE_TYPE (parm))); + src = gen_rtx_MEM (GET_MODE (parmreg), validated_mem); + set_mem_attributes (src, parm, 1); } else if (use_register_for_decl (parm)) { @@ -3302,14 +3332,14 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tr [...] set_mem_attributes (parmreg, parm, 1); }
- if (GET_MODE (parmreg) != GET_MODE (DECL_RTL (parm))) + if (GET_MODE (parmreg) != GET_MODE (src)) { - rtx tempreg = gen_reg_rtx (GET_MODE (DECL_RTL (parm))); + rtx tempreg = gen_reg_rtx (GET_MODE (src)); int unsigned_p = TYPE_UNSIGNED (TREE_TYPE (parm));
push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn); - emit_move_insn (tempreg, DECL_RTL (parm)); + emit_move_insn (tempreg, src); tempreg = convert_to_mode (GET_MODE (parmreg), tempreg, unsigned_p); emit_move_insn (parmreg, tempreg); all->first_conversion_insn = get_insns (); @@ -3318,8 +3348,10 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
did_conversion = true; } + else if (GET_MODE (parmreg) == BLKmode) + gcc_assert (parm_maybe_byref_p (parm)); else - emit_move_insn (parmreg, DECL_RTL (parm)); + emit_move_insn (parmreg, src);
SET_DECL_RTL (parm, parmreg);
@@ -3495,11 +3527,21 @@ assign_parms_unsplit_complex (struct assign_parm_data_all *all, imag = DECL_RTL (fnargs[i + 1]); if (inner != GET_MODE (real)) { - real = gen_lowpart_SUBREG (inner, real); - imag = gen_lowpart_SUBREG (inner, imag); + real = simplify_gen_subreg (inner, real, GET_MODE (real), + subreg_lowpart_offset + (inner, GET_MODE (real))); + imag = simplify_gen_subreg (inner, imag, GET_MODE (imag), + subreg_lowpart_offset + (inner, GET_MODE (imag))); }
- if (TREE_ADDRESSABLE (parm)) + if ((tmp = rtl_for_parm (all, parm)) != NULL_RTX + && rtx_equal_p (real, + read_complex_part (tmp, false)) + && rtx_equal_p (imag, + read_complex_part (tmp, true))) + ; /* We now have the right rtl in tmp. */ + else if (TREE_ADDRESSABLE (parm)) { rtx rmem, imem; HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (parm)); @@ -3645,7 +3687,7 @@ assign_bounds (vec<bounds_parm_data> &bndargs, assign_parm_setup_block (&all, pbdata->bounds_parm, &pbdata->parm_data); else if (pbdata->parm_data.passed_pointer - || use_register_for_decl (pbdata->bounds_parm)) + || use_register_for_parm_decl (&all, pbdata->bounds_parm)) assign_parm_setup_reg (&all, pbdata->bounds_parm, &pbdata->parm_data); else @@ -5207,6 +5249,10 @@ expand_function_start (tree subr) SET_DECL_RTL (parm, local); mark_reg_pointer (local, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));
+ if (GET_MODE (local) != Pmode) + local = convert_to_mode (Pmode, local, + TYPE_UNSIGNED (TREE_TYPE (parm))); + insn = emit_move_insn (local, chain);
/* Mark the register as eliminable, similar to parameters. */ diff --git a/gcc/stmt.c b/gcc/stmt.c index 391686c..e7f7dd4 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -891,7 +891,7 @@ emit_case_decision_tree (tree index_expr, tree index_type, { index = copy_to_reg (index); if (TREE_CODE (index_expr) == SSA_NAME) - set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (index_expr), index); + set_reg_attrs_for_decl_rtl (index_expr, index); }
balance_case_nodes (&case_list, NULL); diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c index a622728..08ce72c 100644 --- a/gcc/tree-ssa-coalesce.c +++ b/gcc/tree-ssa-coalesce.c @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-iterator.h" #include "tree-ssa-live.h" #include "tree-ssa-coalesce.h" +#include "cfgexpand.h" #include "explow.h" #include "diagnostic-core.h"
@@ -1379,10 +1380,15 @@ gimple_can_coalesce_p (tree name1, tree name2) /* Check that the promoted modes are the same. We don't want to coalesce if the promoted modes would be different. Only PARM_DECLs and RESULT_DECLs have different promotion rules, - so skip the test if we both are variables or anonymous - SSA_NAMEs. */ + so skip the test if both are variables, or both are anonymous + SSA_NAMEs. Now, if a parm or result has BLKmode, do not + coalesce its SSA versions with those of any other variables, + because it may be passed by reference. */ return ((!var1 || VAR_P (var1)) && (!var2 || VAR_P (var2))) - || promote_ssa_mode (name1, NULL) == promote_ssa_mode (name2, NULL); + || (/* The case var1 == var2 is already covered above. */ + !parm_maybe_byref_p (var1) + && !parm_maybe_byref_p (var2) + && promote_ssa_mode (name1, NULL) == promote_ssa_mode (name2, NULL)); }
/* If the types are not the same, check for a canonical type match. This