On August 31, 2019 7:41:17 PM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote: >On Sat, Aug 31, 2019 at 07:23:35PM +0200, Richard Biener wrote: >> Hmm, couldn't we make range_check_type_for take an argument whether >signed >> or unsigned type is required? That is, what do we do if the caller >wants >> a signed type? Leaving it unspecified what the function returns is >odd. > >I think we never want specially signed type, either we don't care >whether it >is signed or not, in that case we want just some type that wraps >around, or we >do want an unsigned type.
So why not always return an unsigned type then by telling type_for_size? > >So something like below, with using range_check_type (x, true) in some >places. > >Note it will be more compile time expensive than just calling >unsigned_type_for after the range_check_type call, due to all the >wrap-around verification it does. > >--- gcc/fold-const.h.jj 2019-08-08 08:34:28.010306157 +0200 >+++ gcc/fold-const.h 2019-08-31 19:39:13.436366420 +0200 >@@ -182,7 +182,7 @@ extern bool tree_expr_nonnegative_warnv_ > extern tree make_range (tree, int *, tree *, tree *, bool *); >extern tree make_range_step (location_t, enum tree_code, tree, tree, >tree, > tree *, tree *, int *, bool *); >-extern tree range_check_type (tree); >+extern tree range_check_type (tree, bool = false); >extern tree build_range_check (location_t, tree, tree, int, tree, >tree); > extern bool merge_ranges (int *, tree *, tree *, int, tree, tree, int, > tree, tree); >--- gcc/fold-const.c.jj 2019-08-27 12:26:39.303884758 +0200 >+++ gcc/fold-const.c 2019-08-31 19:39:06.235470312 +0200 >@@ -4930,10 +4930,12 @@ maskable_range_p (const_tree low, const_ > } > > >/* Helper routine for build_range_check and match.pd. Return the type >to >- perform the check or NULL if it shouldn't be optimized. */ >+ perform the check or NULL if it shouldn't be optimized. >+ If UNSIGNEDP is true, the returned type must be unsigned, otherwise >+ it can be some INTEGER_TYPE that wraps around. */ > > tree >-range_check_type (tree etype) >+range_check_type (tree etype, bool unsignedp) > { >/* First make sure that arithmetics in this type is valid, then make >sure > that it wraps around. */ >@@ -4941,7 +4943,8 @@ range_check_type (tree etype) > etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), > TYPE_UNSIGNED (etype)); > >- if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_OVERFLOW_WRAPS >(etype)) >+ if (unsignedp >+ || (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_OVERFLOW_WRAPS >(etype))) > { > tree utype, minv, maxv; > > > > Jakub