nir: Add and use algebraic property "is selection"

There are several places that should have supported the various sized
versions of bcsel and the various nir_op_[fi]csel_* opcodes.  Rather
than enumerate the whole list, add a property.

v2: Make the comment for NIR_OP_IS_SELECTION more descriptive.
Suggested by Jason.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17048>
This commit is contained in:
Ian Romanick 2019-06-18 18:08:45 -07:00 committed by Marge Bot
parent a2a2fbc510
commit fd1f2d3b5a
4 changed files with 25 additions and 13 deletions

View File

@ -1355,6 +1355,13 @@ typedef enum {
* Operation is associative
*/
NIR_OP_IS_ASSOCIATIVE = (1 << 1),
/**
* Operation where src[0] is used to select src[1] on true or src[2] false.
* src[0] may be Boolean, or it may be another type used in an implicit
* comparison.
*/
NIR_OP_IS_SELECTION = (1 << 2),
} nir_op_algebraic_property;
/* vec16 is the widest ALU op in NIR, making the max number of input of ALU
@ -1419,6 +1426,12 @@ typedef struct nir_op_info {
/** Metadata for each nir_op, indexed by opcode */
extern const nir_op_info nir_op_infos[nir_num_opcodes];
static inline bool
nir_op_is_selection(nir_op op)
{
return (nir_op_infos[op].algebraic_properties & NIR_OP_IS_SELECTION) != 0;
}
typedef struct nir_alu_instr {
/** Base instruction */
nir_instr instr;

View File

@ -146,6 +146,7 @@ def type_base_type(type_):
# sources.
_2src_commutative = "2src_commutative "
associative = "associative "
selection = "selection "
# global dictionary of opcodes
opcodes = {}
@ -1008,22 +1009,22 @@ triop("iadd3", tint, _2src_commutative + associative, "src0 + src1 + src2")
# component on vectors). There are two versions, one for floating point
# bools (0.0 vs 1.0) and one for integer bools (0 vs ~0).
triop("fcsel", tfloat32, "", "(src0 != 0.0f) ? src1 : src2")
triop("fcsel", tfloat32, selection, "(src0 != 0.0f) ? src1 : src2")
opcode("bcsel", 0, tuint, [0, 0, 0],
[tbool1, tuint, tuint], False, "", "src0 ? src1 : src2")
[tbool1, tuint, tuint], False, selection, "src0 ? src1 : src2")
opcode("b8csel", 0, tuint, [0, 0, 0],
[tbool8, tuint, tuint], False, "", "src0 ? src1 : src2")
[tbool8, tuint, tuint], False, selection, "src0 ? src1 : src2")
opcode("b16csel", 0, tuint, [0, 0, 0],
[tbool16, tuint, tuint], False, "", "src0 ? src1 : src2")
[tbool16, tuint, tuint], False, selection, "src0 ? src1 : src2")
opcode("b32csel", 0, tuint, [0, 0, 0],
[tbool32, tuint, tuint], False, "", "src0 ? src1 : src2")
[tbool32, tuint, tuint], False, selection, "src0 ? src1 : src2")
triop("i32csel_gt", tint32, "", "(src0 > 0) ? src1 : src2")
triop("i32csel_ge", tint32, "", "(src0 >= 0) ? src1 : src2")
triop("i32csel_gt", tint32, selection, "(src0 > 0) ? src1 : src2")
triop("i32csel_ge", tint32, selection, "(src0 >= 0) ? src1 : src2")
triop("fcsel_gt", tfloat32, "", "(src0 > 0.0f) ? src1 : src2")
triop("fcsel_ge", tfloat32, "", "(src0 >= 0.0f) ? src1 : src2")
triop("fcsel_gt", tfloat32, selection, "(src0 > 0.0f) ? src1 : src2")
triop("fcsel_ge", tfloat32, selection, "(src0 >= 0.0f) ? src1 : src2")
# SM5 bfi assembly
triop("bfi", tuint32, "", """

View File

@ -303,9 +303,7 @@ is_trivial_bcsel(const nir_instr *instr, bool allow_non_phi_src)
return false;
nir_alu_instr *const bcsel = nir_instr_as_alu(instr);
if (bcsel->op != nir_op_bcsel &&
bcsel->op != nir_op_b32csel &&
bcsel->op != nir_op_fcsel)
if (!nir_op_is_selection(bcsel->op))
return false;
for (unsigned i = 0; i < 3; i++) {

View File

@ -38,7 +38,7 @@
static bool
opt_undef_csel(nir_alu_instr *instr)
{
if (instr->op != nir_op_bcsel && instr->op != nir_op_fcsel)
if (!nir_op_is_selection(instr->op))
return false;
assert(instr->dest.dest.is_ssa);