On Mon, Aug 28, 2017 at 10:16 PM, Bill Schmidt
<wschm...@linux.vnet.ibm.com> wrote:
>> On Aug 28, 2017, at 7:37 AM, Richard Biener <richard.guent...@gmail.com> 
>> wrote:
>>
>> Not sure, but would it be fixed in a similar way when writing
> <snip>
>> ?
>
> Thanks, Richard, that works very well.  I decided this was a good opportunity 
> to also
> simplify the control flow a little with early returns.  Here's the result.  
> Bootstrapped and
> tested on powerpc64le-linux-gnu with no regressions.  Is this ok for trunk, 
> and
> eventually for backport to gcc 5, 6, and 7?  (I can omit the control flow 
> cleanups for
> the older releases if desired.)

Note I removed the to_shwi () != HOST_WIDE_INT_MIN check and we might end up
negating a signed MIN value, turning it into itself but doing plus -> minus in

> +  if (wi::neg_p (bump))
>      {
> -      enum tree_code code = PLUS_EXPR;
> -      tree bump_tree;
> -      gimple *stmt_to_print = NULL;
> +      code = MINUS_EXPR;
> +      bump = -bump;
> +    }

I'm not sure if that's an issue in practice (I doubt).  I think we
keep whatever the
user wrote if you write that in source in regular folding, not doing x - INT_MIN
to x + INT_MIN canonicalization.  Was the != HOST_WIDE_INT_MIN check
done for any wrong-code issue?

