This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR78305
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 16 Nov 2016 10:32:47 +0100 (CET)
- Subject: [PATCH] Fix PR78305
- Authentication-results: sourceware.org; auth=none
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;
+}