On Thu, Aug 3, 2017 at 9:34 PM, Bill Schmidt
<wschm...@linux.vnet.ibm.com> wrote:
> Hi,
>
> Here's v2 of the patch with Jakub's suggestions incorporated.  Bootstrapped
> and tested on powerpc64le-linux-gnu with no regressions.  Is this ok for
> trunk?
>
> Eventually this should be backported to all active releases as well.
> Ok for that after a week or so of burn-in? (And after 7.2, I imagine.)
>
> Thanks,
> Bill
>
>
> [gcc]
>
> 2017-08-03  Bill Schmidt  <wschm...@linux.vnet.ibm.com>
>             Jakub Jelinek  <ja...@redhat.com>
>
>         PR tree-optimization/81503
>         * gimple-ssa-strength-reduction.c (replace_mult_candidate): Ensure
>         folded constant fits in the target type.
>
> [gcc/testsuite]
>
> 2017-08-03  Bill Schmidt  <wschm...@linux.vnet.ibm.com>
>             Jakub Jelinek  <ja...@redhat.com>
>
>         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 250791)
> +++ gcc/gimple-ssa-strength-reduction.c (working copy)
> @@ -2074,6 +2074,10 @@ 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);
> +  unsigned int prec = TYPE_PRECISION (target_type);
> +  tree maxval = (POINTER_TYPE_P (target_type)
> +                ? TYPE_MAX_VALUE (sizetype)
> +                : TYPE_MAX_VALUE (target_type));
>
>    /* It is highly unlikely, but possible, that the resulting
>       bump doesn't fit in a HWI.  Abandon the replacement
> @@ -2082,6 +2086,17 @@ replace_mult_candidate (slsr_cand_t c, tree basis_
>       types but allows for safe negation without twisted logic.  */
>    if (wi::fits_shwi_p (bump)
>        && bump.to_shwi () != HOST_WIDE_INT_MIN
> +      /* It is more likely that the bump doesn't fit in the target
> +        type, so check whether constraining it to that type changes
> +        the value.  For a signed type, the value mustn't change.
> +        For an unsigned type, the value may only change to a
> +        congruent value (for negative bumps).  */
> +      && (TYPE_UNSIGNED (target_type)
> +         ? wi::eq_p (wi::neg_p (bump)
> +                     ? bump + wi::to_widest (maxval) + 1
> +                     : bump,
> +                     wi::zext (bump, prec))
> +         : wi::eq_p (bump, wi::sext (bump, prec)))

Not sure, but would it be fixed in a similar way when writing

@@ -2089,16 +2089,9 @@ replace_mult_candidate (slsr_cand_t c, t
   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
+  /* 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
@@ -2109,18 +2102,25 @@ replace_mult_candidate (slsr_cand_t c, t
       tree bump_tree;
       gimple *stmt_to_print = NULL;

-      /* 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))
        {
          code = MINUS_EXPR;
          bump = -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);

?

>        /* It is not useful to replace casts, copies, negates, or adds of
>          an SSA name and a constant.  */
>        && cand_code != SSA_NAME
> 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;
> +}
>
>
> On 8/3/17 1:02 PM, Bill Schmidt wrote:
>>> On Aug 3, 2017, at 11:39 AM, Jakub Jelinek <ja...@redhat.com> wrote:
>>>
>>> On Thu, Aug 03, 2017 at 11:29:44AM -0500, Bill Schmidt wrote:
>>>>> And, wouldn't it be more readable to use:
>>>>>     && (TYPE_UNSIGNED (target_type)
>>>>>      ? (wi::eq_p (bump, wi::zext (bump, prec))
>>>>>         || wi::eq_p (bump + wi::to_widest (maxval) + 1,
>>>>>                      wi::zext (bump, prec)))
>>>>>      : wi::eq_p (bump, wi::sext (bump, prec)))
>>>>> ?
>>>> Probably.  As noted, it's all becoming a bit unreadable with too
>>>> much negative logic in a long conditional, so I want to clean that
>>>> up in a follow-up.
>>>>
>>>>> For TYPE_UNSIGNED, do you actually need any restriction?
>>>>> What kind of bump values are wrong for unsigned types and why?
>>>> If the value of the bump is actually larger than the precision of the
>>>> type (not likely except for quite small types), say 2 * (maxval + 1)
>>>> which is congruent to 0, the replacement is wrong.
>>> Ah, ok.  Anyway, for unsigned type, perhaps it could be written as:
>>>      && (TYPE_UNSIGNED (target_type)
>>>        ? wi::eq_p (wi::neg_p (bump) ? bump + wi::to_widest (maxval) + 1
>>>                                     : bump, wi::zext (bump, prec))
>>>        : wi::eq_p (bump, wi::sext (bump, prec)))
>>> I mean, if bump >= 0, then the bump + wi::to_widest (maxval) + 1
>>> value has no chance to be equal to zero extended bump, and
>>> for bump < 0 only that one has a chance.
>> Yeah, that's true.  And arguably my case for the really large bump
>> causing problems is kind of thin, because the program is probably
>> already broken in that case anyway.  But I think I will sleep better
>> having the check in there, as somebody other than SLSR will catch
>> the bug then. ;-)
>>
>> Thanks for all the help with this one.  These corner cases are
>> always tricky, and I appreciate the extra eyeballs.
>>
>> Bill
>>
>>>      Jakub
>>>
>

Reply via email to