vkd3d-shader/hlsl: Fold basic idempotencies.
While not strictly necessary, this pass allows to remove some unnecessary instructions.
For instance:
float4 a;
float4 main() : sv_target
{
float4 zero = {0, 0, 0, 0};
float4 one = {1, 1, 1, 1};
return a + zero + a * one + zero * one;
}
Compiles to:
ps_4_0
dcl_constantbuffer cb0[1], immediateIndexed
dcl_output o0.xyzw
dcl_temps 1
mov r0.xyzw, cb0[0].xyzw
add r0.xyzw, r0.xyzw, r0.xyzw
mov o0.xyzw, r0.xyzw
ret
Instead of
ps_4_0
dcl_constantbuffer cb0[1], immediateIndexed
dcl_output o0.xyzw
dcl_temps 2
mov r0.xyzw, cb0[0].xyzw
add r1.xyzw, r0.xyzw, l(0.000000, 0.000000, 0.000000, 0.000000)
mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
add r0.xyzw, r1.xyzw, r0.xyzw
add r0.xyzw, r0.xyzw, l(0.000000, 0.000000, 0.000000, 0.000000)
mov o0.xyzw, r0.xyzw
ret
Merge request reports
Activity
If we find constant folding problems it might be beneficial to immediately discard this folding of identities as a suspect. Also the asymmetry of how the cases with two constants will be handled bothers me a little, we would be folding
0 + 8
but no8 + 0
. And there isn't much gain in simplification since we also have to check that the expression indeed has two operands in the new version.Anyways, these are little things and the code seems more readable, so I applied this suggestion.
Thinking more about it, this machinery could be useful to allow DCE to fold short-circuit evaluation, for
false and x
andtrue or x
.In the native compiler it seems quite aggressive, not even resource loads are safe:
Texture2D tex; float4 main() : sv_target { if (false && tex.Load(int3(0, 0, 0)).x == 2.0) return 0; return 1; }
Hmm, I don't remember whether HLSL has the same short circuit rules as C, but if it does the above code should already compile (at the frontend level) to something like:
if (false) { if (tex.Load(...)) return 0; } return 1;
And here you don't need to fold any identity, this is just dropping statically unreachable branches (which I guess we already have, don't we?). Also notice that here the
Load()
result is unused and I don't thinkLoad()
can have any side effect, so the compiler might just be dropping it independently of short circuit rules.
- Resolved by Giovanni Mascellani
- Resolved by Giovanni Mascellani
Oh, I was forgetting: could you also add your test to the test suite?
added 101 commits
-
b9085323...13e14919 - 98 commits from branch
wine:master
- c43c900a - tests: Test x + 0 and x * 1 indentities.
- b14f935d - vkd3d-shader/hlsl: Fold x + 0 identities.
- ee735e8e - vkd3d-shader/hlsl: Fold x * 1 identities.
Toggle commit list-
b9085323...13e14919 - 98 commits from branch