[PATCH] Fix PRs 33691, 33694 and 33696
Richard Guenther
rguenther@suse.de
Mon Oct 8 14:39:00 GMT 2007
This fixes a bunch of type-checking problems in fold-const.c. More to
come.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to mainline.
Richard.
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.
Index: fold-const.c
===================================================================
*** fold-const.c (revision 129036)
--- fold-const.c (working copy)
*************** fold_unary (enum tree_code code, tree ty
*** 8374,8383 ****
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);
/* 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),
build_int_cst (type, 1));
/* Convert ~ (A - 1) or ~ (A + -1) to -A. */
else if (INTEGRAL_TYPE_P (type)
--- 8374,8384 ----
if (TREE_CODE (arg0) == INTEGER_CST)
return fold_not_const (arg0, type);
else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
! 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,
! 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)
*************** fold_unary (enum tree_code code, tree ty
*** 8385,8391 ****
&& 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));
/* 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,
--- 8386,8393 ----
&& integer_onep (TREE_OPERAND (arg0, 1)))
|| (TREE_CODE (arg0) == PLUS_EXPR
&& integer_all_onesp (TREE_OPERAND (arg0, 1)))))
! 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,
*************** fold_binary (enum tree_code code, tree t
*** 10126,10140 ****
}
/* A - (-B) -> A + B */
if (TREE_CODE (arg1) == NEGATE_EXPR)
! return fold_build2 (PLUS_EXPR, type, arg0, 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));
/* Convert -A - 1 to ~A. */
if (INTEGRAL_TYPE_P (type)
&& TREE_CODE (arg0) == NEGATE_EXPR
--- 10128,10144 ----
}
/* A - (-B) -> A + B */
if (TREE_CODE (arg1) == NEGATE_EXPR)
! 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,
! 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
*************** fold_binary (enum tree_code code, tree t
*** 10889,10899 ****
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));
/* (X | Y) & Y is (X, Y). */
if (TREE_CODE (arg0) == BIT_IOR_EXPR
--- 10893,10908 ----
if (TREE_CODE (arg0) == BIT_IOR_EXPR
&& TREE_CODE (arg1) == INTEGER_CST
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
! {
! 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
Index: testsuite/gcc.dg/pr33691.c
===================================================================
*** testsuite/gcc.dg/pr33691.c (revision 0)
--- testsuite/gcc.dg/pr33691.c (revision 0)
***************
*** 0 ****
--- 1,8 ----
+ /* { dg-do compile } */
+
+ /* ICEd with type-checking enabled. */
+
+ unsigned int mgaSetTexImages(int i)
+ {
+ return ((i | 0x40) & 0xffffffc0);
+ }
Index: testsuite/gcc.dg/pr33694.c
===================================================================
*** testsuite/gcc.dg/pr33694.c (revision 0)
--- testsuite/gcc.dg/pr33694.c (revision 0)
***************
*** 0 ****
--- 1,8 ----
+ /* { dg-do compile } */
+
+ /* This used to ICE with type-checking enabled. */
+
+ __SIZE_TYPE__ cnfs_mapcntl(long pagesize)
+ {
+ return ~(__SIZE_TYPE__)(pagesize - 1);
+ }
Index: testsuite/gcc.dg/pr33696.c
===================================================================
*** testsuite/gcc.dg/pr33696.c (revision 0)
--- testsuite/gcc.dg/pr33696.c (revision 0)
***************
*** 0 ****
--- 1,13 ----
+ /* { dg-do compile } */
+
+ /* This used to ICE with type-checking enabled. */
+
+ typedef unsigned char uint8_t;
+ typedef unsigned int uint_least32_t;
+ extern int foo (long int __off);
+ void write (uint_least32_t chunk_len)
+ {
+ uint8_t tmp[4];
+ foo (-(long)chunk_len - sizeof(tmp));
+ }
+
More information about the Gcc-patches
mailing list