[PATCH] D41761: Introduce llvm.nospeculateload intrinsic

Kristof Beyls via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 3 12:00:58 PST 2018


kristof.beyls added a comment.

In https://reviews.llvm.org/D41761#996858, @chandlerc wrote:

> > 2. Is the API available in C too?
> > 
> >   IIUC, the SecureBoundOffset intrinsic is usable from both C and C++, but the IsPointerInRange intrinsic can only be used from C++? Do you have ideas around bringing similar functionality to C?
>
> Yeah, this is part of why I suggest the much more generic `ProtectFromSpeculation` API which I think is easily applicable in C. The C version might use pointers or whatever, but this kind of API doesn't fundamentally require any interesting lang
>
> > 
> > 
> > 3. For the variant with a general predicate (`bool ProtectFromSpeculation(bool predicate, ZeroArgs&... args);`); do you have ideas about how to make sure that the optimizers in the compiler don’t simplify the predicate too much? For example:
> > 
> >   ``` if (a>7) { x = a; if (ProtectFromSpeculation(a>5, x) { ... = v[x]; ... } }
> > 
> >   ``` how to prevent this from being optimized to: ``` if (a>7) { x = a; if (ProtectFromSpeculation(true, x) { ... = v[x]; ... } } ``` which leads to no longer giving protection.
>
> No matter what, this will require deep compiler support to implement. Even without the example you give, these construct fundamentally violate the rules the optimizer uses: they are by definition no-ops for execution of the program!
>
> This means we will have to work to build up specific an dedicated infrastructure in the compiler to model these as having special semantics. That exact infrastructure can provide whatever optimization barriers are necessary to get the desired behavior. For example, the code generation I suggest above for x86 cannot be implemented in LLVM using its IR alone (I've actually tried). We'll have to model this both in the IR and even in the code generator specially in order to produce the kind of specific pattern that is necessary.
>
> But there is also the question of what burden do we want to place on the user of these intrinsics vs. what performance hit we're willing to accept due to optimization barriers. I could imagine two approaches here:
>
> 1. It is the programmers responsibility to correctly protect any predicates that their application is sensitive to. As a consequence, if the `a>5` predicate is sensitive for the application, so must the `a>7` predicate be, and it is the programmers responsibility to protect both of them. This allows the implementation to have the minimal set of optimization barriers, but may make it difficult for programmers to use correctly.
> 2. The predicate provided to these APIs is truly special and is forced to be a *dynamic* predicate. That is, we require the compiler to emit the predicate as if no preconditions existed. There are ways to model this in LLVM and I assume any compiler. As a trivial (but obviously bad) example: all references to variables within the predicate could be lowered by rinsing that SSA value through an opaque construct like inline asm.
>
>   There is clearly a "programmer ease / security" vs. "better optimization" tradeoff between the two. If one isn't *clearly* the correct choice in all cases, we could even expose both behind separate APIs that try to make it clear the extent of protections provided.
>
>   Does that make sense?


Thanks for sharing your thoughts, Chandler.
Yes, this does make a lot of sense to me. I was thinking roughly along the same lines - apart from maybe fixating more on a single solution. Your above thoughts for potentially 2 related solutions - or at least experimenting with the 2 related solutions - make a lot of sense to me.
I would expect that only providing option (1) may not be ideal - as it may be hard in some cases to protect all flows, e.g. when also all possible cross-translation unit, inter-procedural flows need to be considered.
Instinctively, I would expect that (2) might be more appealing to many programmers - if the performance overhead of it wouldn't be too high. I also expect that at least a pretty dumb way to force the predicate to be dynamic to not be too hard to implement in a front-end. Although I say that with hardly ever having written any front-end code in practice - it just seems at least conceptually not overly hard. I hope to find some time in the near future to experiment with this. In the mean time, if you, or anyone else, has any further insights to share: I'm all ears!

Thanks!


https://reviews.llvm.org/D41761





More information about the llvm-commits mailing list