aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@issan.informatik.uni-dortmund.de>1998-06-02 21:53:37 +0000
committerJeff Law <law@gcc.gnu.org>1998-06-02 15:53:37 -0600
commitdf0e526f2ddd7af54268839582a8b278249da86e (patch)
tree1ebe3908161c9d4f702e0bf08a2f7ff5e4835a9b /gcc
parentccdb92510523a0302c4bd058a51530d089aac21f (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c53
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)));
}