aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2007-10-08 14:44:14 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2007-10-08 14:44:14 +0000
commit8174836f1ebff55e127300c942adf3e689d3d3d4 (patch)
treefed6dbf121ef1138a33f97ed54004b0db8ff84e0 /gcc/fold-const.c
parent7b6cb84335d934861a6058e2751435fbad61191d (diff)
downloadgcc-8174836f1ebff55e127300c942adf3e689d3d3d4.zip
gcc-8174836f1ebff55e127300c942adf3e689d3d3d4.tar.gz
gcc-8174836f1ebff55e127300c942adf3e689d3d3d4.tar.bz2
re PR middle-end/33691 (Type checking error with bitwise and/or)
2007-10-08 Richard Guenther <rguenther@suse.de> PR middle-end/33691 PR middle-end/33694 PR middle-end/33696 * fold-const.c (fold_binary): Use the correct types when folding (A | CST1) & CST2 to (A & CST2) | (CST1 & CST2). (fold_binary): Use the correct types when folding (-A) - B to (-B) - A. (fold_unary): Use the correct types when folding ~(X). * gcc.dg/pr33691.c: New testcase. * gcc.dg/pr33694.c: Likewise. * gcc.dg/pr33696.c: Likewise. From-SVN: r129128
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 46e0e33..0313c0c 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8374,10 +8374,11 @@ fold_unary (enum tree_code code, tree type, tree op0)
if (TREE_CODE (arg0) == INTEGER_CST)
return fold_not_const (arg0, type);
else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
- return TREE_OPERAND (arg0, 0);
+ return TREE_OPERAND (op0, 0);
/* Convert ~ (-A) to A - 1. */
else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
- return fold_build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0),
+ return fold_build2 (MINUS_EXPR, type,
+ fold_convert (type, TREE_OPERAND (arg0, 0)),
build_int_cst (type, 1));
/* Convert ~ (A - 1) or ~ (A + -1) to -A. */
else if (INTEGRAL_TYPE_P (type)
@@ -8385,7 +8386,8 @@ fold_unary (enum tree_code code, tree type, tree op0)
&& integer_onep (TREE_OPERAND (arg0, 1)))
|| (TREE_CODE (arg0) == PLUS_EXPR
&& integer_all_onesp (TREE_OPERAND (arg0, 1)))))
- return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0));
+ return fold_build1 (NEGATE_EXPR, type,
+ fold_convert (type, TREE_OPERAND (arg0, 0)));
/* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify. */
else if (TREE_CODE (arg0) == BIT_XOR_EXPR
&& (tem = fold_unary (BIT_NOT_EXPR, type,
@@ -10126,15 +10128,17 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
}
/* A - (-B) -> A + B */
if (TREE_CODE (arg1) == NEGATE_EXPR)
- return fold_build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0));
+ return fold_build2 (PLUS_EXPR, type, op0,
+ fold_convert (type, TREE_OPERAND (arg1, 0)));
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR
&& (FLOAT_TYPE_P (type)
|| INTEGRAL_TYPE_P (type))
&& negate_expr_p (arg1)
&& reorder_operands_p (arg0, arg1))
- return fold_build2 (MINUS_EXPR, type, negate_expr (arg1),
- TREE_OPERAND (arg0, 0));
+ return fold_build2 (MINUS_EXPR, type,
+ fold_convert (type, negate_expr (arg1)),
+ fold_convert (type, TREE_OPERAND (arg0, 0)));
/* Convert -A - 1 to ~A. */
if (INTEGRAL_TYPE_P (type)
&& TREE_CODE (arg0) == NEGATE_EXPR
@@ -10889,11 +10893,16 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (TREE_CODE (arg0) == BIT_IOR_EXPR
&& TREE_CODE (arg1) == INTEGER_CST
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
- return fold_build2 (BIT_IOR_EXPR, type,
- fold_build2 (BIT_AND_EXPR, type,
- TREE_OPERAND (arg0, 0), arg1),
- fold_build2 (BIT_AND_EXPR, type,
- TREE_OPERAND (arg0, 1), arg1));
+ {
+ tree tmp1 = fold_convert (TREE_TYPE (arg0), arg1);
+ tree tmp2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
+ TREE_OPERAND (arg0, 0), tmp1);
+ tree tmp3 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
+ TREE_OPERAND (arg0, 1), tmp1);
+ return fold_convert (type,
+ fold_build2 (BIT_IOR_EXPR, TREE_TYPE (arg0),
+ tmp2, tmp3));
+ }
/* (X | Y) & Y is (X, Y). */
if (TREE_CODE (arg0) == BIT_IOR_EXPR