diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1993-07-30 19:07:52 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1993-07-30 19:07:52 -0400 |
commit | 33558beb6ade3caee5803e93001d625d82877730 (patch) | |
tree | c76ae0d85d486aedb7c9a9d27cd9953742a42628 | |
parent | 819126a60788afcdf2beafcf26ebf2127b9eb518 (diff) | |
download | gcc-33558beb6ade3caee5803e93001d625d82877730.zip gcc-33558beb6ade3caee5803e93001d625d82877730.tar.gz gcc-33558beb6ade3caee5803e93001d625d82877730.tar.bz2 |
(fold...
(fold, case NOP_EXPR): Delete a pair of conversions back to the
original type when intermediate type is at least as wide.
From-SVN: r5046
-rw-r--r-- | gcc/fold-const.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a88b619..e3eab5b 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3342,6 +3342,22 @@ fold (expr) case CONVERT_EXPR: case FIX_TRUNC_EXPR: /* Other kinds of FIX are not handled properly by fold_convert. */ + + /* In addition to the cases of two conversions in a row + handled below, if we are converting something to its own + type via an object of identical or wider precision, neither + conversion is needed. */ + if ((TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR + || TREE_CODE (TREE_OPERAND (t, 0)) == CONVERT_EXPR) + && TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)) == TREE_TYPE (t) + && ((INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))) + && INTEGRAL_TYPE_P (TREE_TYPE (t))) + || (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))) + && FLOAT_TYPE_P (TREE_TYPE (t)))) + && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0))) + >= TYPE_PRECISION (TREE_TYPE (t)))) + return TREE_OPERAND (TREE_OPERAND (t, 0), 0); + /* Two conversions in a row are not needed unless: - the intermediate type is narrower than both initial and final, or - the intermediate type and innermost type differ in signedness, |