[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