[PATCH] Clarify wording in the LangRef around !invariant.load
Andrew Trick
atrick at apple.com
Mon Nov 24 13:00:20 PST 2014
> On Nov 24, 2014, at 12:34 AM, Sanjoy Das <sanjoy at playingwithpointers.com> wrote:
>
>> I would actually be fine with more conservative semantics - the load is only invariant with respect to its original uses - because it won't affect optimization in practice.
>
> I was under the impression that one of motivations for invariant loads
> was to be able to hoist them out of arbitrary control flow.
>
> Thanks,
> -- Sanjoy
I think hoisting invariant loads is typically a goal, but "dereferenceable" doesn't have to be implied by "invariant". I now agree with Philip's clarification of the semantics:
"Being invariant does not imply that a location is dereferenceable, but it does imply that once the location is known dereferenceable it's value is henceforth unchanging."
Given:
int *p = <known dereferenceable>
store(q)
if (something)
m1 = load(p) !invariant
foo(m1)
else
m2 = load(p)
bar(m2)
This is definitely valid:
int *p = <known dereferenceable>
m1 = load(p) !invariant
store(q)
m2 = load(p)
if (something)
foo(m1)
else
bar(m2)
But is this valid?
int *p = <known dereferenceable>
m = load(p) !invariant
store(q)
if (something)
foo(m)
else
bar(m)
I would like to claim that it is valid, because that would make the original code interchangeable with:
int *p = <known dereferenceable>
assume_invariant(p)
store(q)
if (something)
m1 = load(p)
foo(m1)
else
m2 = load(p)
bar(m2)
If it is not valid to infer invariance of the memory at ‘p', then the assume_invariant limits optimization vs. the invariant.load metadata. You would be forced to do this, which I think would prevent reordering store(q) and m1 = load(p):
int *p = <known dereferenceable>
store(q)
if (something)
assume_invariant(p)
m1 = load(p)
foo(m1)
else
m2 = load(p)
bar(m2)
-Andy
More information about the llvm-commits
mailing list