diff --git a/src/freedreno/ir3/ir3_nir_opt_preamble.c b/src/freedreno/ir3/ir3_nir_opt_preamble.c index b3c5dee36ce..3997c03d842 100644 --- a/src/freedreno/ir3/ir3_nir_opt_preamble.c +++ b/src/freedreno/ir3/ir3_nir_opt_preamble.c @@ -212,6 +212,8 @@ instr_cost(nir_instr *instr, const void *data) static float rewrite_cost(nir_def *def, const void *data) { + const struct ir3_shader_variant *v = data; + /* We always have to expand booleans */ if (def->bit_size == 1) return def->num_components; @@ -219,10 +221,7 @@ rewrite_cost(nir_def *def, const void *data) bool mov_needed = false; nir_foreach_use (use, def) { nir_instr *parent_instr = nir_src_parent_instr(use); - if (parent_instr->type != nir_instr_type_alu) { - mov_needed = true; - break; - } else { + if (parent_instr->type == nir_instr_type_alu) { nir_alu_instr *alu = nir_instr_as_alu(parent_instr); if (alu->op == nir_op_vec2 || alu->op == nir_op_vec3 || @@ -233,6 +232,23 @@ rewrite_cost(nir_def *def, const void *data) } else { /* Assume for non-moves that the const is folded into the src */ } + } else if (parent_instr->type == nir_instr_type_intrinsic) { + nir_intrinsic_instr *parent_intrin = + nir_instr_as_intrinsic(parent_instr); + + if (v->compiler->has_alias_rt && v->type == MESA_SHADER_FRAGMENT && + parent_intrin->intrinsic == nir_intrinsic_store_output && + def->bit_size == 32) { + /* For FS outputs, alias.rt can use const registers without a mov. + * This only works for full regs though. + */ + } else { + mov_needed = true; + break; + } + } else { + mov_needed = true; + break; } } @@ -307,6 +323,7 @@ ir3_nir_opt_preamble(nir_shader *nir, struct ir3_shader_variant *v) .instr_cost_cb = instr_cost, .avoid_instr_cb = avoid_instr, .rewrite_cost_cb = rewrite_cost, + .cb_data = v, }; unsigned size = 0;