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" } } */