nir/spirv: initial handling of OpenCL.std extension opcodes
[mesa.git] / src / compiler / nir / nir_opt_algebraic.py
index e8191b722718fa5cb99ec840af1d6d471e7f67bf..5b2e7ee2405378896e8283641c9302a84b2651bd 100644 (file)
@@ -678,6 +678,12 @@ optimizations = [
     ('bcsel', ('ilt', 31, 'bits'), 'insert',
               ('bfi', ('bfm', 'bits', 'offset'), 'insert', 'base')),
     'options->lower_bitfield_insert'),
+   (('ihadd', a, b), ('iadd', ('iand', a, b), ('ishr', ('ixor', a, b), 1)), 'options->lower_hadd'),
+   (('uhadd', a, b), ('iadd', ('iand', a, b), ('ushr', ('ixor', a, b), 1)), 'options->lower_hadd'),
+   (('irhadd', a, b), ('isub', ('ior', a, b), ('ishr', ('ixor', a, b), 1)), 'options->lower_hadd'),
+   (('urhadd', a, b), ('isub', ('ior', a, b), ('ushr', ('ixor', a, b), 1)), 'options->lower_hadd'),
+   (('uadd_sat', a, b), ('bcsel', ('ult', ('iadd', a, b), a), -1, ('iadd', a, b)), 'options->lower_add_sat'),
+   (('usub_sat', a, b), ('bcsel', ('ult', a, b), 0, ('isub', a, b)), 'options->lower_add_sat'),
 
    # Alternative lowering that doesn't rely on bfi.
    (('bitfield_insert', 'base', 'insert', 'offset', 'bits'),
@@ -794,6 +800,21 @@ optimizations = [
    (('isign', a), ('imin', ('imax', a, -1), 1), 'options->lower_isign'),
 ]
 
+# bit_size dependent lowerings
+for bit_size in [8, 16, 32, 64]:
+   # convenience constants
+   intmax = (1 << (bit_size - 1)) - 1
+   intmin = 1 << (bit_size - 1)
+
+   optimizations += [
+      (('iadd_sat@' + str(bit_size), a, b),
+       ('bcsel', ('ige', b, 1), ('bcsel', ('ilt', ('iadd', a, b), a), intmax, ('iadd', a, b)),
+                                ('bcsel', ('ilt', a, ('iadd', a, b)), intmin, ('iadd', a, b))), 'options->lower_add_sat'),
+      (('isub_sat@' + str(bit_size), a, b),
+       ('bcsel', ('ilt', b, 0), ('bcsel', ('ilt', ('isub', a, b), a), intmax, ('isub', a, b)),
+                                ('bcsel', ('ilt', a, ('isub', a, b)), intmin, ('isub', a, b))), 'options->lower_add_sat'),
+   ]
+
 invert = OrderedDict([('feq', 'fne'), ('fne', 'feq'), ('fge', 'flt'), ('flt', 'fge')])
 
 for left, right in itertools.combinations_with_replacement(invert.keys(), 2):