diff options
author | Richard Guenther <rguenther@suse.de> | 2007-10-08 14:44:14 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2007-10-08 14:44:14 +0000 |
commit | 8174836f1ebff55e127300c942adf3e689d3d3d4 (patch) | |
tree | fed6dbf121ef1138a33f97ed54004b0db8ff84e0 /gcc/fold-const.c | |
parent | 7b6cb84335d934861a6058e2751435fbad61191d (diff) | |
download | gcc-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.c | 31 |
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 |