[LLVMdev] Modeling volatile register read as intrinsic
Philip Reames
listmail at philipreames.com
Fri Feb 14 10:29:55 PST 2014
On 02/12/2014 05:48 AM, Justin Holewinski wrote:
> = Background =
>
> We are trying to introduce a target-dependent intrinsic that compiles
> to a read of a volatile register. In this case, the register holds a
> perf counter value, but in general the register can hold any volatile
> value. The problem we have is that it seems this cannot be modeled in
> LLVM currently.
>
>
> = Issue =
>
> The issue we are having is deciding how to represent the intrinsic in
> LLVM IR; specifically, the intrinsic properties. We cannot use
> IntrNoMem since that does not model a volatile read of a value. For
> example, if we have two calls to the intrinsic in a function, the
> optimizers will eliminate one of the reads and replace it with the
> value from the other read.
>
> %i1 = tail call i32 @llvm.foo()
> %i2 = tail call i32 @llvm.foo()
> %i3 = add i32 %i1, %i2
>
> becomes
>
> %i1 = tail call i32 @llvm.foo()
> %i2 = add i32 %i1, %i2
>
> Since the read should be volatile, this is not what we want. On the
> other hand, we do not want to use an empty set of properties since
> this is too conservative and prevents valid optimizations. For
> example, if we do not use any Intr* properties, the optimizers cannot
> prove that the intrinsic does not modify memory.
>
> store i32 42, i32* %ptr
> %i1 = tail call i32 @llvm.foo()
> %i2 = load i32* %ptr
> ...
> ret i32 %i2
>
> should be optimized to
>
> store i32 42, i32* %ptr
> %i1 = tail call i32 @llvm.foo()
> ...
> ret i32 42
>
> but this does not happen since the optimizers cannot prove that the
> intrinsic did not modify the value in memory at %ptr.
>
> The IntrReadMem property gets us a bit closer, but still does not
> model the volatile property correctly. The optimizers correctly see
> the operation as read-only and can optimize other memory accesses
> between intrinsic calls accordingly, but they also assume that the
> intrinsic reads the same memory and its return value will not change
> if a store is not seen between calls to the intrinsic. This is the
> definition of 'readonly' in LLVM IR, which is not quite what we want.
> We still have the same issue as using IntrNoMem in this regard:
>
> %i1 = tail call i32 @llvm.foo()
> %i2 = tail call i32 @llvm.foo()
> %i3 = add i32 %i1, %i2
>
> becomes
>
> %i1 = tail call i32 @llvm.foo()
> %i2 = add i32 %i1, %i2
>
> unless there is a store instruction between the calls. For
> correctness, we are better off using no properties (over-conservative).
I have to say this example surprised me. This is not what I would
expect a read-only annotation to enable.
> Am I missing something here that could represent this kind of
> intrinsic? It seems like we need a new function attribute
> readonly_volatile.
I would prefer to see the current IntrReadMem modified to allow volatile
reads. Then a new IntrReadMemNonVolatile could be added to describe the
current semantics in a less surprising way.
Philip
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140214/2526a5bf/attachment.html>
More information about the llvm-dev
mailing list