[llvm-commits] [pr12979][patch/rfc] Clear nsw/nuw in gvn

Nuno Lopes nunoplopes at sapo.pt
Fri Jun 1 20:02:55 PDT 2012


>>> %a = load i32* %p, !range !1
>>> %b = load i32* %p, !range !2
>>>
>>> I think the resulting range should be the *intersection*, and not the
>>> union of the ranges.  Someone says: "I'm sure this value is between 0
>>> and 5", and someone else says "I'm sure that value is between 3 and
>>> 6".  Then we know that the value must be between 3 and 5;  we don't
>>> need to expand our beliefs to be between 0 and 6.
>>> (of course this reasoning assumes that ranges are always conservative,
>>> which must be the case, anyway)
>>>
>> This is right.
>
> I think it should be the union. The logic is similar to what is being
> applied to tbaa. Consider someone implementing tagged types with an
> union in C++:
>
> struct foo {
>   char tag;
>   union {
>     bool a;
>     enum zed b;
>   };
> };
>
> now consider code accessing a variable x of type foo*:
>
> if (x->tag == 42) {
>   do something with x->a;
> } else {
>   do something with x->b;
> }
>
> we have one load in each side of the branch. Each will have a range
> matching the union field. If we were to create a single load above the
> if, it could see a bool or an enum, so the range must be the union.

ah, ok, you convinced me :)  Let it be the union then!
I'll review your patch again for the range union (since I skipped that part 
before). I'll ping you if I've any comment.

BTW, I'm wondering if we shouldn't have a ConstantRangeUnion class or 
something similar, that would perform operations on disjunction of 
intervals. And some utility functions to extract ConstantRanges and 
ConstantRangeUnions out of range metadata.  I'm sure a few optimization 
passes could benefit from this infrastructure. Including your pass.

Nuno 




More information about the llvm-commits mailing list