assert(nir_alu_type_get_type_size(src_type) == 0 ||
nir_alu_type_get_type_size(src_type) == src->bit_size);
- src_type = (nir_alu_type) (src_type | src->bit_size);
+ const nir_alu_type dst_base =
+ (nir_alu_type) nir_alu_type_get_base_type(dest_type);
- nir_op opcode =
- nir_type_conversion_op(src_type, dest_type, rnd);
- if (opcode == nir_op_mov)
- return src;
+ const nir_alu_type src_base =
+ (nir_alu_type) nir_alu_type_get_base_type(src_type);
- return nir_build_alu(b, opcode, src, NULL, NULL, NULL);
+ /* b2b and f2b use the regular type conversion path, but i2b is implemented
+ * as src != 0.
+ */
+ if (dst_base == nir_type_bool && (src_base == nir_type_int ||
+ src_base == nir_type_uint)) {
+ nir_op opcode;
+
+ const unsigned dst_bit_size = nir_alu_type_get_type_size(dest_type);
+
+ switch (dst_bit_size) {
+ case 1: opcode = nir_op_ine; break;
+ case 8: opcode = nir_op_ine8; break;
+ case 16: opcode = nir_op_ine16; break;
+ case 32: opcode = nir_op_ine32; break;
+ default: unreachable("Invalid Boolean size.");
+ }
+
+ return nir_build_alu(b, opcode, src,
+ nir_imm_zero(b, src->num_components, src->bit_size),
+ NULL, NULL);
+ } else {
+ src_type = (nir_alu_type) (src_type | src->bit_size);
+
+ nir_op opcode =
+ nir_type_conversion_op(src_type, dest_type, rnd);
+ if (opcode == nir_op_mov)
+ return src;
+
+ return nir_build_alu(b, opcode, src, NULL, NULL, NULL);
+ }
}
nir_ssa_def *