diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2020-07-10 19:06:46 +0100 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2020-07-10 19:06:46 +0100 |
commit | 510125d2272175f47b26227fbe9b8c8c5abfd988 (patch) | |
tree | c728707640fde946dd6dc9c70d7b624799a1f2ec /gcc/expr.c | |
parent | efe99cca78215e339ba79f0a900a896b4c0a3d36 (diff) | |
download | gcc-510125d2272175f47b26227fbe9b8c8c5abfd988.zip gcc-510125d2272175f47b26227fbe9b8c8c5abfd988.tar.gz gcc-510125d2272175f47b26227fbe9b8c8c5abfd988.tar.bz2 |
expr: Move reduce_bit_field target mode check [PR96151]
In some cases, expand_expr_real_2 prefers to use the mode of the
caller-suggested target instead of the mode of the expression when
passing values to reduce_to_bit_field_precision. E.g.:
else if (target == 0)
op0 = convert_to_mode (mode, op0,
TYPE_UNSIGNED (TREE_TYPE
(treeop0)));
else
{
convert_move (target, op0,
TYPE_UNSIGNED (TREE_TYPE (treeop0)));
op0 = target;
}
where “op0” might not have “mode” for the “else” branch,
but does for all the others.
reduce_to_bit_field_precision discards the suggested target if it
has the wrong mode. This patch moves that to expand_expr_real_2
instead (conditional on reduce_bit_field).
gcc/
PR middle-end/96151
* expr.c (expand_expr_real_2): When reducing bit fields,
clear the target if it has a different mode from the expression.
(reduce_to_bit_field_precision): Don't do that here. Instead
assert that the target already has the correct mode.
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 9 |
1 files changed, 5 insertions, 4 deletions
@@ -8664,7 +8664,9 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, reduce_bit_field = (INTEGRAL_TYPE_P (type) && !type_has_mode_precision_p (type)); - if (reduce_bit_field && modifier == EXPAND_STACK_PARM) + if (reduce_bit_field + && (modifier == EXPAND_STACK_PARM + || (target && GET_MODE (target) != mode))) target = 0; /* Use subtarget as the target for operand 0 of a binary operation. */ @@ -11527,9 +11529,8 @@ reduce_to_bit_field_precision (rtx exp, rtx target, tree type) { scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type); HOST_WIDE_INT prec = TYPE_PRECISION (type); - gcc_assert (GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode); - if (target && GET_MODE (target) != mode) - target = 0; + gcc_assert ((GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode) + && (!target || GET_MODE (target) == mode)); /* For constant values, reduce using wide_int_to_tree. */ if (poly_int_rtx_p (exp)) |