[PATCH] Fix PR37125/PR36548, extract_muldiv bug with %

Richard Guenther rguenther@suse.de
Fri Aug 22 13:30:00 GMT 2008


Cancelling of (X * C) % C is only valid if the multiplication does
not overflow.  Fixed by only doing this for types which have undefined
overflow.  Not quite.  We end up needing to do this for sizetype
types as well, as otherwise DECL_FIELD_BIT_OFFSET in some cases ends
up with a non-constant expression which breaks Ada bootstrap :/

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk,
queued for 4.3.3.

Richard.

2008-08-22  Richard Guenther  <rguenther@suse.de>

	PR middle-end/36548
	PR middle-end/37125
	* fold-const.c (extract_muldiv_1): Optimize (X * C1) % C2 only
	if the multiplication does not overflow.

	* gcc.c-torture/execute/pr37125.c: New testcase.

Index: gcc/testsuite/gcc.c-torture/execute/pr37125.c
===================================================================
*** gcc/testsuite/gcc.c-torture/execute/pr37125.c	(revision 0)
--- gcc/testsuite/gcc.c-torture/execute/pr37125.c	(revision 0)
***************
*** 0 ****
--- 1,23 ----
+ extern void abort (void);
+ 
+ static inline unsigned int
+ mod_rhs(int rhs)
+ {
+   if (rhs == 0) return 1;
+   return rhs;
+ }
+ 
+ void func_44 (unsigned int p_45);
+ void func_44 (unsigned int p_45)
+ {
+   if (!((p_45 * -9) % mod_rhs (-9))) {
+       abort();
+   }
+ }
+ 
+ int main (void)
+ {
+   func_44 (2);
+   return 0;
+ }
+ 
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 139433)
--- gcc/fold-const.c	(working copy)
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 5930,5938 ****
  	 (C * 8) % 4 since we know that's zero.  */
        if ((code == TRUNC_MOD_EXPR || code == CEIL_MOD_EXPR
  	   || code == FLOOR_MOD_EXPR || code == ROUND_MOD_EXPR)
  	  && TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
  	  && integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
! 	return omit_one_operand (type, integer_zero_node, op0);
  
        /* ... fall through ...  */
  
--- 5930,5949 ----
  	 (C * 8) % 4 since we know that's zero.  */
        if ((code == TRUNC_MOD_EXPR || code == CEIL_MOD_EXPR
  	   || code == FLOOR_MOD_EXPR || code == ROUND_MOD_EXPR)
+ 	  /* If the multiplication can overflow we cannot optimize this.
+ 	     ???  Until we can properly mark individual operations as
+ 	     not overflowing we need to treat sizetype special here as
+ 	     stor-layout relies on this opimization to make
+ 	     DECL_FIELD_BIT_OFFSET always a constant.  */
+ 	  && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t))
+ 	      || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
+ 		  && TYPE_IS_SIZETYPE (TREE_TYPE (t))))
  	  && TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
  	  && integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
! 	{
! 	  *strict_overflow_p = true;
! 	  return omit_one_operand (type, integer_zero_node, op0);
! 	}
  
        /* ... fall through ...  */
  



More information about the Gcc-patches mailing list