On Tue, Sep 5, 2023 at 2:51 PM Jakub Jelinek <ja...@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 >