This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR78305


I am testing the following to avoid undefined behavior when negating
a multiplication (basically extending a previous fix to properly handle
negative power of two).

Bootstrap / regtest running on x86_64-unknown-linux-gnu.

Richard.

2016-11-16  Richard Biener  <rguenther@suse.de>

	PR middle-end/78305
	* fold-const.c (negate_expr_p): Fix multiplication case.

	* gcc.dg/torture/pr78305.c: New testcase.

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 242471)
+++ gcc/fold-const.c	(working copy)
@@ -450,13 +450,15 @@ negate_expr_p (tree t)
       if (TYPE_UNSIGNED (type))
 	break;
       /* INT_MIN/n * n doesn't overflow while negating one operand it does
-         if n is a power of two.  */
+         if n is a power of (minus) two.  */
       if (INTEGRAL_TYPE_P (TREE_TYPE (t))
 	  && ! TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
 	  && ! ((TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
-		 && ! integer_pow2p (TREE_OPERAND (t, 0)))
+		 && (wi::popcount (TREE_OPERAND (t, 0))
+		     != 1 + wi::neg_p (TREE_OPERAND (t, 0), SIGNED)))
 		|| (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
-		    && ! integer_pow2p (TREE_OPERAND (t, 1)))))
+		    && (wi::popcount (TREE_OPERAND (t, 1))
+			!= 1 + wi::neg_p (TREE_OPERAND (t, 1), SIGNED)))))
 	break;
 
       /* Fall through.  */
Index: gcc/testsuite/gcc.dg/torture/pr78305.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr78305.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr78305.c	(working copy)
@@ -0,0 +1,14 @@
+/* { dg-require-effective-target int32plus } */
+/* { dg-do run } */
+
+int main ()
+{
+  int a = 2;
+  int b = 1;
+
+  int t = -1 * ( -0x40000000 * a / ( -0x20000000 + b ) )  / -1;
+
+  if (t != 4) __builtin_abort();
+
+  return 0;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]