Hello,
this patch extends the property that x*x is non-negative, which was
already known for floats, to integers with undefined overflow.
2013-03-19 Marc Glisse <[email protected]>
PR tree-optimization/56355
gcc/
* fold-const.c (tree_binary_nonnegative_warnv_p) <MULT_EXPR>:
Also handle integers with undefined overflow.
gcc/testsuite/
* gcc.dg/pr56355-1.c: New file.
--
Marc GlisseIndex: gcc/testsuite/gcc.dg/pr56355-1.c
===================================================================
--- gcc/testsuite/gcc.dg/pr56355-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr56355-1.c (revision 0)
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wstrict-overflow=4" } */
+
+int
+f (int i)
+{
+ return __builtin_abs (i * i); /* { dg-warning "assuming signed overflow" } */
+}
Property changes on: gcc/testsuite/gcc.dg/pr56355-1.c
___________________________________________________________________
Added: svn:eol-style
+ native
Added: svn:keywords
+ Author Date Id Revision URL
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c (revision 196633)
+++ gcc/fold-const.c (working copy)
@@ -15286,29 +15286,32 @@ tree_binary_nonnegative_warnv_p (enum tr
&& TREE_CODE (inner2) == INTEGER_TYPE && TYPE_UNSIGNED (inner2))
{
unsigned int prec = MAX (TYPE_PRECISION (inner1),
TYPE_PRECISION (inner2)) + 1;
return prec < TYPE_PRECISION (type);
}
}
break;
case MULT_EXPR:
- if (FLOAT_TYPE_P (type))
+ if (FLOAT_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
{
- /* x * x for floating point x is always non-negative. */
- if (operand_equal_p (op0, op1, 0))
- return true;
- return (tree_expr_nonnegative_warnv_p (op0,
- strict_overflow_p)
- && tree_expr_nonnegative_warnv_p (op1,
- strict_overflow_p));
+ /* x * x is always non-negative for floating point x
+ or without overflow. */
+ if (operand_equal_p (op0, op1, 0)
+ || (tree_expr_nonnegative_warnv_p (op0, strict_overflow_p)
+ && tree_expr_nonnegative_warnv_p (op1, strict_overflow_p)))
+ {
+ if (TYPE_OVERFLOW_UNDEFINED (type))
+ *strict_overflow_p = true;
+ return true;
+ }
}
/* zero_extend(x) * zero_extend(y) is non-negative if x and y are
both unsigned and their total bits is shorter than the result. */
if (TREE_CODE (type) == INTEGER_TYPE
&& (TREE_CODE (op0) == NOP_EXPR || TREE_CODE (op0) == INTEGER_CST)
&& (TREE_CODE (op1) == NOP_EXPR || TREE_CODE (op1) == INTEGER_CST))
{
tree inner0 = (TREE_CODE (op0) == NOP_EXPR)
? TREE_TYPE (TREE_OPERAND (op0, 0))