[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