diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-08-08 08:32:24 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-08-08 08:32:24 +0000 |
commit | ef9384f3e0317cc7938526c93237a39df6767e0b (patch) | |
tree | 748209c722d516febae45c294a24cf4c971dc4e2 /gcc/combine.c | |
parent | 887d9ba903797a2903696e3aa921616a220a783a (diff) | |
download | gcc-ef9384f3e0317cc7938526c93237a39df6767e0b.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@150578 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 6a0e6ec5c93..3a2c41205e5 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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); |