From f3ce108897e16f828b3350ac5c5be9d0ffc622c0 Mon Sep 17 00:00:00 2001 From: Adam Nemet Date: Sat, 18 Jul 2009 21:52:48 +0000 Subject: [PATCH] combine.c (try_widen_shift_mode): Add COUNT, OUTER_CODE and OUTER_CONST arguments. * combine.c (try_widen_shift_mode): Add COUNT, OUTER_CODE and OUTER_CONST arguments. : Use them to allow widening if the bits shifted in from the new wider mode will be masked off. (simplify_shift_const_1): Adjust calls to try_widen_shift_mode. From-SVN: r149780 --- gcc/ChangeLog | 8 ++++++++ gcc/combine.c | 30 +++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1c418d1a04b..c087253a80a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-07-18 Adam Nemet + + * combine.c (try_widen_shift_mode): Add COUNT, OUTER_CODE and + OUTER_CONST arguments. + : Use them to allow widening if the bits shifted in from + the new wider mode will be masked off. + (simplify_shift_const_1): Adjust calls to try_widen_shift_mode. + 2009-07-18 Adam Nemet * combine.c (try_widen_shift_mode) : Allow widening if the diff --git a/gcc/combine.c b/gcc/combine.c index 12f0ed8223f..39daf2881d4 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -8985,11 +8985,14 @@ merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, /* A helper to simplify_shift_const_1 to determine the mode we can perform the shift in. The original shift operation CODE is performed on OP in ORIG_MODE. Return the wider mode MODE if we can perform the operation - in that mode. Return ORIG_MODE otherwise. */ + in that mode. Return ORIG_MODE otherwise. We can also assume that the + result of the shift is subject to operation OUTER_CODE with operand + OUTER_CONST. */ static enum machine_mode -try_widen_shift_mode (enum rtx_code code, rtx op, - enum machine_mode orig_mode, enum machine_mode mode) +try_widen_shift_mode (enum rtx_code code, rtx op, int count, + enum machine_mode orig_mode, enum machine_mode mode, + enum rtx_code outer_code, HOST_WIDE_INT outer_const) { if (orig_mode == mode) return mode; @@ -9012,6 +9015,21 @@ try_widen_shift_mode (enum rtx_code code, rtx op, if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT && (nonzero_bits (op, mode) & ~GET_MODE_MASK (orig_mode)) == 0) return mode; + + /* We can also widen if the bits brought in will be masked off. This + operation is performed in ORIG_MODE. */ + if (outer_code == AND + && GET_MODE_BITSIZE (orig_mode) <= HOST_BITS_PER_WIDE_INT) + { + int care_bits; + + outer_const &= GET_MODE_MASK (orig_mode); + care_bits = exact_log2 (outer_const + 1); + + if (care_bits >= 0 + && GET_MODE_BITSIZE (orig_mode) - care_bits >= count) + return mode; + } /* fall through */ case ROTATE: @@ -9084,7 +9102,8 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode, count = bitsize - count; } - shift_mode = try_widen_shift_mode (code, varop, result_mode, mode); + shift_mode = try_widen_shift_mode (code, varop, count, result_mode, + mode, outer_op, outer_const); /* Handle cases where the count is greater than the size of the mode minus 1. For ASHIFT, use the size minus one as the count (this can @@ -9682,7 +9701,8 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode, break; } - shift_mode = try_widen_shift_mode (code, varop, result_mode, mode); + shift_mode = try_widen_shift_mode (code, varop, count, result_mode, mode, + outer_op, outer_const); /* We have now finished analyzing the shift. The result should be a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places. If -- 2.30.2