nir/algebraic: mark some optimizations with fsat(NaN) as inexact
[mesa.git] / src / compiler / nir / nir_search_helpers.h
index a52104c7109007c47a142fbfc7f1a60d89f1e936..abfd660ae792597475df99956a411b6a1eab9398 100644 (file)
@@ -42,7 +42,8 @@ is_pos_power_of_two(UNUSED struct hash_table *ht, nir_alu_instr *instr,
       return false;
 
    for (unsigned i = 0; i < num_components; i++) {
-      switch (nir_op_infos[instr->op].input_types[src]) {
+      nir_alu_type type = nir_op_infos[instr->op].input_types[src];
+      switch (nir_alu_type_get_base_type(type)) {
       case nir_type_int: {
          int64_t val = nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
          if (val <= 0 || !util_is_power_of_two_or_zero64(val))
@@ -73,7 +74,8 @@ is_neg_power_of_two(UNUSED struct hash_table *ht, nir_alu_instr *instr,
       return false;
 
    for (unsigned i = 0; i < num_components; i++) {
-      switch (nir_op_infos[instr->op].input_types[src]) {
+      nir_alu_type type = nir_op_infos[instr->op].input_types[src];
+      switch (nir_alu_type_get_base_type(type)) {
       case nir_type_int: {
          int64_t val = nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
          if (val >= 0 || !util_is_power_of_two_or_zero64(-val))
@@ -88,6 +90,32 @@ is_neg_power_of_two(UNUSED struct hash_table *ht, nir_alu_instr *instr,
    return true;
 }
 
+#define MULTIPLE(test)                                                  \
+static inline bool                                                      \
+is_unsigned_multiple_of_ ## test(UNUSED struct hash_table *ht, nir_alu_instr *instr, \
+                                 unsigned src, unsigned num_components, \
+                                 const uint8_t *swizzle)                \
+{                                                                       \
+   /* only constant srcs: */                                            \
+   if (!nir_src_is_const(instr->src[src].src))                          \
+      return false;                                                     \
+                                                                        \
+   for (unsigned i = 0; i < num_components; i++) {                      \
+      uint64_t val = nir_src_comp_as_uint(instr->src[src].src, swizzle[i]); \
+      if (val % test != 0)                                              \
+         return false;                                                  \
+   }                                                                    \
+                                                                        \
+   return true;                                                         \
+}
+
+MULTIPLE(2)
+MULTIPLE(4)
+MULTIPLE(8)
+MULTIPLE(16)
+MULTIPLE(32)
+MULTIPLE(64)
+
 static inline bool
 is_zero_to_one(UNUSED struct hash_table *ht, nir_alu_instr *instr, unsigned src,
                unsigned num_components,
@@ -153,7 +181,8 @@ is_not_const_zero(UNUSED struct hash_table *ht, nir_alu_instr *instr,
       return true;
 
    for (unsigned i = 0; i < num_components; i++) {
-      switch (nir_op_infos[instr->op].input_types[src]) {
+      nir_alu_type type = nir_op_infos[instr->op].input_types[src];
+      switch (nir_alu_type_get_base_type(type)) {
       case nir_type_float:
          if (nir_src_comp_as_float(instr->src[src].src, swizzle[i]) == 0.0)
             return false;
@@ -209,7 +238,7 @@ is_fsign(nir_alu_instr *instr, unsigned src,
    if (src_alu->op == nir_op_fneg)
       src_alu = nir_src_as_alu_instr(src_alu->src[0].src);
 
-   return src_alu->op == nir_op_fsign;
+   return src_alu != NULL && src_alu->op == nir_op_fsign;
 }
 
 static inline bool
@@ -223,8 +252,8 @@ is_not_const_and_not_fsign(struct hash_table *ht, nir_alu_instr *instr, unsigned
 static inline bool
 is_used_once(nir_alu_instr *instr)
 {
-   bool zero_if_use = list_empty(&instr->dest.dest.ssa.if_uses);
-   bool zero_use = list_empty(&instr->dest.dest.ssa.uses);
+   bool zero_if_use = list_is_empty(&instr->dest.dest.ssa.if_uses);
+   bool zero_use = list_is_empty(&instr->dest.dest.ssa.uses);
 
    if (zero_if_use && zero_use)
       return false;
@@ -245,13 +274,13 @@ is_used_once(nir_alu_instr *instr)
 static inline bool
 is_used_by_if(nir_alu_instr *instr)
 {
-   return !list_empty(&instr->dest.dest.ssa.if_uses);
+   return !list_is_empty(&instr->dest.dest.ssa.if_uses);
 }
 
 static inline bool
 is_not_used_by_if(nir_alu_instr *instr)
 {
-   return list_empty(&instr->dest.dest.ssa.if_uses);
+   return list_is_empty(&instr->dest.dest.ssa.if_uses);
 }
 
 static inline bool