[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