From 6e2fda15f14d95ead492245698f430b6708329f0 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Mon, 1 Aug 2022 14:42:27 +0200 Subject: [PATCH] nv50/ir/nir: convert to 32 bit for all OP_SET opcodes The 'set' instruction does distinguish between signed and unsigned, but always treats values as 32 bit. For singed values < 0 with a bit width smaller than 32 bit this falsely results in treating it as a positive value. Reviewed-by: Karol Herbst Signed-off-by: Danilo Krummrich Part-of: --- src/nouveau/codegen/nv50_ir_from_nir.cpp | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/nouveau/codegen/nv50_ir_from_nir.cpp b/src/nouveau/codegen/nv50_ir_from_nir.cpp index 07d762c..8fa70c5 100644 --- a/src/nouveau/codegen/nv50_ir_from_nir.cpp +++ b/src/nouveau/codegen/nv50_ir_from_nir.cpp @@ -160,6 +160,8 @@ private: bool visit(nir_ssa_undef_instr *); bool visit(nir_tex_instr *); + static unsigned lowerBitSizeCB(const nir_instr *, void *); + // tex stuff unsigned int getNIRArgCount(TexInstruction::Target&); @@ -3238,6 +3240,62 @@ nv_nir_move_stores_to_end(nir_shader *s) nir_metadata_dominance); } +unsigned +Converter::lowerBitSizeCB(const nir_instr *instr, void *data) +{ + Converter *instance = static_cast(data); + nir_alu_instr *alu; + + if (instr->type != nir_instr_type_alu) + return 0; + + alu = nir_instr_as_alu(instr); + + switch (alu->op) { + /* TODO: Check for operation OP_SET instead of all listed nir opcodes + * individually. + * + * Currently, we can't call getOperation(nir_op), since not all nir opcodes + * are handled within getOperation() and we'd run into an assert(). + * + * Adding all nir opcodes to getOperation() isn't trivial, since the + * enum operation of some of the nir opcodes isn't distinct (e.g. depends + * on the data type). + */ + case nir_op_ieq8: + case nir_op_ige8: + case nir_op_uge8: + case nir_op_ilt8: + case nir_op_ult8: + case nir_op_ine8: + case nir_op_ieq16: + case nir_op_ige16: + case nir_op_uge16: + case nir_op_ilt16: + case nir_op_ult16: + case nir_op_ine16: + case nir_op_feq32: + case nir_op_ieq32: + case nir_op_fge32: + case nir_op_ige32: + case nir_op_uge32: + case nir_op_flt32: + case nir_op_ilt32: + case nir_op_ult32: + case nir_op_fneu32: + case nir_op_ine32: { + DataType stype = instance->getSTypes(alu)[0]; + + if (isSignedIntType(stype) && typeSizeof(stype) < 4) + return 32; + + return 0; + } + default: + return 0; + } +} + bool Converter::run() { @@ -3311,6 +3369,8 @@ Converter::run() NIR_PASS_V(nir, nv_nir_move_stores_to_end); NIR_PASS_V(nir, nir_lower_bool_to_int32); + NIR_PASS_V(nir, nir_lower_bit_size, Converter::lowerBitSizeCB, this); + NIR_PASS_V(nir, nir_convert_from_ssa, true); // Garbage collect dead instructions -- 2.7.4