Mesa (master): freedreno/a3xx/compiler: fix for resolving PHI's

Rob Clark robclark at kemper.freedesktop.org
Sun Mar 2 16:32:33 UTC 2014


Module: Mesa
Branch: master
Commit: e0007f733dfffff2b5c3729546d6c16ecba6faa9
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e0007f733dfffff2b5c3729546d6c16ecba6faa9

Author: Rob Clark <robclark at freedesktop.org>
Date:   Sat Mar  1 12:06:44 2014 -0500

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 <robclark at freedesktop.org>

---

 src/gallium/drivers/freedreno/a3xx/ir3_flatten.c |   51 ++++++++++++++--------
 1 file 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 3cf76db..00a2bf1 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) &&




More information about the mesa-commit mailing list