/**
* Turns a nir_src into a nir_ssa_def * so it can be passed to
* nir_build_alu()-based builder calls.
+ *
+ * See nir_ssa_for_alu_src() for alu instructions.
*/
static inline nir_ssa_def *
nir_ssa_for_src(nir_builder *build, nir_src src, int num_components)
return nir_imov_alu(build, alu, num_components);
}
+/**
+ * Similar to nir_ssa_for_src(), but for alu src's, respecting the
+ * nir_alu_src's swizzle.
+ */
+static inline nir_ssa_def *
+nir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn)
+{
+ static uint8_t trivial_swizzle[4] = { 0, 1, 2, 3 };
+ nir_alu_src *src = &instr->src[srcn];
+ unsigned num_components = nir_ssa_alu_instr_src_components(instr, srcn);
+
+ if (src->src.is_ssa && (src->src.ssa->num_components == num_components) &&
+ !src->abs && !src->negate &&
+ (memcmp(src->swizzle, trivial_swizzle, num_components) == 0))
+ return src->src.ssa;
+
+ return nir_imov_alu(build, *src, num_components);
+}
+
static inline nir_ssa_def *
nir_load_var(nir_builder *build, nir_variable *var)
{
bld->cursor = nir_before_instr(&alu->instr);
- numer = nir_ssa_for_src(bld, alu->src[0].src,
- nir_ssa_alu_instr_src_components(alu, 0));
- denom = nir_ssa_for_src(bld, alu->src[1].src,
- nir_ssa_alu_instr_src_components(alu, 1));
+ numer = nir_ssa_for_alu_src(bld, alu, 0);
+ denom = nir_ssa_for_alu_src(bld, alu, 1);
if (is_signed) {
af = nir_i2f(bld, numer);