Zebediah Figura (@zfigura) commented about libs/vkd3d-shader/hlsl_codegen.c:
- For the latter case, this pass takes care of lowering hlsl_ir_indexes (and index chains) into
- individual hlsl_ir_loads.
- It is worth noting that the generated hlsl_ir_loads don't load from a copy of the variable loaded
- at the beginning of the index chain, but from the same variable instead, because it is assumed
- that the value of the variable won't change between the the hlsl_ir_load instruction and the
- hlsl_ir_index. */
- at the beginning of the index chain, but from the same variable instead. This can be done because
- the copy_index_values pass takes care of creating the copies and pointing the index chains to
- them. */
I'm not quite happy about the explanation before or after this commit.
From my perspective, the result of "x[x[1] = 1]" in patch 3/10 is counterintuitive. If the array is evaluated before its index, then I would expect it to have an intermediate value, just like func(10) does. Like, there *shouldn't* be any difference between two different node types conceptually.
...and then I realized, in the middle of writing that, that "the array is evaluated before its index" is an implicit assumption, and lo and behold, testing shows that's simply not the case. Here's a simple shader that proves it:
``` float4 func(void) { static uint i;
i += 1;
return float4(0.1, 0.2, 0.3, 0.4) + i; }
float4 main() : sv_target { return func()[func().x]; } ```
This returns 2.2; if the array were evaluated first it'd be 1.3 (as vkd3d with this patch series).
This means, I think that if we reverse the list_move_tail() in the array indexing rule, there's no reason that we can't just always use a synthetic load when lowering indices.
Yes, this results in an unnecessary proliferation of temporary variables and LOAD instructions. But I'd really rather have IR that behaves according to consistent rules as a top priority, so that (a) that kind of function-call behaviour that we're trying to fix never happens again, and (b) we don't have to do mental gymnastics to prove that it can't happen.