nir: Replace an odd comparison involving fmin of -b2f
[mesa.git] / src / compiler / nir / nir_lower_double_ops.c
index ad9631327b4e116608994c80e4a460e99da6cf22..b3543bc6963ee4c2161a72aa72db1af2e4bfcd9e 100644 (file)
@@ -116,7 +116,7 @@ lower_rcp(nir_builder *b, nir_ssa_def *src)
    /* cast to float, do an rcp, and then cast back to get an approximate
     * result
     */
-   nir_ssa_def *ra = nir_f2d(b, nir_frcp(b, nir_d2f(b, src_norm)));
+   nir_ssa_def *ra = nir_f2f64(b, nir_frcp(b, nir_f2f32(b, src_norm)));
 
    /* Fixup the exponent of the result - note that we check if this is too
     * small below.
@@ -180,7 +180,7 @@ lower_sqrt_rsq(nir_builder *b, nir_ssa_def *src, bool sqrt)
                                         nir_iadd(b, nir_imm_int(b, 1023),
                                                  even));
 
-   nir_ssa_def *ra = nir_f2d(b, nir_frsq(b, nir_d2f(b, src_norm)));
+   nir_ssa_def *ra = nir_f2f64(b, nir_frsq(b, nir_f2f32(b, src_norm)));
    nir_ssa_def *new_exp = nir_isub(b, get_exponent(b, ra), half);
    ra = set_exponent(b, ra, new_exp);
 
@@ -456,61 +456,61 @@ lower_mod(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1)
                     nir_imm_double(b, 0.0));
 }
 
-static void
+static bool
 lower_doubles_instr(nir_alu_instr *instr, nir_lower_doubles_options options)
 {
    assert(instr->dest.dest.is_ssa);
    if (instr->dest.dest.ssa.bit_size != 64)
-      return;
+      return false;
 
    switch (instr->op) {
    case nir_op_frcp:
       if (!(options & nir_lower_drcp))
-         return;
+         return false;
       break;
 
    case nir_op_fsqrt:
       if (!(options & nir_lower_dsqrt))
-         return;
+         return false;
       break;
 
    case nir_op_frsq:
       if (!(options & nir_lower_drsq))
-         return;
+         return false;
       break;
 
    case nir_op_ftrunc:
       if (!(options & nir_lower_dtrunc))
-         return;
+         return false;
       break;
 
    case nir_op_ffloor:
       if (!(options & nir_lower_dfloor))
-         return;
+         return false;
       break;
 
    case nir_op_fceil:
       if (!(options & nir_lower_dceil))
-         return;
+         return false;
       break;
 
    case nir_op_ffract:
       if (!(options & nir_lower_dfract))
-         return;
+         return false;
       break;
 
    case nir_op_fround_even:
       if (!(options & nir_lower_dround_even))
-         return;
+         return false;
       break;
 
    case nir_op_fmod:
       if (!(options & nir_lower_dmod))
-         return;
+         return false;
       break;
 
    default:
-      return;
+      return false;
    }
 
    nir_builder bld;
@@ -560,20 +560,40 @@ lower_doubles_instr(nir_alu_instr *instr, nir_lower_doubles_options options)
 
    nir_ssa_def_rewrite_uses(&instr->dest.dest.ssa, nir_src_for_ssa(result));
    nir_instr_remove(&instr->instr);
+   return true;
 }
 
-void
+static bool
+nir_lower_doubles_impl(nir_function_impl *impl,
+                       nir_lower_doubles_options options)
+{
+   bool progress = false;
+
+   nir_foreach_block(block, impl) {
+      nir_foreach_instr_safe(instr, block) {
+         if (instr->type == nir_instr_type_alu)
+            progress |= lower_doubles_instr(nir_instr_as_alu(instr),
+                                            options);
+      }
+   }
+
+   if (progress)
+      nir_metadata_preserve(impl, nir_metadata_block_index |
+                                  nir_metadata_dominance);
+
+   return progress;
+}
+
+bool
 nir_lower_doubles(nir_shader *shader, nir_lower_doubles_options options)
 {
+   bool progress = false;
+
    nir_foreach_function(function, shader) {
-      if (!function->impl)
-         continue;
-
-      nir_foreach_block(block, function->impl) {
-         nir_foreach_instr_safe(instr, block) {
-            if (instr->type == nir_instr_type_alu)
-               lower_doubles_instr(nir_instr_as_alu(instr), options);
-         }
+      if (function->impl) {
+         progress |= nir_lower_doubles_impl(function->impl, options);
       }
    }
+
+   return progress;
 }