diff options
author | kan <kan@FreeBSD.org> | 2005-06-03 03:28:44 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2005-06-03 03:28:44 +0000 |
commit | 2156e40a831a8e0ab68e4bc091c2940bf46ca6df (patch) | |
tree | f0dc8ad34f9fcaf27052e24e893a4284b5fee6e9 /contrib/gcc/fold-const.c | |
parent | 0a20abcc95340c9d2bb59421bac84eca4fb43b0c (diff) | |
download | FreeBSD-src-2156e40a831a8e0ab68e4bc091c2940bf46ca6df.zip FreeBSD-src-2156e40a831a8e0ab68e4bc091c2940bf46ca6df.tar.gz |
Gcc 3.4.4 release.
Diffstat (limited to 'contrib/gcc/fold-const.c')
-rw-r--r-- | contrib/gcc/fold-const.c | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/contrib/gcc/fold-const.c b/contrib/gcc/fold-const.c index 2c0f813..b34422f 100644 --- a/contrib/gcc/fold-const.c +++ b/contrib/gcc/fold-const.c @@ -1828,7 +1828,8 @@ fold_convert (tree type, tree arg) if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig)) return fold (build1 (NOP_EXPR, type, arg)); - if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)) + if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type) + || TREE_CODE (type) == OFFSET_TYPE) { if (TREE_CODE (arg) == INTEGER_CST) { @@ -1836,7 +1837,8 @@ fold_convert (tree type, tree arg) if (tem != NULL_TREE) return tem; } - if (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig)) + if (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig) + || TREE_CODE (orig) == OFFSET_TYPE) return fold (build1 (NOP_EXPR, type, arg)); if (TREE_CODE (orig) == COMPLEX_TYPE) { @@ -2187,10 +2189,21 @@ operand_equal_p (tree arg0, tree arg1, int only_const) { case '1': /* Two conversions are equal only if signedness and modes match. */ - if ((TREE_CODE (arg0) == NOP_EXPR || TREE_CODE (arg0) == CONVERT_EXPR) - && (TREE_UNSIGNED (TREE_TYPE (arg0)) - != TREE_UNSIGNED (TREE_TYPE (arg1)))) - return 0; + switch (TREE_CODE (arg0)) + { + case NOP_EXPR: + case CONVERT_EXPR: + case FIX_CEIL_EXPR: + case FIX_TRUNC_EXPR: + case FIX_FLOOR_EXPR: + case FIX_ROUND_EXPR: + if (TREE_UNSIGNED (TREE_TYPE (arg0)) + != TREE_UNSIGNED (TREE_TYPE (arg1))) + return 0; + break; + default: + break; + } return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0); @@ -4452,9 +4465,9 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type) && TYPE_IS_SIZETYPE (TREE_TYPE (op0))) && (GET_MODE_SIZE (TYPE_MODE (ctype)) > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))) - /* ... or its type is larger than ctype, - then we cannot pass through this truncation. */ - || (GET_MODE_SIZE (TYPE_MODE (ctype)) + /* ... or this is a truncation (t is narrower than op0), + then we cannot pass through this narrowing. */ + || (GET_MODE_SIZE (TYPE_MODE (type)) < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))) /* ... or signedness changes for division or modulus, then we cannot pass through this conversion. */ @@ -4475,7 +4488,21 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type) return t1; break; - case NEGATE_EXPR: case ABS_EXPR: + case ABS_EXPR: + /* If widening the type changes it from signed to unsigned, then we + must avoid building ABS_EXPR itself as unsigned. */ + if (TREE_UNSIGNED (ctype) && !TREE_UNSIGNED (type)) + { + tree cstype = (*lang_hooks.types.signed_type) (ctype); + if ((t1 = extract_muldiv (op0, c, code, cstype)) != 0) + { + t1 = fold (build1 (tcode, cstype, fold_convert (cstype, t1))); + return fold_convert (ctype, t1); + } + break; + } + /* FALLTHROUGH */ + case NEGATE_EXPR: if ((t1 = extract_muldiv (op0, c, code, wide_type)) != 0) return fold (build1 (tcode, ctype, fold_convert (ctype, t1))); break; |