combine.c (gen_lowpart_or_truncate): Exclude CONST_INTs from mode check.

gcc/
	* combine.c (gen_lowpart_or_truncate): Exclude CONST_INTs from
	mode check.  Do truncations in an integer mode.
	(force_to_mode): Handle subregs for all mode types.  Only do
	arithmetic simplifications on integer modes.

From-SVN: r150578
This commit is contained in:
Richard Sandiford 2009-08-08 08:32:24 +00:00 committed by Richard Sandiford
parent 1fc00cc90a
commit d686d89233
2 changed files with 35 additions and 23 deletions

View File

@ -1,3 +1,10 @@
2009-08-08 Richard Sandiford <rdsandiford@googlemail.com>
* combine.c (gen_lowpart_or_truncate): Exclude CONST_INTs from
mode check. Do truncations in an integer mode.
(force_to_mode): Handle subregs for all mode types. Only do
arithmetic simplifications on integer modes.
2009-08-07 Richard Guenther <rguenther@suse.de>
PR tree-optimization/40999

View File

@ -7243,13 +7243,20 @@ canon_reg_for_combine (rtx x, rtx reg)
static rtx
gen_lowpart_or_truncate (enum machine_mode mode, rtx x)
{
if (GET_MODE_SIZE (GET_MODE (x)) <= GET_MODE_SIZE (mode)
|| TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (GET_MODE (x)))
|| (REG_P (x) && reg_truncated_to_mode (mode, x)))
return gen_lowpart (mode, x);
else
return simplify_gen_unary (TRUNCATE, mode, x, GET_MODE (x));
if (!CONST_INT_P (x)
&& GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x))
&& !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (GET_MODE (x)))
&& !(REG_P (x) && reg_truncated_to_mode (mode, x)))
{
/* Bit-cast X into an integer mode. */
if (!SCALAR_INT_MODE_P (GET_MODE (x)))
x = gen_lowpart (int_mode_for_mode (GET_MODE (x)), x);
x = simplify_gen_unary (TRUNCATE, int_mode_for_mode (mode),
x, GET_MODE (x));
}
return gen_lowpart (mode, x);
}
/* See if X can be simplified knowing that we will only refer to it in
@ -7336,9 +7343,20 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
&& (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
return gen_lowpart (mode, x);
/* The arithmetic simplifications here do the wrong thing on vector modes. */
if (VECTOR_MODE_P (mode) || VECTOR_MODE_P (GET_MODE (x)))
return gen_lowpart (mode, x);
/* We can ignore the effect of a SUBREG if it narrows the mode or
if the constant masks to zero all the bits the mode doesn't have. */
if (GET_CODE (x) == SUBREG
&& subreg_lowpart_p (x)
&& ((GET_MODE_SIZE (GET_MODE (x))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
|| (0 == (mask
& GET_MODE_MASK (GET_MODE (x))
& ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
return force_to_mode (SUBREG_REG (x), mode, mask, next_select);
/* The arithmetic simplifications here only work for scalar integer modes. */
if (!SCALAR_INT_MODE_P (mode) || !SCALAR_INT_MODE_P (GET_MODE (x)))
return gen_lowpart_or_truncate (mode, x);
switch (code)
{
@ -7356,19 +7374,6 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
return force_to_mode (x, mode, mask, next_select);
break;
case SUBREG:
if (subreg_lowpart_p (x)
/* We can ignore the effect of this SUBREG if it narrows the mode or
if the constant masks to zero all the bits the mode doesn't
have. */
&& ((GET_MODE_SIZE (GET_MODE (x))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
|| (0 == (mask
& GET_MODE_MASK (GET_MODE (x))
& ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
return force_to_mode (SUBREG_REG (x), mode, mask, next_select);
break;
case TRUNCATE:
/* Similarly for a truncate. */
return force_to_mode (XEXP (x, 0), mode, mask, next_select);