diff mbox

Fix PR49958

Message ID alpine.LNX.2.00.1108031404400.810@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Aug. 3, 2011, 12:05 p.m. UTC
This fixes a wrong re-association which can introduce undefined
overflow.  The fix is to perform this only when overflow is known
to wrap.

Bootstrap and regtest pending on x86_64-unknown-linux-gnu.

Richard.

2011-08-03  Richard Guenther  <rguenther@suse.de>

	PR middle-end/49958
	* fold-const.c (fold_binary_loc): Only associate
	(+ (+ (* a b) c) (* d e)) as (+ (+ (* a b) (* d e)) c) if
	overflow wraps.
diff mbox

Patch

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 177094)
+++ gcc/fold-const.c	(working copy)
@@ -9712,12 +9712,13 @@  fold_binary_loc (location_t loc,
 	  /* Reassociate (plus (plus (mult) (foo)) (mult)) as
 	     (plus (plus (mult) (mult)) (foo)) so that we can
 	     take advantage of the factoring cases below.  */
-	  if (((TREE_CODE (arg0) == PLUS_EXPR
-		|| TREE_CODE (arg0) == MINUS_EXPR)
-	       && TREE_CODE (arg1) == MULT_EXPR)
-	      || ((TREE_CODE (arg1) == PLUS_EXPR
-		   || TREE_CODE (arg1) == MINUS_EXPR)
-		  && TREE_CODE (arg0) == MULT_EXPR))
+	  if (TYPE_OVERFLOW_WRAPS (type)
+	      && (((TREE_CODE (arg0) == PLUS_EXPR
+		    || TREE_CODE (arg0) == MINUS_EXPR)
+		   && TREE_CODE (arg1) == MULT_EXPR)
+		  || ((TREE_CODE (arg1) == PLUS_EXPR
+		       || TREE_CODE (arg1) == MINUS_EXPR)
+		      && TREE_CODE (arg0) == MULT_EXPR)))
 	    {
 	      tree parg0, parg1, parg, marg;
 	      enum tree_code pcode;
Index: gcc/testsuite/gcc.dg/torture/pr49958.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr49958.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr49958.c	(revision 0)
@@ -0,0 +1,11 @@ 
+/* { dg-do run } */
+/* { dg-options "-fstrict-overflow" } */
+
+extern void abort (void);
+int foo (int i, int j, int o, int m) { return i*o + 1 + j*m > 1; }
+int main()
+{
+  if (foo (- __INT_MAX__ - 1, -1, 1, 1))
+    abort ();
+  return 0;
+}