[PATCH] Clarify wording in the LangRef around !invariant.load
Sanjoy Das
sanjoy at playingwithpointers.com
Thu Nov 20 17:33:29 PST 2014
Something I think needs clarification is whether !invariant.load is a
dynamic property or a static property. In other words, is the pointer
being loaded from specified to be constant only once an
!invariant.load has executed, or is it constant by the virtue of there
*existing* an invariant.load?
If the pointer being loaded from is specified being constant only once
an !invariant.load has executed, it means !invariant.loads cannot be
hoisted above control dependencies in general:
transforming
```
int *x = < known dereferenceable >
if (t) {
m = load(x) !invariant.load
}
*x = 42
```
to
```
int *x = < known dereferenceable >
m = load(x) !invariant.load
if (t) {
}
*x = 42
```
makes a well-defined program undefined when t is false. Hoisting invariant loads through control dependencies can introduce UB.
If the pointer being loaded from is specified being constant if there
*exists* a use of the pointer in an !invariant.load, then:
transforming
```
int *x = < known dereferenceable >
*x = 42
```
to
```
int *x = < known dereferenceable >
if (false) {
m = load(x) !invariant.load
}
*x = 42
```
introduces UB. This is counter-intuitive -- introducing a load that
will *never be executed* makes the program undefined.
Personally, I think the `load` is incorrect place to annotate
invariance -- invariance should be just like `dereferenceable`, an
attribute on a *pointer* + offset range.
http://reviews.llvm.org/D6346
More information about the llvm-commits
mailing list