Browse Source
* cranelift: Optimize select_spectre_guard, carefully This commit makes two changes to our treatment of `select_spectre_guard`. First, stop annotating this instruction as having any side effects. We only care that if its value result is used, then it's computed without branching on the condition input. We don't otherwise care when the value is computed, or if it's computed at all. Second, introduce some carefully selected ISLE egraph rewrites for this instruction. These particular rewrites are those where we can statically determine which SSA value will be the result of the instruction. Since there is no actual choice involved, there's no way to accidentally introduce speculation on the condition input. * Add filetestspull/8202/head
Jamey Sharp
8 months ago
committed by
GitHub
5 changed files with 91 additions and 49 deletions
@ -0,0 +1,14 @@ |
|||
;; Rewrites for `select_spectre_guard`. Check these rules carefully! This |
|||
;; instruction prohibits all speculation on the controlling value when |
|||
;; determining which input to use as the result. Rewrites must respect that |
|||
;; requirement. |
|||
|
|||
;; If we statically know which value will be the result, it's safe to just use |
|||
;; that value. No speculation on the controlling value is possible if we simply |
|||
;; don't depend on that value at all. |
|||
(rule (simplify (select_spectre_guard _ _ x x)) |
|||
(subsume x)) |
|||
(rule (simplify (select_spectre_guard _ (iconst_u _ (u64_nonzero _)) x _)) |
|||
(subsume x)) |
|||
(rule (simplify (select_spectre_guard _ (iconst_u _ 0) _ y)) |
|||
(subsume y)) |
@ -0,0 +1,26 @@ |
|||
test optimize |
|||
set opt_level=speed |
|||
target x86_64 |
|||
|
|||
function %same_value(i8, i64) -> i64 { |
|||
block0(v0: i8, v1: i64): |
|||
v2 = select_spectre_guard v0, v1, v1 |
|||
return v2 |
|||
} |
|||
; check: return v1 |
|||
|
|||
function %const_true(i64, i64) -> i64 { |
|||
block0(v0: i64, v1: i64): |
|||
v2 = iconst.i8 42 |
|||
v3 = select_spectre_guard v2, v0, v1 |
|||
return v3 |
|||
} |
|||
; check: return v0 |
|||
|
|||
function %const_false(i64, i64) -> i64 { |
|||
block0(v0: i64, v1: i64): |
|||
v2 = iconst.i8 0 |
|||
v3 = select_spectre_guard v2, v0, v1 |
|||
return v3 |
|||
} |
|||
; check: return v1 |
Loading…
Reference in new issue