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:
parent
a2a2fbc510
commit
fd1f2d3b5a
|
@ -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;
|
||||
|
|
|
@ -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, "", """
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue