summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/a3xx
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2014-03-01 12:06:44 -0500
committerRob Clark <[email protected]>2014-03-02 11:26:35 -0500
commite0007f733dfffff2b5c3729546d6c16ecba6faa9 (patch)
tree497b719fe899ba80c0a05b144b7284a424965c54 /src/gallium/drivers/freedreno/a3xx
parent26530716ab9398703f91285381033073f47e8bd4 (diff)
freedreno/a3xx/compiler: fix for resolving PHI's
A value may be assigned on only one side of an if/else. In this case we can simply substitute a mov.f32f32. Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/a3xx')
-rw-r--r--src/gallium/drivers/freedreno/a3xx/ir3_flatten.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/ir3_flatten.c b/src/gallium/drivers/freedreno/a3xx/ir3_flatten.c
index 3cf76db5005..00a2bf1dc47 100644
--- a/src/gallium/drivers/freedreno/a3xx/ir3_flatten.c
+++ b/src/gallium/drivers/freedreno/a3xx/ir3_flatten.c
@@ -51,7 +51,9 @@ static struct ir3_register *unwrap(struct ir3_register *reg)
switch (instr->opc) {
case OPC_META_OUTPUT:
case OPC_META_FLOW:
- return instr->regs[1];
+ if (instr->regs_count > 1)
+ return instr->regs[1];
+ return NULL;
default:
break;
}
@@ -78,25 +80,38 @@ static void ir3_instr_flatten(struct ir3_flatten_ctx *ctx,
if (instr->opc == OPC_META_PHI) {
struct ir3_register *cond, *t, *f;
- /* convert the PHI instruction to sel.{f16,f32} */
- instr->category = 3;
+ cond = unwrap(instr->regs[1]);
+ t = unwrap(instr->regs[2]); /* true val */
+ f = unwrap(instr->regs[3]); /* false val */
- /* instruction type based on dst size: */
- if (instr->regs[0]->flags & IR3_REG_HALF)
- instr->opc = OPC_SEL_F16;
- else
- instr->opc = OPC_SEL_F32;
-
- /* swap around src register order, to match what
- * hw expects:
+ /* must have cond, but t or f may be null if only written
+ * one one side of the if/else (in which case we can just
+ * convert the PHI to a simple move).
*/
- cond = instr->regs[1];
- t = instr->regs[2]; /* true val */
- f = instr->regs[3]; /* false val */
-
- instr->regs[1] = unwrap(f);
- instr->regs[2] = unwrap(cond);
- instr->regs[3] = unwrap(t);
+ assert(cond);
+ assert(t || f);
+
+ if (t && f) {
+ /* convert the PHI instruction to sel.{b16,b32} */
+ instr->category = 3;
+
+ /* instruction type based on dst size: */
+ if (instr->regs[0]->flags & IR3_REG_HALF)
+ instr->opc = OPC_SEL_B16;
+ else
+ instr->opc = OPC_SEL_B32;
+
+ instr->regs[1] = t;
+ instr->regs[2] = cond;
+ instr->regs[3] = f;
+ } else {
+ /* convert to simple mov: */
+ instr->category = 1;
+ instr->cat1.dst_type = TYPE_F32;
+ instr->cat1.src_type = TYPE_F32;
+ instr->regs_count = 2;
+ instr->regs[1] = t ? t : f;
+ }
ctx->cnt++;
} else if ((instr->opc == OPC_META_INPUT) &&