Patch is ok.  Cleanups are fine to backport if they are obvious (the
patch doesn't tell that ;))
Please wait a few days with backporting though.

Thanks,
Richard.

> Thanks,
> Bill
>
> [gcc]
>
> 2017-08-03  Bill Schmidt  <wschm...@linux.vnet.ibm.com>
>             Jakub Jelinek  <ja...@redhat.com>
>             Richard Biener  <rguent...@suse.de>
>
>         PR tree-optimization/81503
>         * gimple-ssa-strength-reduction.c (replace_mult_candidate): Ensure
>         folded constant fits in the target type; reorder tests for clarity.
>
> [gcc/testsuite]
>
> 2017-08-03  Bill Schmidt  <wschm...@linux.vnet.ibm.com>
>             Jakub Jelinek  <ja...@redhat.com>
>             Richard Biener  <rguent...@suse.de>
>
>         PR tree-optimization/81503
>         * gcc.c-torture/execute/pr81503.c: New file.
>
>
> Index: gcc/gimple-ssa-strength-reduction.c
> ===================================================================
> --- gcc/gimple-ssa-strength-reduction.c (revision 251369)
> +++ gcc/gimple-ssa-strength-reduction.c (working copy)
> @@ -2089,104 +2089,104 @@ replace_mult_candidate (slsr_cand_t c, tree basis_
>    tree target_type = TREE_TYPE (gimple_assign_lhs (c->cand_stmt));
>    enum tree_code cand_code = gimple_assign_rhs_code (c->cand_stmt);
>
> -  /* It is highly unlikely, but possible, that the resulting
> -     bump doesn't fit in a HWI.  Abandon the replacement
> -     in this case.  This does not affect siblings or dependents
> -     of C.  Restriction to signed HWI is conservative for unsigned
> -     types but allows for safe negation without twisted logic.  */
> -  if (wi::fits_shwi_p (bump)
> -      && bump.to_shwi () != HOST_WIDE_INT_MIN
> -      /* It is not useful to replace casts, copies, negates, or adds of
> -        an SSA name and a constant.  */
> -      && cand_code != SSA_NAME
> -      && !CONVERT_EXPR_CODE_P (cand_code)
> -      && cand_code != PLUS_EXPR
> -      && cand_code != POINTER_PLUS_EXPR
> -      && cand_code != MINUS_EXPR
> -      && cand_code != NEGATE_EXPR)
> +  /* It is not useful to replace casts, copies, negates, or adds of
> +     an SSA name and a constant.  */
> +  if (cand_code == SSA_NAME
> +      || CONVERT_EXPR_CODE_P (cand_code)
> +      || cand_code == PLUS_EXPR
> +      || cand_code == POINTER_PLUS_EXPR
> +      || cand_code == MINUS_EXPR
> +      || cand_code == NEGATE_EXPR)
> +    return;
> +
> +  enum tree_code code = PLUS_EXPR;
> +  tree bump_tree;
> +  gimple *stmt_to_print = NULL;
> +
> +  if (wi::neg_p (bump))
>      {
> -      enum tree_code code = PLUS_EXPR;
> -      tree bump_tree;
> -      gimple *stmt_to_print = NULL;
> +      code = MINUS_EXPR;
> +      bump = -bump;
> +    }
>
> -      /* If the basis name and the candidate's LHS have incompatible
> -        types, introduce a cast.  */
> -      if (!useless_type_conversion_p (target_type, TREE_TYPE (basis_name)))
> -       basis_name = introduce_cast_before_cand (c, target_type, basis_name);
> -      if (wi::neg_p (bump))
> +  /* It is possible that the resulting bump doesn't fit in target_type.
> +     Abandon the replacement in this case.  This does not affect
> +     siblings or dependents of C.  */
> +  if (bump != wi::ext (bump, TYPE_PRECISION (target_type),
> +                      TYPE_SIGN (target_type)))
> +    return;
> +
> +  bump_tree = wide_int_to_tree (target_type, bump);
> +
> +  /* If the basis name and the candidate's LHS have incompatible types,
> +     introduce a cast.  */
> +  if (!useless_type_conversion_p (target_type, TREE_TYPE (basis_name)))
> +    basis_name = introduce_cast_before_cand (c, target_type, basis_name);
> +
> +  if (dump_file && (dump_flags & TDF_DETAILS))
> +    {
> +      fputs ("Replacing: ", dump_file);
> +      print_gimple_stmt (dump_file, c->cand_stmt, 0);
> +    }
> +
> +  if (bump == 0)
> +    {
> +      tree lhs = gimple_assign_lhs (c->cand_stmt);
> +      gassign *copy_stmt = gimple_build_assign (lhs, basis_name);
> +      gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
> +      slsr_cand_t cc = c;
> +      gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
> +      gsi_replace (&gsi, copy_stmt, false);
> +      c->cand_stmt = copy_stmt;
> +      while (cc->next_interp)
>         {
> -         code = MINUS_EXPR;
> -         bump = -bump;
> +         cc = lookup_cand (cc->next_interp);
> +         cc->cand_stmt = copy_stmt;
>         }
> -
> -      bump_tree = wide_int_to_tree (target_type, bump);
> -
>        if (dump_file && (dump_flags & TDF_DETAILS))
> +       stmt_to_print = copy_stmt;
> +    }
> +  else
> +    {
> +      tree rhs1, rhs2;
> +      if (cand_code != NEGATE_EXPR) {
> +       rhs1 = gimple_assign_rhs1 (c->cand_stmt);
> +       rhs2 = gimple_assign_rhs2 (c->cand_stmt);
> +      }
> +      if (cand_code != NEGATE_EXPR
> +         && ((operand_equal_p (rhs1, basis_name, 0)
> +              && operand_equal_p (rhs2, bump_tree, 0))
> +             || (operand_equal_p (rhs1, bump_tree, 0)
> +                 && operand_equal_p (rhs2, basis_name, 0))))
>         {
> -         fputs ("Replacing: ", dump_file);
> -         print_gimple_stmt (dump_file, c->cand_stmt, 0);
> +         if (dump_file && (dump_flags & TDF_DETAILS))
> +           {
> +             fputs ("(duplicate, not actually replacing)", dump_file);
> +             stmt_to_print = c->cand_stmt;
> +           }
>         }
> -
> -      if (bump == 0)
> +      else
>         {
> -         tree lhs = gimple_assign_lhs (c->cand_stmt);
> -         gassign *copy_stmt = gimple_build_assign (lhs, basis_name);
>           gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
>           slsr_cand_t cc = c;
> -         gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
> -         gsi_replace (&gsi, copy_stmt, false);
> -         c->cand_stmt = copy_stmt;
> +         gimple_assign_set_rhs_with_ops (&gsi, code, basis_name, bump_tree);
> +         update_stmt (gsi_stmt (gsi));
> +         c->cand_stmt = gsi_stmt (gsi);
>           while (cc->next_interp)
>             {
>               cc = lookup_cand (cc->next_interp);
> -             cc->cand_stmt = copy_stmt;
> +             cc->cand_stmt = gsi_stmt (gsi);
>             }
>           if (dump_file && (dump_flags & TDF_DETAILS))
> -           stmt_to_print = copy_stmt;
> +           stmt_to_print = gsi_stmt (gsi);
>         }
> -      else
> -       {
> -         tree rhs1, rhs2;
> -         if (cand_code != NEGATE_EXPR) {
> -           rhs1 = gimple_assign_rhs1 (c->cand_stmt);
> -           rhs2 = gimple_assign_rhs2 (c->cand_stmt);
> -         }
> -         if (cand_code != NEGATE_EXPR
> -             && ((operand_equal_p (rhs1, basis_name, 0)
> -                  && operand_equal_p (rhs2, bump_tree, 0))
> -                 || (operand_equal_p (rhs1, bump_tree, 0)
> -                     && operand_equal_p (rhs2, basis_name, 0))))
> -           {
> -             if (dump_file && (dump_flags & TDF_DETAILS))
> -               {
> -                 fputs ("(duplicate, not actually replacing)", dump_file);
> -                 stmt_to_print = c->cand_stmt;
> -               }
> -           }
> -         else
> -           {
> -             gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
> -             slsr_cand_t cc = c;
> -             gimple_assign_set_rhs_with_ops (&gsi, code,
> -                                             basis_name, bump_tree);
> -             update_stmt (gsi_stmt (gsi));
> -              c->cand_stmt = gsi_stmt (gsi);
> -             while (cc->next_interp)
> -               {
> -                 cc = lookup_cand (cc->next_interp);
> -                 cc->cand_stmt = gsi_stmt (gsi);
> -               }
> -             if (dump_file && (dump_flags & TDF_DETAILS))
> -               stmt_to_print = gsi_stmt (gsi);
> -           }
> -       }
> +    }
>
> -      if (dump_file && (dump_flags & TDF_DETAILS))
> -       {
> -         fputs ("With: ", dump_file);
> -         print_gimple_stmt (dump_file, stmt_to_print, 0);
> -         fputs ("\n", dump_file);
> -       }
> +  if (dump_file && (dump_flags & TDF_DETAILS))
> +    {
> +      fputs ("With: ", dump_file);
> +      print_gimple_stmt (dump_file, stmt_to_print, 0);
> +      fputs ("\n", dump_file);
>      }
>  }
>
> Index: gcc/testsuite/gcc.c-torture/execute/pr81503.c
> ===================================================================
> --- gcc/testsuite/gcc.c-torture/execute/pr81503.c       (nonexistent)
> +++ gcc/testsuite/gcc.c-torture/execute/pr81503.c       (working copy)
> @@ -0,0 +1,15 @@
> +unsigned short a = 41461;
> +unsigned short b = 3419;
> +int c = 0;
> +
> +void foo() {
> +  if (a + b * ~(0 != 5))
> +    c = -~(b * ~(0 != 5)) + 2147483647;
> +}
> +
> +int main() {
> +  foo();
> +  if (c != 2147476810)
> +    return -1;
> +  return 0;
> +}
>

Reply via email to