[000/nnn] poly_int: representation of runtime offsets and sizes

Richard Biener richard.guenther@gmail.com
Wed Nov 8 11:57:00 GMT 2017


On Wed, Nov 8, 2017 at 10:39 AM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> Richard Biener <richard.guenther@gmail.com> writes:
>> On Wed, Oct 25, 2017 at 1:26 PM, Richard Sandiford
>> <richard.sandiford@linaro.org> wrote:
>>> Richard Biener <richard.guenther@gmail.com> writes:
>>>> On Tue, Oct 24, 2017 at 3:24 PM, Richard Sandiford
>>>> <richard.sandiford@linaro.org> wrote:
>>>>> Richard Biener <richard.guenther@gmail.com> writes:
>>>>>> On Tue, Oct 24, 2017 at 2:48 PM, Richard Sandiford
>>>>>> <richard.sandiford@linaro.org> wrote:
>>>>>>> Richard Biener <richard.guenther@gmail.com> writes:
>>>>>>>> On Tue, Oct 24, 2017 at 1:23 PM, Richard Sandiford
>>>>>>>> <richard.sandiford@linaro.org> wrote:
>>>>>>>>> Eric Botcazou <ebotcazou@adacore.com> writes:
>>>>>>>>>>> Yeah.  E.g. for ==, the two options would be:
>>>>>>>>>>>
>>>>>>>>>>> a) must_eq (a, b)   -> a == b
>>>>>>>>>>>    must_ne (a, b)   -> a != b
>>>>>>>>>>>
>>>>>>>>>>>    which has the weird property that (a == b) != (!(a != b))
>>>>>>>>>>>
>>>>>>>>>>> b) must_eq (a, b)   -> a == b
>>>>>>>>>>>    may_ne (a, b)    -> a != b
>>>>>>>>>>>
>>>>>>>>>>>    which has the weird property that a can be equal to b when a != b
>>>>>>>>>>
>>>>>>>>>> Yes, a) was the one I had in mind, i.e. the traditional operators are
>>>>>>>>>> the must
>>>>>>>>>> variants and you use an outer ! in order to express the may.  Of
>>>>>>>>>> course this
>>>>>>>>>> would require a bit of discipline but, on the other hand, if most of
>>>>>>>>>> the cases
>>>>>>>>>> fall in the must category, that could be less ugly.
>>>>>>>>>
>>>>>>>>> I just think that discipline is going to be hard to maintain in
>>>>>>>>> practice,
>>>>>>>>> since it's so natural to assume (a == b || a != b) == true.  With the
>>>>>>>>> may/must approach, static type checking forces the issue.
>>>>>>>>>
>>>>>>>>>>> Sorry about that.  It's the best I could come up with without losing
>>>>>>>>>>> the may/must distinction.
>>>>>>>>>>
>>>>>>>>>> Which variant is known_zero though?  Must or may?
>>>>>>>>>
>>>>>>>>> must.  maybe_nonzero is the may version.
>>>>>>>>
>>>>>>>> Can you rename known_zero to must_be_zero then?
>>>>>>>
>>>>>>> That'd be OK with me.
>>>>>>>
>>>>>>> Another alternative I wondered about was must_eq_0 / may_ne_0.
>>>>>>>
>>>>>>>> What's wrong with must_eq (X, 0) / may_eq (X, 0) btw?
>>>>>>>
>>>>>>> must_eq (X, 0) generated a warning if X is unsigned, so sometimes you'd
>>>>>>> need must_eq (X, 0) and sometimes must_eq (X, 0U).
>>>>>>
>>>>>> Is that because they are templates?  Maybe providing a partial
>>>>>> specialization
>>>>>> would help?
>>>>>
>>>>> I don't think it's templates specifically.  We end up with something like:
>>>>>
>>>>>   int f (unsigned int x, const int y)
>>>>>   {
>>>>>     return x != y;
>>>>>   }
>>>>>
>>>>>   int g (unsigned int x) { return f (x, 0); }
>>>>>
>>>>> which generates a warning too.
>>>>>
>>>>>> I'd be fine with must_eq_p and may_eq_0.
>>>>>
>>>>> OK, I'll switch to that if there are no objections.
>>>>
>>>> Hum.  But then we still warn for must_eq_p (x, 1), no?
>>>
>>> Yeah.  The patch also had a known_one and known_all_ones for
>>> those two (fairly) common cases.  For other values the patches
>>> just add "U" where necessary.
>>>
>>> If you think it would be better to use U consistently and not
>>> have the helpers, then I'm happy to do that instead.
>>>
>>>> So why does
>>>>
>>>>   int f (unsigned int x)
>>>>   {
>>>>      return x != 0;
>>>>   }
>>>>
>>>> not warn?  Probably because of promotion of the arg.
>>>
>>> [Jakub's already answered this part.]
>>>
>>>> Shouldn't we then simply never have a may/must_*_p (T1, T2)
>>>> with T1 and T2 being not compatible?  That is, force promotion
>>>> rules on them with template magic?
>>>
>>> This was what I meant by:
>>>
>>>   Or we could suppress warnings by forcibly converting the input.
>>>   Sometimes the warnings are useful though.
>>>
>>> We already do this kind of conversion for arithmetic, to ensure
>>> that poly_uint16 + poly_uint16 -> poly_int64 promotes before the
>>> addition rather than after it.  But it defeats the point of the
>>> comparison warning, which is that you're potentially redefining
>>> the sign bit.
>>>
>>> I think the warning's just as valuable for may/must comparison of
>>> non-literals as it is for normal comparison operators.  It's just
>>> unfortunate that we no longer get the special handling of literals.
>>
>> Ok, I see.
>>
>> I think I have a slight preference for using 0U consistently but I haven't
>> looked at too many patches yet to see how common/ugly that would be.
>
> OK.  FWIW, that's also how we had it until very recently.  I added the
> known/maybe stuff in a late and probably misguided attempt to make
> things prettier.
>
> I've pulled that part out and switched back to using U.  I'll post the
> new 001 patch in a sec.  Should I repost all the other patches that
> changed as well, or isn't it worth it for a change like that?

Not worth re-posting IMHO.

Richard.

> Thanks,
> Richard



More information about the Gcc-patches mailing list