From faab57e3cef4a6034b2336ac1a015b11733a370d Mon Sep 17 00:00:00 2001 From: rakdver Date: Mon, 15 Nov 2004 00:18:37 +0000 Subject: PR tree-optimization/18431 * fold-const.c (associate_trees): Do not produce x + 0. (fold_widened_comparison, fold_sign_changed_comparison): New functions. (fold): Use them. * tree-ssa-loop-niter.c (upper_bound_in_type, lower_bound_in_type): Moved ... * tree.c (upper_bound_in_type, lower_bound_in_type): Here. * tree.h (upper_bound_in_type, lower_bound_in_type): Declare. * testsuite/gcc.c-torture/execute/20041114-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@90646 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index a05dab73f73..654ce785857 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6074,4 +6074,76 @@ get_case_label (tree t) return CASE_LEADER_OR_LABEL (t); } +/* Returns the largest value obtainable by casting something in INNER type to + OUTER type. */ + +tree +upper_bound_in_type (tree outer, tree inner) +{ + unsigned HOST_WIDE_INT lo, hi; + unsigned bits = TYPE_PRECISION (inner); + + if (TYPE_UNSIGNED (outer) || TYPE_UNSIGNED (inner)) + { + /* Zero extending in these cases. */ + if (bits <= HOST_BITS_PER_WIDE_INT) + { + hi = 0; + lo = (~(unsigned HOST_WIDE_INT) 0) + >> (HOST_BITS_PER_WIDE_INT - bits); + } + else + { + hi = (~(unsigned HOST_WIDE_INT) 0) + >> (2 * HOST_BITS_PER_WIDE_INT - bits); + lo = ~(unsigned HOST_WIDE_INT) 0; + } + } + else + { + /* Sign extending in these cases. */ + if (bits <= HOST_BITS_PER_WIDE_INT) + { + hi = 0; + lo = (~(unsigned HOST_WIDE_INT) 0) + >> (HOST_BITS_PER_WIDE_INT - bits) >> 1; + } + else + { + hi = (~(unsigned HOST_WIDE_INT) 0) + >> (2 * HOST_BITS_PER_WIDE_INT - bits) >> 1; + lo = ~(unsigned HOST_WIDE_INT) 0; + } + } + + return fold_convert (outer, + build_int_cst_wide (inner, lo, hi)); +} + +/* Returns the smallest value obtainable by casting something in INNER type to + OUTER type. */ + +tree +lower_bound_in_type (tree outer, tree inner) +{ + unsigned HOST_WIDE_INT lo, hi; + unsigned bits = TYPE_PRECISION (inner); + + if (TYPE_UNSIGNED (outer) || TYPE_UNSIGNED (inner)) + lo = hi = 0; + else if (bits <= HOST_BITS_PER_WIDE_INT) + { + hi = ~(unsigned HOST_WIDE_INT) 0; + lo = (~(unsigned HOST_WIDE_INT) 0) << (bits - 1); + } + else + { + hi = (~(unsigned HOST_WIDE_INT) 0) << (bits - HOST_BITS_PER_WIDE_INT - 1); + lo = 0; + } + + return fold_convert (outer, + build_int_cst_wide (inner, lo, hi)); +} + #include "gt-tree.h" -- cgit v1.2.1