I suppose that you're spelling out the dot product so that it works with any numeric type? I'd rather emit an actual DOT here and then implement DOT lowering for integral types: you make the code cleaner and implement another feature for free.
That is a good idea! I did just that. Note that HLSL_OP2_DOT is not defined for bools, so bool vectors are a special case I had to handle with HLSL_OP2_LOGIC_AND and HLSL_OP2_LOGIC_OR.
Also, notice that the current code triggers an assertion when indexing `bool4`. I think that's due to the introduction of a `bool` cast once they're assumed to have already been lowered. I guess this pass should happen a bit earlier (though, to be fair, it's always difficult to track the pass dependencies and assumptions).
I moved lower_nonconstant_vector_derefs() up. Also, I realized that this shouldn't be a transform_derefs(·) pass, but just a hlsl_transform_ir(·) pass on hlsl_ir_loads. transform_derefs(·) will still be used in following patches though, so I will keep its introduction patch here.