This achieves two things:
- The GLSL backend no longer needs to handle this by itself. Likwise, the
MSL backend won't have to either.
- We no longer handle division by zero for DXIL UDiv and URem instructions,
which leave this undefined.
The following unary identities are applied:
||x|| -> |x|
|-x| -> |x|
~(~x) -> x
f(g(x)) -> g(x), where f(), g() are floor() or ceil() functions.
-(-x) -> x
!!x -> x
!(x == y) -> x != y, !(x < y) -> x >= y, etc (for integers).
We apply distributivity to applicable expressions, specifically with
the following rewrite rules:
(x OPL a) OPR (x OPL b) -> x OPL (a OPR b)
(y OPR (x OPL a)) OPR (x OPL b) -> y OPR (x OPL (a OPR b))
((x OPL a) OPR y) OPR (x OPL b) -> (x OPL (a OPR b)) OPR y
(x OPL a) OPR ((x OPL b) OPR y) -> (x OPL (a OPR b)) OPR y
(x OPL a) OPR (y OPR (x OPL b)) -> (x OPL (a OPR b)) OPR y
where a, b are constants.
We normalize binary expressions by attempting to group constants
together, in order to facilitate further simplification of the
expressions.
For any binary operator OP, non-constants x, y, and constants a, b, we
apply the following rewrite rules:
a OP x -> x OP a, if OP is commutative.
(x OP a) OP b -> x OP (a OP b), if OP is associative.
(x OP a) OP y -> (x OP y) OP a, if OP is associative and commutative.
x OP (y OP a) -> (x OP y) OP a, if OP is associative.
Note that we consider floating point operations to be
non-associative.
This is simply unnecessary and wastes time.
As part of this, simply remove the "all" directive. Only for a couple of tests
is it even potentially interesting to validate all pixels (e.g.
nointerpolation.shader_test), and for those "all" is replaced with an explicit
(0, 0, 640, 480) rect.
In all other cases we just probe (0, 0).