*sz = MAX2(*sz, dsz);
- debug_assert(instr->opc == OPC_META_FO);
- *off = MAX2(*off, instr->fo.off);
+ if (instr->opc == OPC_META_FO)
+ *off = MAX2(*off, instr->fo.off);
d = dd;
}
} else if (instr->regs[0]->flags & IR3_REG_ARRAY) {
id->cls = total_class_count;
} else {
+ /* and the normal case: */
id->defn = get_definer(ctx, instr, &id->sz, &id->off);
id->cls = size_to_class(id->sz, is_half(id->defn), is_high(id->defn));
+
+ /* this is a bit of duct-tape.. if we have a scenario like:
+ *
+ * sam (f32)(x) out.x, ...
+ * sam (f32)(x) out.y, ...
+ *
+ * Then the fanout/split meta instructions for the two different
+ * tex instructions end up grouped as left/right neighbors. The
+ * upshot is that in when you get_definer() on one of the meta:fo's
+ * you get definer as the first sam with sz=2, but when you call
+ * get_definer() on the either of the sam's you get itself as the
+ * definer with sz=1.
+ *
+ * (We actually avoid this scenario exactly, the neighbor links
+ * prevent one of the output mov's from being eliminated, so this
+ * hack should be enough. But probably we need to rethink how we
+ * find the "defining" instruction.)
+ *
+ * TODO how do we figure out offset properly...
+ */
+ if (id->defn != instr) {
+ struct ir3_ra_instr_data *did = &ctx->instrd[id->defn->ip];
+ if (did->sz < id->sz) {
+ did->sz = id->sz;
+ did->cls = id->cls;
+ }
+ }
}
}
}