PR 68393: Handle SUBREG_PROMOTED_VAR_P in expand_direct_optab_fn
Do the usual dance when assigning to SUBREG_PROMOTED_VAR_P destinations: first convert to the outer mode, then extend to the inner mode. Tested that it fixes the powerpc64le-linux-gnu breakage. Also tested on x86_64-linux-gnu and powerpc64-linux-gnu. gcc/ PR bootstrap/68393 * internal-fn.c (expand_direct_optab_fn): Handle SUBREG_PROMOTED_VAR_P destinations. From-SVN: r230590
This commit is contained in:
parent
d0eccfcdc3
commit
ee1326921d
@ -1,3 +1,9 @@
|
||||
2015-11-19 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
PR bootstrap/68393
|
||||
* internal-fn.c (expand_direct_optab_fn): Handle SUBREG_PROMOTED_VAR_P
|
||||
destinations.
|
||||
|
||||
2015-11-18 Jeff Law <law@redhat.com>
|
||||
|
||||
PR tree-optimization/68198
|
||||
|
@ -2124,14 +2124,30 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
|
||||
expand_insn (icode, nargs + 1, ops);
|
||||
if (!rtx_equal_p (lhs_rtx, ops[0].value))
|
||||
{
|
||||
if (INTEGRAL_TYPE_P (lhs_type))
|
||||
/* Convert the operand to the required type, which is useful
|
||||
for things that return an int regardless of the size of
|
||||
the input. If the value produced by the instruction is
|
||||
smaller than required, assume that it is signed. */
|
||||
convert_move (lhs_rtx, ops[0].value, 0);
|
||||
else
|
||||
/* If the return value has an integral type, convert the instruction
|
||||
result to that type. This is useful for things that return an
|
||||
int regardless of the size of the input. If the instruction result
|
||||
is smaller than required, assume that it is signed.
|
||||
|
||||
If the return value has a nonintegral type, its mode must match
|
||||
the instruction result. */
|
||||
if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
|
||||
{
|
||||
/* If this is a scalar in a register that is stored in a wider
|
||||
mode than the declared mode, compute the result into its
|
||||
declared mode and then convert to the wider mode. */
|
||||
gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
|
||||
rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
|
||||
convert_move (SUBREG_REG (lhs_rtx), tmp,
|
||||
SUBREG_PROMOTED_SIGN (lhs_rtx));
|
||||
}
|
||||
else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
|
||||
emit_move_insn (lhs_rtx, ops[0].value);
|
||||
else
|
||||
{
|
||||
gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
|
||||
convert_move (lhs_rtx, ops[0].value, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user