diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/ChangeLog | 7 | ||||
| -rw-r--r-- | gcc/fold-const.c | 33 |
2 files changed, 26 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f09a823..f322b66 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2006-12-01 Eric Botcazou <ebotcazou@adacore.com> + + * fold-const.c (fold_binary) <LT_EXPR>: Use the precision of the + type instead of the size of its mode to compute the highest and + lowest possible values. Still check the size of the mode before + flipping the signedness of the comparison. + 2006-12-01 Trevor Smigiel <trevor_smigiel@playstation.sony.com> * config/spu/predicates.md (spu_mov_operand): Add. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index b19b768..fce41c2 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -7758,24 +7758,24 @@ fold_minmax (enum tree_code code, tree type, tree op0, tree op1) else gcc_unreachable (); - /* MIN (MAX (a, b), b) == b. */ + /* MIN (MAX (a, b), b) == b. */ if (TREE_CODE (op0) == compl_code && operand_equal_p (TREE_OPERAND (op0, 1), op1, 0)) return omit_one_operand (type, op1, TREE_OPERAND (op0, 0)); - /* MIN (MAX (b, a), b) == b. */ + /* MIN (MAX (b, a), b) == b. */ if (TREE_CODE (op0) == compl_code && operand_equal_p (TREE_OPERAND (op0, 0), op1, 0) && reorder_operands_p (TREE_OPERAND (op0, 1), op1)) return omit_one_operand (type, op1, TREE_OPERAND (op0, 1)); - /* MIN (a, MAX (a, b)) == a. */ + /* MIN (a, MAX (a, b)) == a. */ if (TREE_CODE (op1) == compl_code && operand_equal_p (op0, TREE_OPERAND (op1, 0), 0) && reorder_operands_p (op0, TREE_OPERAND (op1, 1))) return omit_one_operand (type, op0, TREE_OPERAND (op1, 1)); - /* MIN (a, MAX (b, a)) == a. */ + /* MIN (a, MAX (b, a)) == a. */ if (TREE_CODE (op1) == compl_code && operand_equal_p (op0, TREE_OPERAND (op1, 1), 0) && reorder_operands_p (op0, TREE_OPERAND (op1, 0))) @@ -10994,15 +10994,15 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) } /* Comparisons with the highest or lowest possible integer of - the specified size will have known values. */ + the specified precision will have known values. */ { - int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1))); + tree arg1_type = TREE_TYPE (arg1); + unsigned int width = TYPE_PRECISION (arg1_type); if (TREE_CODE (arg1) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg1) && width <= 2 * HOST_BITS_PER_WIDE_INT - && (INTEGRAL_TYPE_P (TREE_TYPE (arg1)) - || POINTER_TYPE_P (TREE_TYPE (arg1)))) + && (INTEGRAL_TYPE_P (arg1_type) || POINTER_TYPE_P (arg1_type))) { HOST_WIDE_INT signed_max_hi; unsigned HOST_WIDE_INT signed_max_lo; @@ -11015,7 +11015,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) signed_max_hi = 0; max_hi = 0; - if (TYPE_UNSIGNED (TREE_TYPE (arg1))) + if (TYPE_UNSIGNED (arg1_type)) { max_lo = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1; min_lo = 0; @@ -11037,7 +11037,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) max_lo = -1; min_lo = 0; - if (TYPE_UNSIGNED (TREE_TYPE (arg1))) + if (TYPE_UNSIGNED (arg1_type)) { max_hi = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1; min_hi = 0; @@ -11124,9 +11124,14 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) else if (TREE_INT_CST_HIGH (arg1) == signed_max_hi && TREE_INT_CST_LOW (arg1) == signed_max_lo - && TYPE_UNSIGNED (TREE_TYPE (arg1)) + && TYPE_UNSIGNED (arg1_type) + /* We will flip the signedness of the comparison operator + associated with the mode of arg1, so the sign bit is + specified by this mode. Check that arg1 is the signed + max associated with this sign bit. */ + && width == GET_MODE_BITSIZE (TYPE_MODE (arg1_type)) /* signed_type does not work on pointer types. */ - && INTEGRAL_TYPE_P (TREE_TYPE (arg1))) + && INTEGRAL_TYPE_P (arg1_type)) { /* The following case also applies to X < signed_max+1 and X >= signed_max+1 because previous transformations. */ @@ -11136,8 +11141,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) st0 = lang_hooks.types.signed_type (TREE_TYPE (arg0)); st1 = lang_hooks.types.signed_type (TREE_TYPE (arg1)); return fold_build2 (code == LE_EXPR ? GE_EXPR: LT_EXPR, - type, fold_convert (st0, arg0), - build_int_cst (st1, 0)); + type, fold_convert (st0, arg0), + build_int_cst (st1, 0)); } } } |
