On Thu, Aug 1, 2019 at 10:27 AM Eric Botcazou <ebotca...@adacore.com> wrote:
>
> Hi,
>
> this fixes the cd2a31a regression in the ACATS testsuite on 32-bit targets
> introduced by the recent change to get_array_ctor_element_at_index:
>
>         * fold-const.h (get_array_ctor_element_at_index): Adjust.
>         * fold-const.c (get_array_ctor_element_at_index): Add
>         ctor_idx output parameter informing the caller where in
>         the constructor the element was (not) found.  Add early exit
>         for when the ctor is sorted.
>
> This change overlooks that the index can wrap around during the traversal of
> the CONSTRUCTOR and therefore causes the function to return bogus values as
> soon as this happens.  Moreover, given this chunk of added code:

So isn't this an issue with the code before when we have a RANGE_EXPR
that covers the wrapping point?  Then index > max_index and may not
catch the found element with

    /* Do we have match?  */
    if (wi::cmpu (access_index, index) >= 0
        && wi::cmpu (access_index, max_index) <= 0)
      return cval;

?  We seem to be careful to convert the indices to the index type but
above use unsigned compares - isn't that the underlying issue?  So
isn't

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 273968)
+++ gcc/fold-const.c    (working copy)
@@ -11864,9 +11864,13 @@ get_array_ctor_element_at_index (tree ct
        }
     }

+  signop index_sgn = UNSIGNED;
   if (index_type)
-    access_index = wi::ext (access_index, TYPE_PRECISION (index_type),
-                           TYPE_SIGN (index_type));
+    {
+      index_sgn = TYPE_SIGN (index_type);
+      access_index = wi::ext (access_index, TYPE_PRECISION (index_type),
+                             TYPE_SIGN (index_type));
+    }

   offset_int index = low_bound - 1;
   if (index_type)
@@ -11903,9 +11907,9 @@ get_array_ctor_element_at_index (tree ct
        }

       /* Do we have match?  */
-      if (wi::cmpu (access_index, index) >= 0)
+      if (wi::cmp (access_index, index, index_sgn) >= 0)
        {
-         if (wi::cmpu (access_index, max_index) <= 0)
+         if (wi::cmp (access_index, max_index, index_sgn) <= 0)
            {
              if (ctor_idx)
                *ctor_idx = cnt;


>       else if (in_gimple_form)
>         /* We're past the element we search for.  Note during parsing
>            the elements might not be sorted.
>            ???  We should use a binary search and a flag on the
>            CONSTRUCTOR as to whether elements are sorted in declaration
>            order.  */
>         break;
>
> I would respectfully suggest that the author thinks about redoing things from
> scratch here.  In the meantime, the attached patch kludges around the issue.

I'm not sure how "doing from scratch" would fix things - we simply rely
on reliably detecting an element match.

I wonder how much we can rely on the array domain type to be in sync
with the constructor field entries.

Also we're using offset_int here - doesn't that break when with
Ada we have an array type with domain [uint128_t_max - 1, uint128_t_max + 2]
in a type larger than int128_t?  Or, since we're interpreting it
inconsistently signed/unsigned, a 128bit integer typed domain wraps
around the sign?

If that's not an issue then using signed compare unconditionally is
a valid fix as well I guess.

But in reality 'index' should never really wrap, that is, if the domain
is of 'int' type and starts with INT_MAX then the array shall not have
more than 1 element.  No?

The patch you posted isn't a real fix btw, since iff the break was
hit we either missed an index that is present or we found a gap
but then we can break.

So I'd appreciate more explanation on how the index "wraps".

Richard.

> Tested on x86_64-suse-linux, OK for the mainline?
>
>
> 2019-08-01  Eric Botcazou  <ebotca...@adacore.com>
>
>         PR tree-optimization/91169
>         * fold-const.c (get_array_ctor_element_at_index): Remove early exit 
> and
>         do not return a bogus ctor_idx when the index wraps around.
>
> --
> Eric Botcazou

Reply via email to