This is an archive of the discontinued LLVM Phabricator instance.

[GlobalsAA] Loosen an overly conservative bailout
ClosedPublic

Authored by jmolloy on Oct 7 2015, 7:33 AM.

Details

Reviewers
chandlerc
hfinkel
Summary

When checking if a Value can alias a non-addr-taken global, if the Value is a LoadInst, then it cannot alias the global.

In order for the two to alias, the Value must be a pointer within the
global object. If that pointer has just been loaded from memory, it
cannot possibly alias the global as we know the global's address could
never have ended up in memory in the first place.

I've thrown all the testing I have at this, and it hasn't triggered any miscompares anywhere... but that's no evidence that there isn't a counterexample to my logic above.

Hal and Chandler - I've thought about this a *lot* and I think my logic is correct, but would you guys mind validating it? Thanks!

Diff Detail

Repository
rL LLVM

Event Timeline

jmolloy updated this revision to Diff 36740.Oct 7 2015, 7:33 AM
jmolloy retitled this revision from to [GlobalsAA] Loosen an overly conservative bailout.
jmolloy updated this object.
jmolloy added reviewers: chandlerc, hfinkel.
jmolloy set the repository for this revision to rL LLVM.
jmolloy added a subscriber: llvm-commits.
chandlerc edited edge metadata.Oct 12 2015, 11:16 AM

I don't understand your comment.

How does this not break in the face of reg2mem?

jmolloy updated this revision to Diff 37225.Oct 13 2015, 3:10 AM
jmolloy edited edge metadata.

Hi Chandler,

You're right, the previous patch was utter utter nonsense.

This updated patch covers all the cases I cared about and seems far more sound. Simply: instead of bailing out, recurse. If a captured value is found while following a chain of loads, all those loads are also captured.

This lets us hit the case I care about which is something like:

static int a;
static int **b;

alias? (a, b[1][2]);

Cheers,

James

My brain hurts from thinking about this. ;] Sorry for delays though. I *think* I've got my head wrapped around it.

lib/Analysis/GlobalsModRef.cpp
682

However we end up with this, please minimize the number of calls to GetUnderlyingObject. That is actually the expensive part, and its redundant with the above code.

684–687

So, pushing this onto the worklist isn't quite what we want. And whatever we want, we shouldn't have the one-off check above, because whatever we want should work for the immediate pointer operand as well as N-deep pointer operands.

The loop we want for loads is substantially simpler than the one we are currently inside of, because we don't need to handle overridable global variables, the original global variable, whether things are sized, etc etc.

Once we are looking through a load, we can simply check for globals, calls, invokes, and arguments; and recurse through phis, selects, and subsequent loads. However, this also means we can't re-use the visited set. I think we should have a dedicated helper for recursing on load pointer operands, and pass the depth parameter into it. This will remove the need for some of the shuffling here.

Also, as a minor point, the issue is not capture, but escape. Even if the escape does not outlive a particular function, it can break this. However, as is mentioned above, we are relying on it being unreasonable for a transformation to introduce an escape of a global variable. This includes a direct escape (which the existing code relies upon) and an indirect escape (which your new logic relies upon).

jmolloy updated this revision to Diff 38014.Oct 21 2015, 8:15 AM

Hi Chandler,

Thanks for getting around to this. I agree with everything you've said and have updated the patch.

Hopefully the comments should be correct this time - I did have trouble wording the comments correctly as it's easy to give the wrong impression (as you caught).

James

chandlerc added inline comments.Oct 21 2015, 10:33 AM
lib/Analysis/GlobalsModRef.cpp
613

GlobalValue is repeated here. I would keep a single if, and merge the two comments. Your comment above is excellent.

730

Add vertical space before here?

741

Just call the function? This is the first test it does.

747

No need for else after a continue.

chandlerc accepted this revision.Oct 22 2015, 3:17 AM
chandlerc edited edge metadata.

And as James pointed out, my last round of comment sare completely stylistic. LGTM with these changes.

This revision is now accepted and ready to land.Oct 22 2015, 3:17 AM
jmolloy closed this revision.Oct 26 2015, 3:29 AM