On December 5, 2020 10:14:49 AM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >The following patch improves code generation on the included testcase >by >enabling two_value_replacement on booleans. It does that only for >arg0/arg1 >values that conditional_replacement doesn't handle, and only does it if >not >in the early phiopt pass, because conditional_replacement isn't done >early >either. >I must say I'm not sure about that, in PR87105 / PR87608 you've added >the >early phiopt pass and specifically excluded conditional_replacement and >a >few others from being optimized early, but then 3 months later I've >added >two_value_replacement and didn't restrict it to !early_p. Shall we >instead >do two_value_replacement only in late phiopt?
Yeah, I guess that would make sense. I don't remember exactly but I saw regressions with early doing if conversion besides min/max/abs detection. >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Ok. Richard. >2020-12-05 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/96232 > * tree-ssa-phiopt.c (two_value_replacement): Add early_p argument. > If false, optimize even boolean lhs cases as long as arg0 has wider > precision and conditional_replacement doesn't handle that case. > > * gcc.dg/tree-ssa/pr96232-2.c: New test. > >--- gcc/tree-ssa-phiopt.c.jj 2020-12-04 17:27:53.472837921 +0100 >+++ gcc/tree-ssa-phiopt.c 2020-12-04 17:54:56.070689584 +0100 >@@ -51,7 +51,7 @@ along with GCC; see the file COPYING3. > > static unsigned int tree_ssa_phiopt_worker (bool, bool, bool); >static bool two_value_replacement (basic_block, basic_block, edge, gphi >*, >- tree, tree); >+ tree, tree, bool); > static bool conditional_replacement (basic_block, basic_block, > edge, edge, gphi *, tree, tree); >static gphi *factor_out_conditional_conversion (edge, edge, gphi *, >tree, tree, >@@ -337,7 +337,7 @@ tree_ssa_phiopt_worker (bool do_store_el > } > > /* Do the replacement of conditional if it can be done. */ >- if (two_value_replacement (bb, bb1, e2, phi, arg0, arg1)) >+ if (two_value_replacement (bb, bb1, e2, phi, arg0, arg1, early_p)) > cfgchanged = true; > else if (!early_p > && conditional_replacement (bb, bb1, e1, e2, phi, >@@ -614,7 +614,7 @@ factor_out_conditional_conversion (edge > > static bool > two_value_replacement (basic_block cond_bb, basic_block middle_bb, >- edge e1, gphi *phi, tree arg0, tree arg1) >+ edge e1, gphi *phi, tree arg0, tree arg1, bool early_p) > { > /* Only look for adjacent integer constants. */ > if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0)) >@@ -635,7 +635,7 @@ two_value_replacement (basic_block cond_ > > if (TREE_CODE (lhs) != SSA_NAME > || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)) >- || TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE >+ || (early_p && TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE) > || TREE_CODE (rhs) != INTEGER_CST) > return false; > >@@ -648,9 +648,25 @@ two_value_replacement (basic_block cond_ > return false; > } > >+ /* Defer boolean x ? 0 : {1,-1} or x ? {1,-1} : 0 to >+ conditional_replacement. */ >+ if (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE >+ && (integer_zerop (arg0) >+ || integer_zerop (arg1) >+ || TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE >+ || (TYPE_PRECISION (TREE_TYPE (arg0)) >+ <= TYPE_PRECISION (TREE_TYPE (lhs))))) >+ return false; >+ > wide_int min, max; >- if (get_range_info (lhs, &min, &max) != VR_RANGE >- || min + 1 != max >+ if (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE) >+ { >+ min = wi::to_wide (boolean_false_node); >+ max = wi::to_wide (boolean_true_node); >+ } >+ else if (get_range_info (lhs, &min, &max) != VR_RANGE) >+ return false; >+ if (min + 1 != max > || (wi::to_wide (rhs) != min > && wi::to_wide (rhs) != max)) > return false; >--- gcc/testsuite/gcc.dg/tree-ssa/pr96232-2.c.jj 2020-12-04 >17:56:22.180730234 +0100 >+++ gcc/testsuite/gcc.dg/tree-ssa/pr96232-2.c 2020-12-04 >17:57:27.973997239 +0100 >@@ -0,0 +1,18 @@ >+/* PR tree-optimization/96232 */ >+/* { dg-do compile } */ >+/* { dg-options "-O2 -fdump-tree-optimized" } */ >+/* { dg-final { scan-tree-dump " 38 - " "optimized" } } */ >+/* { dg-final { scan-tree-dump " \\+ 97;" "optimized" } } */ >+/* { dg-final { scan-tree-dump-not "PHI <" "optimized" } } */ >+ >+int >+foo (_Bool x) >+{ >+ return x ? 37 : 38; >+} >+ >+int >+bar (_Bool x) >+{ >+ return x ? 98 : 97; >+} > > Jakub