diff --git a/src/freedreno/ir3/ir3_nir.c b/src/freedreno/ir3/ir3_nir.c index ee37f71bc98..87ef22da394 100644 --- a/src/freedreno/ir3/ir3_nir.c +++ b/src/freedreno/ir3/ir3_nir.c @@ -705,6 +705,7 @@ ir3_nir_lower_variant(struct ir3_shader_variant *so, nir_shader *s) progress |= OPT(s, nir_lower_wrmasks, should_split_wrmask, s); progress |= OPT(s, ir3_nir_lower_64b_intrinsics); + progress |= OPT(s, ir3_nir_lower_64b_undef); progress |= OPT(s, nir_lower_int64); if (!so->binning_pass) diff --git a/src/freedreno/ir3/ir3_nir.h b/src/freedreno/ir3/ir3_nir.h index 1f9e9c7cb87..10bc8a9b08e 100644 --- a/src/freedreno/ir3/ir3_nir.h +++ b/src/freedreno/ir3/ir3_nir.h @@ -58,6 +58,7 @@ void ir3_nir_lower_gs(nir_shader *shader); * 64b related lowering: */ bool ir3_nir_lower_64b_intrinsics(nir_shader *shader); +bool ir3_nir_lower_64b_undef(nir_shader *shader); const nir_shader_compiler_options * ir3_get_compiler_options(struct ir3_compiler *compiler); diff --git a/src/freedreno/ir3/ir3_nir_lower_64b.c b/src/freedreno/ir3/ir3_nir_lower_64b.c index 857f5835269..05a2c9d1fcb 100644 --- a/src/freedreno/ir3/ir3_nir_lower_64b.c +++ b/src/freedreno/ir3/ir3_nir_lower_64b.c @@ -173,3 +173,44 @@ ir3_nir_lower_64b_intrinsics(nir_shader *shader) shader, lower_64b_intrinsics_filter, lower_64b_intrinsics, NULL); } + +/* + * Lowering for 64b undef instructions, splitting into a two 32b undefs + */ + +static nir_ssa_def * +lower_64b_undef(nir_builder *b, nir_instr *instr, void *unused) +{ + (void)unused; + + nir_ssa_undef_instr *undef = nir_instr_as_ssa_undef(instr); + unsigned num_comp = undef->def.num_components; + nir_ssa_def *components[num_comp]; + + for (unsigned i = 0; i < num_comp; i++) { + nir_ssa_def *lowered = nir_ssa_undef(b, 2, 32); + + components[i] = nir_pack_64_2x32_split(b, + nir_channel(b, lowered, 0), + nir_channel(b, lowered, 1)); + } + + return nir_build_alu_src_arr(b, nir_op_vec(num_comp), components); +} + +static bool +lower_64b_undef_filter(const nir_instr *instr, const void *unused) +{ + (void)unused; + + return instr->type == nir_instr_type_ssa_undef && + nir_instr_as_ssa_undef(instr)->def.bit_size == 64; +} + +bool +ir3_nir_lower_64b_undef(nir_shader *shader) +{ + return nir_shader_lower_instructions( + shader, lower_64b_undef_filter, + lower_64b_undef, NULL); +}