Giovanni Mascellani (@giomasce) commented about libs/vkd3d-shader/tpf.c:
if (ctx->temp_count) write_sm4_dcl_temps(&tpf, ctx->temp_count);
- LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry)
- {
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
if (var->is_uniform || var->is_input_semantic || var->is_output_semantic)
continue;
if (!var->regs[HLSL_REGSET_NUMERIC].allocated)
continue;
if (var->indexable)
{
unsigned int id = var->regs[HLSL_REGSET_NUMERIC].id;
I'm not sure this is correct: it seems that the `r` and `x` registers are two independent namespaces, so the `id` that was allocated for the variable as an `r` register has no meaning if you want it to use it as an `x` register. This has a few undesirable implications: * You're wasting registers, because an `r` register makes it impossible to use the corresponding `x` registers and viceversa. This might be minor, I guess, since it's quite likely that a downstream compiler is going to redo register allocation anyway. But it's not pretty. * More importantly, you might end up allocating two different variables (with independent lifespans) on the same or conflicting `x` registers, therefore creating duplicate and possibly contradicting `dcl_indexable_temp` instructions. That doesn't look right.
I think that the proper way forward here is to skip indexable variables from the usual register allocation algorithm and have another round of `x` register allocation for them, in which I think that lifetime doesn't have to be considered (i.e., variables must use independent registers even if they never are alive at the same time). This last bit might require some independent confirmation: I remember it from past experiments, but I might be mistaken.