ac/llvm: force fneg/fabs to flush denorms to zero if requested
LLVM optimizes these instructions with XOR/AND and it loses the sign bit. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
parent
7dfb15fff1
commit
2c2aaf275c
|
@ -516,6 +516,13 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
|
|||
case nir_op_fneg:
|
||||
src[0] = ac_to_float(&ctx->ac, src[0]);
|
||||
result = LLVMBuildFNeg(ctx->ac.builder, src[0], "");
|
||||
if (ctx->ac.float_mode == AC_FLOAT_MODE_DENORM_FLUSH_TO_ZERO) {
|
||||
/* fneg will be optimized by backend compiler with sign
|
||||
* bit removed via XOR. This is probably a LLVM bug.
|
||||
*/
|
||||
result = ac_build_canonicalize(&ctx->ac, result,
|
||||
instr->dest.dest.ssa.bit_size);
|
||||
}
|
||||
break;
|
||||
case nir_op_ineg:
|
||||
result = LLVMBuildNeg(ctx->ac.builder, src[0], "");
|
||||
|
@ -646,6 +653,13 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
|
|||
case nir_op_fabs:
|
||||
result = emit_intrin_1f_param(&ctx->ac, "llvm.fabs",
|
||||
ac_to_float_type(&ctx->ac, def_type), src[0]);
|
||||
if (ctx->ac.float_mode == AC_FLOAT_MODE_DENORM_FLUSH_TO_ZERO) {
|
||||
/* fabs will be optimized by backend compiler with sign
|
||||
* bit removed via AND.
|
||||
*/
|
||||
result = ac_build_canonicalize(&ctx->ac, result,
|
||||
instr->dest.dest.ssa.bit_size);
|
||||
}
|
||||
break;
|
||||
case nir_op_iabs:
|
||||
result = emit_iabs(&ctx->ac, src[0]);
|
||||
|
|
Loading…
Reference in New Issue