This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/78305] Wrong constant folding
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 16 Nov 2016 09:31:30 +0000
- Subject: [Bug tree-optimization/78305] Wrong constant folding
- Auto-submitted: auto-generated
- References: <bug-78305-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78305
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
So it's negating a * -1073741824 via
case MULT_EXPR:
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 (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)))
|| (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
&& ! integer_pow2p (TREE_OPERAND (t, 1)))))
break;
/* Fall through. */
case RDIV_EXPR:
if (! HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (TREE_TYPE (t))))
return negate_expr_p (TREE_OPERAND (t, 1))
|| negate_expr_p (TREE_OPERAND (t, 0));
break;
as we can negate -1073741824. That's because integer_pow2p returns false
for -1073741824 ...
Testing
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. */