diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-01-15 10:46:10 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-01-15 10:46:10 +0100 |
commit | 75b9aa9f27103dfe395589744695c77c42d51c0d (patch) | |
tree | eee50ef2164840adf38bebf57be5788622dbb666 /gcc/fold-const.c | |
parent | 4ba9f2a1e4ff069b076c47ec74e84d4a15380f3a (diff) | |
download | gcc-75b9aa9f27103dfe395589744695c77c42d51c0d.zip gcc-75b9aa9f27103dfe395589744695c77c42d51c0d.tar.gz gcc-75b9aa9f27103dfe395589744695c77c42d51c0d.tar.bz2 |
re PR tree-optimization/19060 (Miscompiling of if and "long long")
PR tree-optimization/19060
* tree-ssa-dom.c (extract_range_from_cond) <case LT_EXPR, GT_EXPR>:
Return 0 if op1 <= TYPE_MIN_VALUE () resp. op1 >= TYPE_MAX_VALUE ().
(simplify_cond_and_lookup_avail_expr): Add assert for dummy == 0
and handle extract_range_from_cond returning false.
* fold-const.c (fold): Optimize comparisons with min/max even for
width > HOST_BITS_PER_WIDE_INT.
* gcc.c-torture/execute/20050104-1.c: New test.
From-SVN: r93692
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 7ccd3a8..24bd28b 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8439,28 +8439,57 @@ fold (tree expr) if (TREE_CODE (arg1) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg1) - && width <= HOST_BITS_PER_WIDE_INT + && width <= 2 * HOST_BITS_PER_WIDE_INT && (INTEGRAL_TYPE_P (TREE_TYPE (arg1)) || POINTER_TYPE_P (TREE_TYPE (arg1)))) { - unsigned HOST_WIDE_INT signed_max; - unsigned HOST_WIDE_INT max, min; + HOST_WIDE_INT signed_max_hi; + unsigned HOST_WIDE_INT signed_max_lo; + unsigned HOST_WIDE_INT max_hi, max_lo, min_hi, min_lo; - signed_max = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1; - - if (TYPE_UNSIGNED (TREE_TYPE (arg1))) + if (width <= HOST_BITS_PER_WIDE_INT) { - max = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1; - min = 0; + signed_max_lo = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) + - 1; + signed_max_hi = 0; + max_hi = 0; + + if (TYPE_UNSIGNED (TREE_TYPE (arg1))) + { + max_lo = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1; + min_lo = 0; + min_hi = 0; + } + else + { + max_lo = signed_max_lo; + min_lo = ((unsigned HOST_WIDE_INT) -1 << (width - 1)); + min_hi = -1; + } } else { - max = signed_max; - min = ((unsigned HOST_WIDE_INT) -1 << (width - 1)); + width -= HOST_BITS_PER_WIDE_INT; + signed_max_lo = -1; + signed_max_hi = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) + - 1; + max_lo = -1; + min_lo = 0; + + if (TYPE_UNSIGNED (TREE_TYPE (arg1))) + { + max_hi = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1; + min_hi = 0; + } + else + { + max_hi = signed_max_hi; + min_hi = ((unsigned HOST_WIDE_INT) -1 << (width - 1)); + } } - if (TREE_INT_CST_HIGH (arg1) == 0 - && TREE_INT_CST_LOW (arg1) == max) + if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1) == max_hi + && TREE_INT_CST_LOW (arg1) == max_lo) switch (code) { case GT_EXPR: @@ -8481,8 +8510,9 @@ fold (tree expr) default: break; } - else if (TREE_INT_CST_HIGH (arg1) == 0 - && TREE_INT_CST_LOW (arg1) == max - 1) + else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1) + == max_hi + && TREE_INT_CST_LOW (arg1) == max_lo - 1) switch (code) { case GT_EXPR: @@ -8494,8 +8524,9 @@ fold (tree expr) default: break; } - else if (TREE_INT_CST_HIGH (arg1) == (min ? -1 : 0) - && TREE_INT_CST_LOW (arg1) == min) + else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1) + == min_hi + && TREE_INT_CST_LOW (arg1) == min_lo) switch (code) { case LT_EXPR: @@ -8513,8 +8544,9 @@ fold (tree expr) default: break; } - else if (TREE_INT_CST_HIGH (arg1) == (min ? -1 : 0) - && TREE_INT_CST_LOW (arg1) == min + 1) + else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1) + == min_hi + && TREE_INT_CST_LOW (arg1) == min_lo + 1) switch (code) { case GE_EXPR: @@ -8528,8 +8560,8 @@ fold (tree expr) } else if (!in_gimple_form - && TREE_INT_CST_HIGH (arg1) == 0 - && TREE_INT_CST_LOW (arg1) == signed_max + && TREE_INT_CST_HIGH (arg1) == signed_max_hi + && TREE_INT_CST_LOW (arg1) == signed_max_lo && TYPE_UNSIGNED (TREE_TYPE (arg1)) /* signed_type does not work on pointer types. */ && INTEGRAL_TYPE_P (TREE_TYPE (arg1))) |