nir: add single bit test opcodes
authorGeorg Lehmann <dadschoorse@gmail.com>
Sat, 27 May 2023 09:27:12 +0000 (11:27 +0200)
committerMarge Bot <emma+marge@anholt.net>
Thu, 29 Jun 2023 13:39:30 +0000 (13:39 +0000)
These directly map to amd's SALU s_bitcmp0/1.
For VALU we can use v_cmp_class_f32 if the second source is constant.

Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23298>

src/compiler/nir/nir.c
src/compiler/nir/nir_opcodes.py

index fa67a94..4bca3aa 100644 (file)
@@ -3227,6 +3227,8 @@ nir_alu_instr_is_comparison(const nir_alu_instr *instr)
    CASE_ALL_SIZES(nir_op_uge)
    CASE_ALL_SIZES(nir_op_ieq)
    CASE_ALL_SIZES(nir_op_ine)
+   CASE_ALL_SIZES(nir_op_bitz)
+   CASE_ALL_SIZES(nir_op_bitnz)
    case nir_op_inot:
       return true;
    default:
index abdbccd..ca98f33 100644 (file)
@@ -571,30 +571,32 @@ if (src0.z < 0 && absZ >= absX && absZ >= absY) dst.x = 5;
 unop_reduce("fsum", 1, tfloat, tfloat, "{src}", "{src0} + {src1}", "{src}",
             description = "Sum of vector components")
 
-def binop_convert(name, out_type, in_type, alg_props, const_expr, description=""):
-   opcode(name, 0, out_type, [0, 0], [in_type, in_type],
+def binop_convert(name, out_type, in_type1, alg_props, const_expr, description="", in_type2=None):
+   if in_type2 is None:
+      in_type2 = in_type1
+   opcode(name, 0, out_type, [0, 0], [in_type1, in_type2],
           False, alg_props, const_expr, description)
 
 def binop(name, ty, alg_props, const_expr, description = ""):
    binop_convert(name, ty, ty, alg_props, const_expr, description)
 
-def binop_compare(name, ty, alg_props, const_expr, description = ""):
-   binop_convert(name, tbool1, ty, alg_props, const_expr, description)
+def binop_compare(name, ty, alg_props, const_expr, description = "", ty2=None):
+   binop_convert(name, tbool1, ty, alg_props, const_expr, description, ty2)
 
-def binop_compare8(name, ty, alg_props, const_expr, description = ""):
-   binop_convert(name, tbool8, ty, alg_props, const_expr, description)
+def binop_compare8(name, ty, alg_props, const_expr, description = "", ty2=None):
+   binop_convert(name, tbool8, ty, alg_props, const_expr, description, ty2)
 
-def binop_compare16(name, ty, alg_props, const_expr, description = ""):
-   binop_convert(name, tbool16, ty, alg_props, const_expr, description)
+def binop_compare16(name, ty, alg_props, const_expr, description = "", ty2=None):
+   binop_convert(name, tbool16, ty, alg_props, const_expr, description, ty2)
 
-def binop_compare32(name, ty, alg_props, const_expr, description = ""):
-   binop_convert(name, tbool32, ty, alg_props, const_expr, description)
+def binop_compare32(name, ty, alg_props, const_expr, description = "", ty2=None):
+   binop_convert(name, tbool32, ty, alg_props, const_expr, description, ty2)
 
-def binop_compare_all_sizes(name, ty, alg_props, const_expr, description = ""):
-   binop_compare(name, ty, alg_props, const_expr, description)
-   binop_compare8(name + "8", ty, alg_props, const_expr, description)
-   binop_compare16(name + "16", ty, alg_props, const_expr, description)
-   binop_compare32(name + "32", ty, alg_props, const_expr, description)
+def binop_compare_all_sizes(name, ty, alg_props, const_expr, description = "", ty2=None):
+   binop_compare(name, ty, alg_props, const_expr, description, ty2)
+   binop_compare8(name + "8", ty, alg_props, const_expr, description, ty2)
+   binop_compare16(name + "16", ty, alg_props, const_expr, description, ty2)
+   binop_compare32(name + "32", ty, alg_props, const_expr, description, ty2)
 
 def binop_horiz(name, out_size, out_type, src1_size, src1_type, src2_size,
                 src2_type, const_expr, description = ""):
@@ -847,6 +849,12 @@ binop_compare_all_sizes("ine", tint, _2src_commutative, "src0 != src1")
 binop_compare_all_sizes("ult", tuint, "", "src0 < src1")
 binop_compare_all_sizes("uge", tuint, "", "src0 >= src1")
 
+binop_compare_all_sizes("bitnz", tuint, "", "((uint64_t)src0 >> (src1 & (bit_size - 1)) & 0x1) == 0x1",
+   "only uses the least significant bits like SM5 shifts", tuint32)
+
+binop_compare_all_sizes("bitz", tuint, "", "((uint64_t)src0 >> (src1 & (bit_size - 1)) & 0x1) == 0x0",
+   "only uses the least significant bits like SM5 shifts", tuint32)
+
 # integer-aware GLSL-style comparisons that compare floats and ints
 
 binop_reduce_all_sizes("ball_fequal",  1, tfloat, "{src0} == {src1}",