This is part of implementing a technique to mitigate against Spectre v1,
similar in spirit to what has been proposed by Chandler for X86_64 at
http://lists.llvm.org/pipermail/llvm-dev/2018-March/122085.html.
This patch adds a new llvm intrinsic:
T @llvm.speculation_safe_value(T %val)
where T can be any integer or any pointer type.
- This intrinsic returns either value %val or 0. When this intrinsic is executed on a miss-speculated path, where the miss-speculation is caused by at least one miss-predicted direct conditional branch, the intrinsic guarantees that value 0 is returned.
- This intrinsic is close to what Philip Reames suggested as an alternative on https://reviews.llvm.org/D41761.
- This could be extended to become T @llvm.speculation_safe_value(T %val, T %miss_spec_val) where the intrinsics returns %miss_spec_val instead of 0 when executed on miss-speculated path. However, that is currently not implemented in this patch.
The introduction of this intrinsic has multiple advantages in helping to
mitigate against Spectre v1 attacks:
- It enables users to only mark the specific values they need to be protected under miss-speculation - if they know which values/program locations need protection.
- For automatic protection of all values loaded: this enables relatively easy experimentation with different heuristics of where the intrinsic/protection should get inserted. One such example heuristic is implemented in a follow-on patch. In other words, even when only focussing on a fully automated approach, separating the decisions on where to insert protection vs doing the necessary transforms/lowering on where protection is needed makes the code slightly easier to understand, review and maintain.
The intrinsic (as implemented in this patch) assumes control flow
miss-speculation tracking has been enabled (see previous patch).
A follow-on patch will make this intrinsic also work without needing
the miss-speculation tracking.