[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