nir/opt_undef: add a pass to clean up 64bit undefs
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Wed, 21 Sep 2022 13:49:11 +0000 (09:49 -0400)
committerMarge Bot <emma+marge@anholt.net>
Tue, 27 Sep 2022 18:38:25 +0000 (18:38 +0000)
somehow 64bit lowering creates patterns like

vec1 64 ssa_1 = undefined
ssa_2 = unpack_64_2x32_split_x ssa_1

and then the 64bit value is never otherwise used. for this case, rewriting
the unpack to just be a 32bit undef allows the 64bit undef to be optimized
out, avoiding spec violations

fixes #6945

SoroushIMG <soroush.kashani@imgtec.com>

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18728>

src/compiler/nir/nir_opt_undef.c

index 0d63de7..effd9d0 100644 (file)
@@ -169,11 +169,32 @@ opt_undef_store(nir_intrinsic_instr *intrin)
 }
 
 static bool
+opt_undef_pack(nir_builder *b, nir_alu_instr *alu)
+{
+   switch (alu->op) {
+   case nir_op_unpack_64_2x32_split_x:
+   case nir_op_unpack_64_2x32_split_y:
+   case nir_op_unpack_64_2x32:
+      if (nir_src_is_undef(alu->src[0].src))
+         break;
+      return false;
+   default:
+      return false;
+   }
+   unsigned num_components = nir_dest_num_components(alu->dest.dest);
+   b->cursor = nir_before_instr(&alu->instr);
+   nir_ssa_def *def = nir_ssa_undef(b, num_components, 32);
+   nir_ssa_def_rewrite_uses_after(&alu->dest.dest.ssa, def, &alu->instr);
+   nir_instr_remove(&alu->instr);
+   return true;
+}
+
+static bool
 nir_opt_undef_instr(nir_builder *b, nir_instr *instr, void *data)
 {
    if (instr->type == nir_instr_type_alu) {
       nir_alu_instr *alu = nir_instr_as_alu(instr);
-      return opt_undef_csel(alu) || opt_undef_vecN(b, alu);
+      return opt_undef_csel(alu) || opt_undef_vecN(b, alu) || opt_undef_pack(b, alu);
    } else if (instr->type == nir_instr_type_intrinsic) {
       nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
       return opt_undef_store(intrin);