[PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989]

Andrew Pinski pinskia@gmail.com
Tue Sep 5 22:07:15 GMT 2023


On Tue, Sep 5, 2023 at 2:51 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Tue, Sep 05, 2023 at 02:27:10PM -0700, Andrew Pinski wrote:
> > > I admit it isn't really clear to me what do you want to achieve by the
> > > above build_nonstandard_integer_type.  Is it because of BOOLEAN_TYPE
> > > or perhaps ENUMERAL_TYPE as well?
> >
> > Yes I was worried about types where the precision was set but MIN/MAX
> > of that type was not over the full precision and would not include
> > both 0 and allones in that range.
> > There is another match.pd pattern where we do a similar thing with
> > calling build_nonstandard_integer_type for a similar reason but
> > because we don't know if the type includes 0, 1, and allones in their
> > range.
>
> Ah, in that case you should use range_check_type, that is used already
> in multiple spots in match.pd for the same purpose.  It can return NULL and
> in that case one should punt on the optimization.  Otherwise, that is the
> function which ensures that the type is unsigned and max + 1 is min and min
> - 1 is max.
> And for me, I should add BITINT_TYPE handling to that function.

Hmm maybe range_check_type is the correct one here.


>
> > > If type is INTEGER_TYPE or BITINT_TYPE, one doesn't really need to create a
> > > new type, type already is an integral type with that precision and
> > > signedness.  In other places using unsigned_type_for or signed_type_for
> > > might be better than using build_nonstandard_integer_type if that is what
> > > one wants to achieve, those functions handle BITINT_TYPE.
> >
> > Maybe here we should just use `signed_or_unsigned_type_for (type,
> > TYPE_SIGN (type));`
> > instead of build_nonstandard_integer_type.
>
> No, signed_or_unsigned_type_for (TYPE_UNSIGNED (type), type) will just return
> type.
>   if (ANY_INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) == unsignedp)
>     return type;

Oh I missed that.

Note I notice another all to build_nonstandard_integer_type in this
match pattern which might also need to be fixed:
/* For (x << c) >> c, optimize into x & ((unsigned)-1 >> c) for
   unsigned x OR truncate into the precision(type) - c lowest bits
   of signed x (if they have mode precision or a precision of 1).  */
(simplify
 (rshift (nop_convert? (lshift @0 INTEGER_CST@1)) @@1)
 (if (wi::ltu_p (wi::to_wide (@1), element_precision (type)))
  (if (TYPE_UNSIGNED (type))
   (bit_and (convert @0) (rshift { build_minus_one_cst (type); } @1))
   (if (INTEGRAL_TYPE_P (type))
    (with {
      int width = element_precision (type) - tree_to_uhwi (@1);
      tree stype = build_nonstandard_integer_type (width, 0);
     }
     (if (width == 1 || type_has_mode_precision_p (stype))
      (convert (convert:stype @0))))))))

Do we have ranges on BITINT_TYPEs? If so the two_value_replacement
pattern in match.pd has a similar issue too.
(that is where I copied the code to use build_nonstandard_integer_type
from originally too.

Thanks,
Andrew


>
>         Jakub
>


More information about the Gcc-patches mailing list