summaryrefslogtreecommitdiff
path: root/src/freedreno/ir3/ir3_compiler_nir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/freedreno/ir3/ir3_compiler_nir.c')
-rw-r--r--src/freedreno/ir3/ir3_compiler_nir.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c
index b27253afd05..7478ec14d00 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -2644,6 +2644,14 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
src, 0);
dst[0]->dsts[0]->flags |= IR3_REG_SHARED;
dst[0]->srcs[0]->flags |= IR3_REG_PREDICATE;
+ /* Work around a bug with half-register shared -> non-shared moves by
+ * adding an extra mov here so that the original destination stays full.
+ */
+ if (src->dsts[0]->flags & IR3_REG_HALF) {
+ dst[0] = ir3_MOV(b, dst[0], TYPE_U32);
+ if (!ctx->compiler->has_scalar_alu)
+ dst[0]->dsts[0]->flags &= ~IR3_REG_SHARED;
+ }
break;
}
@@ -2651,6 +2659,12 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
struct ir3_instruction *src = ir3_get_src(ctx, &intr->src[0])[0];
dst[0] = ir3_READ_FIRST_MACRO(ctx->block, src, 0);
dst[0]->dsts[0]->flags |= IR3_REG_SHARED;
+ /* See above. */
+ if (src->dsts[0]->flags & IR3_REG_HALF) {
+ dst[0] = ir3_MOV(b, dst[0], TYPE_U32);
+ if (!ctx->compiler->has_scalar_alu)
+ dst[0]->dsts[0]->flags &= ~IR3_REG_SHARED;
+ }
break;
}
@@ -3586,7 +3600,12 @@ read_phi_src(struct ir3_context *ctx, struct ir3_block *blk,
/* Create an ir3 undef */
return NULL;
} else {
- return ir3_get_src(ctx, &nsrc->src)[0];
+ /* We need to insert the move at the end of the block */
+ struct ir3_block *old_block = ctx->block;
+ ctx->block = blk;
+ struct ir3_instruction *src = ir3_get_src(ctx, &nsrc->src)[0];
+ ctx->block = old_block;
+ return src;
}
}
}