diff options
author | Zdenek Dvorak <dvorakz@suse.cz> | 2004-11-15 01:18:37 +0100 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2004-11-15 00:18:37 +0000 |
commit | 18522563e0d346db259fc6404b54c95e4155ae48 (patch) | |
tree | 8a20893a5c5c0b8de8fe5ddf927281ae604e7f1d /gcc/tree.c | |
parent | 4d6079e03d5291b4a7e1aae7fd836661c2331fed (diff) | |
download | gcc-18522563e0d346db259fc6404b54c95e4155ae48.zip gcc-18522563e0d346db259fc6404b54c95e4155ae48.tar.gz gcc-18522563e0d346db259fc6404b54c95e4155ae48.tar.bz2 |
re PR tree-optimization/18431 (Code for arrays and pointers are not the same)
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.
From-SVN: r90646
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 72 |
1 files changed, 72 insertions, 0 deletions
@@ -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" |