diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-04-04 05:29:22 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-04-04 05:29:22 +0000 |
commit | 03725bf031ec9456e4e6afd9dc4ebd50fcccda1c (patch) | |
tree | f15eaa08e855cdbc68c60389f528daa3d081414f /gcc/fold-const.c | |
parent | 5ca8d76e2ccecf6db2a30b1c37b567cc004d7af5 (diff) |
gcc2 snapshot 980401 import
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc3@18982 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 75290dea448..7a0b6e70b55 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1,5 +1,5 @@ /* Fold a constant sub-tree into a single node for C-compiler - Copyright (C) 1987, 88, 92-96, 1997 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc. This file is part of GNU CC. @@ -175,7 +175,7 @@ force_fit_type (t, overflow) low = TREE_INT_CST_LOW (t); high = TREE_INT_CST_HIGH (t); - if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE) + if (POINTER_TYPE_P (TREE_TYPE (t))) prec = POINTER_SIZE; else prec = TYPE_PRECISION (TREE_TYPE (t)); @@ -1493,7 +1493,7 @@ fold_convert (t, arg1) register tree type = TREE_TYPE (t); int overflow = 0; - if (TREE_CODE (type) == POINTER_TYPE || INTEGRAL_TYPE_P (type)) + if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type)) { if (TREE_CODE (arg1) == INTEGER_CST) { @@ -1513,12 +1513,12 @@ fold_convert (t, arg1) if ARG1 is a too-large unsigned value and T is signed. But don't indicate an overflow if converting a pointer. */ TREE_OVERFLOW (t) - = (TREE_OVERFLOW (arg1) - || (force_fit_type (t, - (TREE_INT_CST_HIGH (arg1) < 0 - & (TREE_UNSIGNED (type) - < TREE_UNSIGNED (TREE_TYPE (arg1))))) - && TREE_CODE (TREE_TYPE (arg1)) != POINTER_TYPE)); + = ((force_fit_type (t, + (TREE_INT_CST_HIGH (arg1) < 0 + & (TREE_UNSIGNED (type) + < TREE_UNSIGNED (TREE_TYPE (arg1))))) + && ! POINTER_TYPE_P (TREE_TYPE (arg1))) + || TREE_OVERFLOW (arg1)); TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1); } @@ -1894,7 +1894,7 @@ operand_equal_for_comparison_p (arg0, arg1, other) tree other; { int unsignedp1, unsignedpo; - tree primarg1, primother; + tree primarg0, primarg1, primother; unsigned correct_width; if (operand_equal_p (arg0, arg1, 0)) @@ -1904,6 +1904,14 @@ operand_equal_for_comparison_p (arg0, arg1, other) || ! INTEGRAL_TYPE_P (TREE_TYPE (arg1))) return 0; + /* Discard any conversions that don't change the modes of ARG0 and ARG1 + and see if the inner values are the same. This removes any + signedness comparison, which doesn't matter here. */ + primarg0 = arg0, primarg1 = arg1; + STRIP_NOPS (primarg0); STRIP_NOPS (primarg1); + if (operand_equal_p (primarg0, primarg1, 0)) + return 1; + /* Duplicate what shorten_compare does to ARG1 and see if that gives the actual comparison operand, ARG0. @@ -4050,6 +4058,13 @@ fold (expr) && ! final_ptr) return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0)); + /* If we have a sign-extension of a zero-extended value, we can + replace that by a single zero-extension. */ + if (inside_int && inter_int && final_int + && inside_prec < inter_prec && inter_prec < final_prec + && inside_unsignedp && !inter_unsignedp) + return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0)); + /* Two conversions in a row are not needed unless: - some conversion is floating-point (overstrict for now), or - the intermediate type is narrower than both initial and @@ -5028,7 +5043,7 @@ fold (expr) if CONST+INCR overflows or if foo+incr might overflow. This optimization is invalid for floating point due to rounding. For pointer types we assume overflow doesn't happen. */ - if (TREE_CODE (TREE_TYPE (varop)) == POINTER_TYPE + if (POINTER_TYPE_P (TREE_TYPE (varop)) || (! FLOAT_TYPE_P (TREE_TYPE (varop)) && (code == EQ_EXPR || code == NE_EXPR))) { @@ -5063,7 +5078,7 @@ fold (expr) } else if (constop && TREE_CODE (varop) == POSTDECREMENT_EXPR) { - if (TREE_CODE (TREE_TYPE (varop)) == POINTER_TYPE + if (POINTER_TYPE_P (TREE_TYPE (varop)) || (! FLOAT_TYPE_P (TREE_TYPE (varop)) && (code == EQ_EXPR || code == NE_EXPR))) { @@ -5257,7 +5272,7 @@ fold (expr) /* An unsigned comparison against 0 can be simplified. */ if (integer_zerop (arg1) && (INTEGRAL_TYPE_P (TREE_TYPE (arg1)) - || TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE) + || POINTER_TYPE_P (TREE_TYPE (arg1))) && TREE_UNSIGNED (TREE_TYPE (arg1))) { switch (TREE_CODE (t)) @@ -5292,7 +5307,7 @@ fold (expr) && TREE_INT_CST_LOW (arg1) == ((HOST_WIDE_INT) 1 << (width - 1)) - 1 && TREE_INT_CST_HIGH (arg1) == 0 && (INTEGRAL_TYPE_P (TREE_TYPE (arg1)) - || TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE) + || POINTER_TYPE_P (TREE_TYPE (arg1))) && TREE_UNSIGNED (TREE_TYPE (arg1))) { switch (TREE_CODE (t)) |