This is the mail archive of the gcc-bugs@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]

[Bug tree-optimization/78305] Wrong constant folding


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.  */

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