[PATCH] Fix PR33779, extract_muldiv introducing new undefined overflow
Richard Guenther
rguenther@suse.de
Wed Oct 31 13:46:00 GMT 2007
extract_muldiv happily folds ((unsigned)(i + 1)) * 4 to
(unsigned)((i + 1) * 4) which is bogus.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to mainline.
Richard.
2007-10-31 Richard Guenther <rguenther@suse.de>
PR middle-end/33779
* fold-const.c (extract_muldiv_1): Make sure to not introduce
new undefined integer overflow.
(fold_binary): Avoid useless conversion.
* gcc.c-torture/execute/pr33779-1.c: New testcase.
* gcc.c-torture/execute/pr33779-2.c: Likewise.
Index: fold-const.c
===================================================================
*** fold-const.c (revision 129795)
--- fold-const.c (working copy)
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 6060,6066 ****
then we cannot pass through this conversion. */
|| (code != MULT_EXPR
&& (TYPE_UNSIGNED (ctype)
! != TYPE_UNSIGNED (TREE_TYPE (op0))))))
break;
/* Pass the constant down and see if we can make a simplification. If
--- 6060,6071 ----
then we cannot pass through this conversion. */
|| (code != MULT_EXPR
&& (TYPE_UNSIGNED (ctype)
! != TYPE_UNSIGNED (TREE_TYPE (op0))))
! /* ... or has undefined overflow while the converted to
! type has not, we cannot do the operation in the inner type
! as that would introduce undefined overflow. */
! || (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0))
! && !TYPE_OVERFLOW_UNDEFINED (type))))
break;
/* Pass the constant down and see if we can make a simplification. If
*************** fold_binary (enum tree_code code, tree t
*** 10266,10274 ****
strict_overflow_p = false;
if (TREE_CODE (arg1) == INTEGER_CST
! && 0 != (tem = extract_muldiv (op0,
! fold_convert (type, arg1),
! code, NULL_TREE,
&strict_overflow_p)))
{
if (strict_overflow_p)
--- 10271,10277 ----
strict_overflow_p = false;
if (TREE_CODE (arg1) == INTEGER_CST
! && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE,
&strict_overflow_p)))
{
if (strict_overflow_p)
Index: testsuite/gcc.c-torture/execute/pr33779-1.c
===================================================================
*** testsuite/gcc.c-torture/execute/pr33779-1.c (revision 0)
--- testsuite/gcc.c-torture/execute/pr33779-1.c (revision 0)
***************
*** 0 ****
--- 1,14 ----
+ int foo(int i)
+ {
+ if (((unsigned)(i + 1)) * 4 == 0)
+ return 1;
+ return 0;
+ }
+
+ extern void abort(void);
+ int main()
+ {
+ if (foo(0x3fffffff) == 0)
+ abort ();
+ return 0;
+ }
Index: testsuite/gcc.c-torture/execute/pr33779-2.c
===================================================================
*** testsuite/gcc.c-torture/execute/pr33779-2.c (revision 0)
--- testsuite/gcc.c-torture/execute/pr33779-2.c (revision 0)
***************
*** 0 ****
--- 1,12 ----
+ int foo(int i)
+ {
+ return ((int)((unsigned)(i + 1) * 4)) / 4;
+ }
+
+ extern void abort(void);
+ int main()
+ {
+ if (foo(0x3fffffff) != 0)
+ abort ();
+ return 0;
+ }
More information about the Gcc-patches
mailing list