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

Rafael Espíndola rafael.espindola at gmail.com
Fri Jun 1 18:33:58 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.

About TBAA, in the end Nuno analysis in the second email (using the
lowest common ancestor)  is correct, no? Some interesting cases

* Two loads from different languages: They cannot alias, so there is
no ancestor and we will simply drop the tbaa.
* 2 and 3 in the tree
     / \
   1   4
  / \
2   3

should produce 1. Anything that would alias 2 or 3 will alias 1 and
that is the node that alias the least. Returning 0 for example would
unnecessarily alias 4.


More information about the llvm-commits mailing list