diff options
author | Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> | 1998-06-02 21:53:37 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1998-06-02 15:53:37 -0600 |
commit | df0e526f2ddd7af54268839582a8b278249da86e (patch) | |
tree | 1ebe3908161c9d4f702e0bf08a2f7ff5e4835a9b | |
parent | ccdb92510523a0302c4bd058a51530d089aac21f (diff) | |
download | gcc-df0e526f2ddd7af54268839582a8b278249da86e.zip gcc-df0e526f2ddd7af54268839582a8b278249da86e.tar.gz gcc-df0e526f2ddd7af54268839582a8b278249da86e.tar.bz2 |
fold-const.c (fold, [...]): When folding VAR++ == CONST or VAR-- == CONST construct a proper mask if...
* fold-const.c (fold, case EQ_EXPR): When folding VAR++ == CONST
or VAR-- == CONST construct a proper mask if VAR is a bitfield.
Cope with CONST being out of range for the bitfield.
From-SVN: r20198
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 53 |
2 files changed, 55 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7a0e7a4..af9dab8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Tue Jun 2 22:50:10 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * fold-const.c (fold, case EQ_EXPR): When folding VAR++ == CONST + or VAR-- == CONST construct a proper mask if VAR is a bitfield. + Cope with CONST being out of range for the bitfield. + Tue Jun 2 22:28:31 1998 Bernd Schmidt <crux@ohara.Informatik.RWTH-Aachen.DE> * expr.c (emit_move_insn_1): When moving complex values in several diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 9d1cb36..d847764 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5222,11 +5222,35 @@ fold (expr) = TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (varop, 0), 1))); - + tree mask, unsigned_type; + int precision; + tree folded_compare; + + /* First check whether the comparison would come out + always the same. If we don't do that we would + change the meaning with the masking. */ + if (constopnum == 0) + folded_compare = fold (build (code, type, constop, + TREE_OPERAND (varop, 0))); + else + folded_compare = fold (build (code, type, + TREE_OPERAND (varop, 0), + constop)); + if (integer_zerop (folded_compare) + || integer_onep (folded_compare)) + return omit_one_operand (type, folded_compare, varop); + + unsigned_type = type_for_size (size, 1); + precision = TYPE_PRECISION (unsigned_type); + mask = build_int_2 (~0, ~0); + TREE_TYPE (mask) = unsigned_type; + force_fit_type (mask, 0); + mask = const_binop (RSHIFT_EXPR, mask, + size_int (precision - size), 0); newconst = fold (build (BIT_AND_EXPR, TREE_TYPE (varop), newconst, convert (TREE_TYPE (varop), - build_int_2 (size, 0)))); + mask))); } @@ -5255,11 +5279,32 @@ fold (expr) = TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (varop, 0), 1))); - + tree mask, unsigned_type; + int precision; + tree folded_compare; + + if (constopnum == 0) + folded_compare = fold (build (code, type, constop, + TREE_OPERAND (varop, 0))); + else + folded_compare = fold (build (code, type, + TREE_OPERAND (varop, 0), + constop)); + if (integer_zerop (folded_compare) + || integer_onep (folded_compare)) + return omit_one_operand (type, folded_compare, varop); + + unsigned_type = type_for_size (size, 1); + precision = TYPE_PRECISION (unsigned_type); + mask = build_int_2 (~0, ~0); + TREE_TYPE (mask) = TREE_TYPE (varop); + force_fit_type (mask, 0); + mask = const_binop (RSHIFT_EXPR, mask, + size_int (precision - size), 0); newconst = fold (build (BIT_AND_EXPR, TREE_TYPE (varop), newconst, convert (TREE_TYPE (varop), - build_int_2 (size, 0)))); + mask))); } |