Hi! As mentioned in the PR, for boolean x we currently optimize in phiopt x ? 0 : -1 into -(int)!x but it can be optimized as (int) x - 1 which is one less operation both in GIMPLE and in x86 assembly.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? And/or, shall we have a match.pd optimization to turn that -(type)!x for BOOLEAN_TYPE (or other 1 bit unsigned precision values) into (type) - 1. 2020-12-05 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/96232 * tree-ssa-phiopt.c (conditional_replacement): Optimize x ? 0 : -1 as (int) x - 1 rather than -(int)!x. * gcc.dg/tree-ssa/pr96232-1.c: New test. --- gcc/tree-ssa-phiopt.c.jj 2020-11-04 11:58:58.670252748 +0100 +++ gcc/tree-ssa-phiopt.c 2020-12-04 17:27:53.472837921 +0100 @@ -827,10 +827,24 @@ conditional_replacement (basic_block con if (neg) { - cond = fold_convert_loc (gimple_location (stmt), - TREE_TYPE (result), cond); - cond = fold_build1_loc (gimple_location (stmt), - NEGATE_EXPR, TREE_TYPE (cond), cond); + if (TREE_CODE (cond) == TRUTH_NOT_EXPR + && INTEGRAL_TYPE_P (TREE_TYPE (nonzero_arg))) + { + /* x ? 0 : -1 is better optimized as (int) x - 1 than + -(int)!x. */ + cond = fold_convert_loc (gimple_location (stmt), + TREE_TYPE (result), + TREE_OPERAND (cond, 0)); + cond = fold_build2_loc (gimple_location (stmt), PLUS_EXPR, + TREE_TYPE (result), cond, nonzero_arg); + } + else + { + cond = fold_convert_loc (gimple_location (stmt), + TREE_TYPE (result), cond); + cond = fold_build1_loc (gimple_location (stmt), + NEGATE_EXPR, TREE_TYPE (cond), cond); + } } else if (shift) { --- gcc/testsuite/gcc.dg/tree-ssa/pr96232-1.c.jj 2020-12-04 17:32:40.607615276 +0100 +++ gcc/testsuite/gcc.dg/tree-ssa/pr96232-1.c 2020-12-04 17:33:09.914286354 +0100 @@ -0,0 +1,11 @@ +/* PR tree-optimization/96232 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump " \\+ -1;" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "~x_\[0-9]*\\\(D\\\)" "optimized" } } */ + +int +foo (_Bool x) +{ + return x ? 0 : -1; +} Jakub