nir: introduce lowering of bitfield_insert to bfm and a new opcode bitfield_select.
authorDaniel Schürmann <daniel@schuermann.dev>
Thu, 13 Jun 2019 09:34:01 +0000 (11:34 +0200)
committerDaniel Schürmann <daniel@schuermann.dev>
Mon, 24 Jun 2019 16:42:20 +0000 (18:42 +0200)
bitfield_select is defined as:
bitfield_select(mask, base, insert) = (mask & base) | (~mask & insert)
matching the behavior of AMD's BFI instruction.

Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
src/compiler/nir/nir.h
src/compiler/nir/nir_opcodes.py
src/compiler/nir/nir_opt_algebraic.py

index 9feed169e4727ce9f92021fb4ada67edbdc57247..bc9122d1f254fc4d9e4c8854635c73d5edcd5c41 100644 (file)
@@ -2288,6 +2288,8 @@ typedef struct nir_shader_compiler_options {
    bool lower_bitfield_insert;
    /** Lowers bitfield_insert to compares, and shifts. */
    bool lower_bitfield_insert_to_shifts;
+   /** Lowers bitfield_insert to bfm/bitfield_select. */
+   bool lower_bitfield_insert_to_bitfield_select;
    /** Lowers bitfield_reverse to shifts. */
    bool lower_bitfield_reverse;
    /** Lowers bit_count to shifts. */
index 8771c74b0337364dd7f44a6f95d4e6b2679d6670..a12b0269e2e4156b49b1231a66a509cecbacade6 100644 (file)
@@ -871,6 +871,9 @@ if (mask == 0) {
 }
 """)
 
+
+triop("bitfield_select", tuint, "", "(src0 & src1) | (~src0 & src2)")
+
 # SM5 ubfe/ibfe assembly: only the 5 least significant bits of offset and bits are used.
 opcode("ubfe", 0, tuint32,
        [0, 0, 0], [tuint32, tuint32, tuint32], False, "", """
index 0d21696273a70efcdc8b448161c88126a21498a3..4147be9c1f790465f674dbb39c44ac9fee165bc6 100644 (file)
@@ -799,6 +799,12 @@ optimizations.extend([
     ('iand', ('ishl', 'insert', 'offset'), ('ishl', ('isub', ('ishl', 1, 'bits'), 1), 'offset'))),
     'options->lower_bitfield_insert_to_shifts'),
 
+   # Alternative lowering that uses bitfield_select.
+   (('bitfield_insert', 'base', 'insert', 'offset', 'bits'),
+    ('bcsel', ('ult', 31, 'bits'), 'insert',
+              ('bitfield_select', ('bfm', 'bits', 'offset'), ('ishl', 'insert', 'offset'), 'base')),
+    'options->lower_bitfield_insert_to_bitfield_select'),
+
    (('ibitfield_extract', 'value', 'offset', 'bits'),
     ('bcsel', ('ult', 31, 'bits'), 'value',
               ('ibfe', 'value', 'offset', 'bits')),