I don't think it's possible to do the same optimization for the inverse macro NOT_TERNARY because you would either need to swap x and y in the formula, adding an additional swap operation, or use iszero. Since that macro is already 3 gas less than the TERNARY macro, adding another operation to the branchless version makes it equivalent for one case and more expensive for the other.
For reference, there are two formulae you can use:
// condition ? x : y
(x - y) * condition + y
// Required Stack: [x, y, condition, y]
// sub mul add
((x ^ y) * condition) ^ y
// Required Stack: [x, y, condition, y] OR [y, x, condition, y]
// xor mul xor
And for the inverse
// condition ? y : x
(y - x) * condition + x
// Required Stack: [y, x, condition, x]
// sub mul add
((x ^ y) * condition) ^ x
// Required Stack: [x, y, condition, x] OR [y, x, condition, x]
// xor mul xor
Old
TERNARY
macro:When the condition is true, the operations are:
iszero push jumpi swap jumpdest pop
= 23 gas When it's false:iszero push jumpi jumpdest pop
= 20 gasIf we use branchless logic we can get this down to 17 for both cases:
swap1 dup3 xor mul xor
= 17 gasI don't think it's possible to do the same optimization for the inverse macro
NOT_TERNARY
because you would either need to swap x and y in the formula, adding an additional swap operation, or use iszero. Since that macro is already 3 gas less than theTERNARY
macro, adding another operation to the branchless version makes it equivalent for one case and more expensive for the other.For reference, there are two formulae you can use:
And for the inverse