aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1993-07-30 19:07:52 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1993-07-30 19:07:52 -0400
commit33558beb6ade3caee5803e93001d625d82877730 (patch)
treec76ae0d85d486aedb7c9a9d27cd9953742a42628
parent819126a60788afcdf2beafcf26ebf2127b9eb518 (diff)
downloadgcc-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.c16
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,