diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 01bfdf64ada..c62b35537e4 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -1529,6 +1529,7 @@ INSTR3(MAD_U24) INSTR3(MAD_S24) INSTR3(MAD_F16) INSTR3(MAD_F32) +/* NOTE: SEL_B32 checks for zero vs nonzero */ INSTR3(SEL_B16) INSTR3(SEL_B32) INSTR3(SEL_S16) diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index 5057215c3d2..bc0513f413e 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -629,10 +629,17 @@ emit_alu(struct ir3_context *ctx, nir_alu_instr *alu) case nir_op_b16csel: case nir_op_b32csel: { - struct ir3_instruction *cond = ir3_b2n(b, src[0]); + struct ir3_instruction *cond = src[0]; - if ((src[0]->regs[0]->flags & IR3_REG_HALF)) - cond->regs[0]->flags |= IR3_REG_HALF; + /* If src[0] is a negation (likely as a result of an ir3_b2n(cond)), + * we can ignore that and use original cond, since the nonzero-ness of + * cond stays the same. + */ + if (cond->opc == OPC_ABSNEG_S && + cond->flags == 0 && + (cond->regs[1]->flags & (IR3_REG_SNEG | IR3_REG_SABS)) == IR3_REG_SNEG) { + cond = cond->regs[1]->instr; + } compile_assert(ctx, bs[1] == bs[2]); /* Make sure the boolean condition has the same bit size as the other