aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/spirv/vtn_alu.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/src/compiler/spirv/vtn_alu.c b/src/compiler/spirv/vtn_alu.c
index 6d98a62ab97..95ff2b1aafe 100644
--- a/src/compiler/spirv/vtn_alu.c
+++ b/src/compiler/spirv/vtn_alu.c
@@ -257,7 +257,10 @@ vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap)
case SpvOpBitReverse: return nir_op_bitfield_reverse;
case SpvOpBitCount: return nir_op_bit_count;
- /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
+ /* The ordered / unordered operators need special implementation besides
+ * the logical operator to use since they also need to check if operands are
+ * ordered.
+ */
case SpvOpFOrdEqual: return nir_op_feq;
case SpvOpFUnordEqual: return nir_op_feq;
case SpvOpINotEqual: return nir_op_ine;
@@ -447,6 +450,54 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
nir_imm_float(&b->nb, INFINITY));
break;
+ case SpvOpFUnordEqual:
+ case SpvOpFUnordNotEqual:
+ case SpvOpFUnordLessThan:
+ case SpvOpFUnordGreaterThan:
+ case SpvOpFUnordLessThanEqual:
+ case SpvOpFUnordGreaterThanEqual: {
+ bool swap;
+ nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap);
+
+ if (swap) {
+ nir_ssa_def *tmp = src[0];
+ src[0] = src[1];
+ src[1] = tmp;
+ }
+
+ val->ssa->def =
+ nir_ior(&b->nb,
+ nir_build_alu(&b->nb, op, src[0], src[1], NULL, NULL),
+ nir_ior(&b->nb,
+ nir_fne(&b->nb, src[0], src[0]),
+ nir_fne(&b->nb, src[1], src[1])));
+ break;
+ }
+
+ case SpvOpFOrdEqual:
+ case SpvOpFOrdNotEqual:
+ case SpvOpFOrdLessThan:
+ case SpvOpFOrdGreaterThan:
+ case SpvOpFOrdLessThanEqual:
+ case SpvOpFOrdGreaterThanEqual: {
+ bool swap;
+ nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap);
+
+ if (swap) {
+ nir_ssa_def *tmp = src[0];
+ src[0] = src[1];
+ src[1] = tmp;
+ }
+
+ val->ssa->def =
+ nir_iand(&b->nb,
+ nir_build_alu(&b->nb, op, src[0], src[1], NULL, NULL),
+ nir_iand(&b->nb,
+ nir_feq(&b->nb, src[0], src[0]),
+ nir_feq(&b->nb, src[1], src[1])));
+ break;
+ }
+
default: {
bool swap;
nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap);