<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, Nov 13, 2018 at 9:48 AM Karol Herbst <<a href="mailto:kherbst@redhat.com">kherbst@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Rob Clark <<a href="mailto:robdclark@gmail.com" target="_blank">robdclark@gmail.com</a>><br>
<br>
changes by Karol:<br>
v2: make compatible with 64 bit floats<br>
    fix isfinite<br>
v3: use snake_case.<br>
<br>
Signed-off-by: Karol Herbst <<a href="mailto:kherbst@redhat.com" target="_blank">kherbst@redhat.com</a>><br>
---<br>
 src/compiler/spirv/vtn_alu.c | 32 ++++++++++++++++++++++++++++++++<br>
 1 file changed, 32 insertions(+)<br>
<br>
diff --git a/src/compiler/spirv/vtn_alu.c b/src/compiler/spirv/vtn_alu.c<br>
index b1492c1501a..ea25d4bcbdc 100644<br>
--- a/src/compiler/spirv/vtn_alu.c<br>
+++ b/src/compiler/spirv/vtn_alu.c<br>
@@ -583,6 +583,38 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,<br>
       break;<br>
    }<br>
<br>
+   case SpvOpIsFinite: {<br>
+      nir_ssa_def *inf = nir_imm_floatN_t(&b->nb, INFINITY, src[0]->bit_size);<br>
+      nir_ssa_def *is_number = nir_feq(&b->nb, src[0], src[0]);<br>
+      nir_ssa_def *is_not_inf = nir_ine(&b->nb, nir_fabs(&b->nb, src[0]), inf);<br>
+      val->ssa->def = nir_iand(&b->nb, is_number, is_not_inf);<br></blockquote><div><br></div><div>What we really want here is FOrdNotEqual.  Unfortunately, I'm not sure we're handling ordered vs. not correctly in the NIR opcodes but you should be able to just do return is_not_inf and the abs(x) != INF will return false if x is NaN assuming that abs handles NaN correctly.</div><div><br></div><div>Also, set b->nb.exact = true prior to this sequence to make it build exact opcodes so that NIR doesn't try to optimize anything away.</div><div><br></div><div>Also, I think it'd be nice to have these in builder helpers.  Not a bit deal but it'd be nice.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      break;<br>
+   }<br>
+<br>
+   case SpvOpIsNormal: {<br>
+      unsigned bit_size = src[0]->bit_size;<br>
+<br>
+      uint32_t m;<br>
+      if (bit_size == 64)<br>
+         m = 11;<br>
+      else if (bit_size == 32)<br>
+         m = 8;<br>
+      else if (bit_size == 16)<br>
+         m = 5;<br>
+      else<br>
+         assert(!"unknown float type");<br>
+<br>
+      nir_ssa_def *shift = nir_imm_int(&b->nb, bit_size - m - 1);<br>
+      nir_ssa_def *abs = nir_fabs(&b->nb, src[0]);<br>
+      nir_ssa_def *exp = nir_iadd(&b->nb,<br>
+                                  nir_ushr(&b->nb, abs, shift),<br>
+                                  nir_imm_intN_t(&b->nb, -1, bit_size));<br>
+      val->ssa->def = nir_ult(&b->nb,<br>
+                              exp,<br>
+                              nir_imm_intN_t(&b->nb, (1 << m) - 2, bit_size));<br></blockquote><div><br></div><div>I think you can do this way simpler:</div><div><br></div><div>iand(fne(x, 0.0), i2b(iand(x, 0x7f800000)))</div><div><br></div><div>assuming 0 is considered normal.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      break;<br>
+   }<br>
+<br>
    case SpvOpFUnordEqual:<br>
    case SpvOpFUnordNotEqual:<br>
    case SpvOpFUnordLessThan:<br>
-- <br>
2.19.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div></div>