aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorZdenek Dvorak <dvorakz@suse.cz>2004-11-15 01:18:37 +0100
committerZdenek Dvorak <rakdver@gcc.gnu.org>2004-11-15 00:18:37 +0000
commit18522563e0d346db259fc6404b54c95e4155ae48 (patch)
tree8a20893a5c5c0b8de8fe5ddf927281ae604e7f1d /gcc/tree.c
parent4d6079e03d5291b4a7e1aae7fd836661c2331fed (diff)
downloadgcc-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.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index a05dab7..654ce78 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"