From ef9384f3e0317cc7938526c93237a39df6767e0b Mon Sep 17 00:00:00 2001 From: rsandifo Date: Sat, 8 Aug 2009 08:32:24 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 +++++++ gcc/combine.c | 51 ++++++++++++++++++++++++++++----------------------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3a43fe3dd8e..f2e11bc9bed 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-08-08 Richard Sandiford + + * 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 PR tree-optimization/40999 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); -- 2.11.0