The following fixes phiopt to not introduce undefined behavior
in its abs replacement code in case we negate only positive values
in the original code.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2016-11-07  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/78228
        * tree-ssa-phiopt.c (abs_replacement): Avoid introducing
        undefined behavior.

        * gcc.dg/tree-ssa/phi-opt-15.c: New testcase.

Index: gcc/tree-ssa-phiopt.c
===================================================================
--- gcc/tree-ssa-phiopt.c       (revision 241891)
+++ gcc/tree-ssa-phiopt.c       (working copy)
@@ -1453,6 +1453,14 @@ abs_replacement (basic_block cond_bb, ba
   else
     negate = false;
 
+  /* If the code negates only iff positive then make sure to not
+     introduce undefined behavior when negating or computing the absolute.
+     ???  We could use range info if present to check for arg1 == INT_MIN.  */
+  if (negate
+      && (ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg1))
+         && ! TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))))
+    return false;
+
   result = duplicate_ssa_name (result, NULL);
 
   if (negate)
Index: gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c  (revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c  (working copy)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int
+foo (int i)
+{
+  if (i > 0)
+    i = -i;
+  return i;
+}
+
+/* { dg-final { scan-tree-dump-not "ABS" "optimized" } } */

Reply via email to