On Wed, 6 Jun 2018, Jakub Jelinek wrote: > Hi! > > The following testcase shows another case that can be handled easily. > If rhs2 is defined in a bb dominated by first_bb, we need to be careful > because we can't rely on value range information of it after we optimize the > guarding >= 0 check into 1. On the testcase, we have there > rhs2 = (int) something_N; > cast where both types are integral with the same precision, so we can in > this case just check if something_N is defined in some bb not dominated by > first_bb, or if it is result of & constant, or zero extension etc. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Thanks, Richard. > 2018-06-05 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/69615 > * tree-ssa-reassoc.c (optimize_range_tests_var_bound): If rhs2 is lhs > of a cast from a same precision integral SSA_NAME in a bb dominated > by first_bb, retry with rhs2 set to the rhs1 of the cast. Don't emit > cast to utype if rhs2 has already a compatible type. > > * gcc.dg/tree-ssa/pr69615.c: New test. > > --- gcc/tree-ssa-reassoc.c.jj 2018-04-27 09:08:57.667850280 +0200 > +++ gcc/tree-ssa-reassoc.c 2018-06-05 17:01:39.028144763 +0200 > @@ -3172,7 +3172,7 @@ optimize_range_tests_var_bound (enum tre > to (unsigned) k_32 < (unsigned) iftmp.0_44, then we would execute > those stmts even for negative k_32 and the value ranges would be no > longer guaranteed and so the optimization would be invalid. */ > - if (opcode == ERROR_MARK) > + while (opcode == ERROR_MARK) > { > gimple *g = SSA_NAME_DEF_STMT (rhs2); > basic_block bb2 = gimple_bb (g); > @@ -3182,21 +3182,37 @@ optimize_range_tests_var_bound (enum tre > { > /* As an exception, handle a few common cases. */ > if (gimple_assign_cast_p (g) > - && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (g))) > - && TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g))) > - && (TYPE_PRECISION (TREE_TYPE (rhs2)) > - > TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (g))))) > - /* Zero-extension is always ok. */ ; > + && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (g)))) > + { > + tree op0 = gimple_assign_rhs1 (g); > + if (TYPE_UNSIGNED (TREE_TYPE (op0)) > + && (TYPE_PRECISION (TREE_TYPE (rhs2)) > + > TYPE_PRECISION (TREE_TYPE (op0)))) > + /* Zero-extension is always ok. */ > + break; > + else if (TYPE_PRECISION (TREE_TYPE (rhs2)) > + == TYPE_PRECISION (TREE_TYPE (op0)) > + && TREE_CODE (op0) == SSA_NAME) > + { > + /* Cast from signed to unsigned or vice versa. Retry > + with the op0 as new rhs2. */ > + rhs2 = op0; > + continue; > + } > + } > else if (is_gimple_assign (g) > && gimple_assign_rhs_code (g) == BIT_AND_EXPR > && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST > && !wi::neg_p (wi::to_wide (gimple_assign_rhs2 (g)))) > /* Masking with INTEGER_CST with MSB clear is always ok > - too. */ ; > - else > - continue; > + too. */ > + break; > + rhs2 = NULL_TREE; > } > + break; > } > + if (rhs2 == NULL_TREE) > + continue; > > wide_int nz = get_nonzero_bits (rhs2); > if (wi::neg_p (nz)) > @@ -3253,10 +3269,13 @@ optimize_range_tests_var_bound (enum tre > gimple_set_uid (g, uid); > rhs1 = gimple_assign_lhs (g); > gsi_insert_before (&gsi, g, GSI_SAME_STMT); > - g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, rhs2); > - gimple_set_uid (g, uid); > - rhs2 = gimple_assign_lhs (g); > - gsi_insert_before (&gsi, g, GSI_SAME_STMT); > + if (!useless_type_conversion_p (utype, TREE_TYPE (rhs2))) > + { > + g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, rhs2); > + gimple_set_uid (g, uid); > + rhs2 = gimple_assign_lhs (g); > + gsi_insert_before (&gsi, g, GSI_SAME_STMT); > + } > if (tree_swap_operands_p (rhs1, rhs2)) > { > std::swap (rhs1, rhs2); > --- gcc/testsuite/gcc.dg/tree-ssa/pr69615.c.jj 2018-06-06 > 12:55:16.535159073 +0200 > +++ gcc/testsuite/gcc.dg/tree-ssa/pr69615.c 2018-06-06 12:54:53.993133421 > +0200 > @@ -0,0 +1,16 @@ > +/* PR tree-optimization/69615 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump-not " >= 0" "optimized" } } */ > +/* { dg-final { scan-tree-dump-not " < 0" "optimized" } } */ > + > +extern void foo (void); > + > +void > +bar (int z, unsigned int y) > +{ > + long long x = z; > + y &= 0xf; > + if (x >= 0 && x < (int) y) > + foo (); > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)