On Wed, Feb 14, 2018 at 11:53 PM, Timothy Arceri <tarc...@itsqueeze.com> wrote: > > > On 15/02/18 04:39, Marek Olšák wrote: >> >> Reviewed-by: Marek Olšák <marek.ol...@amd.com> >> >> Marek >> >> On Wed, Feb 14, 2018 at 7:29 AM, Timothy Arceri <tarc...@itsqueeze.com> >> wrote: >>> >>> Fixes glsl-1.30/execution/isinf-and-isnan* piglit tests for >>> radeonsi and should fix SPIRV errors when LLVM optimises away >>> the workarounds in vtn_handle_alu() for handling ordered >>> comparisons. >>> >>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104905 >>> --- >>> src/amd/common/ac_nir_to_llvm.c | 8 ++++---- >>> 1 file changed, 4 insertions(+), 4 deletions(-) >>> >>> diff --git a/src/amd/common/ac_nir_to_llvm.c >>> b/src/amd/common/ac_nir_to_llvm.c >>> index a0c5680205..e81f86bb08 100644 >>> --- a/src/amd/common/ac_nir_to_llvm.c >>> +++ b/src/amd/common/ac_nir_to_llvm.c >>> @@ -1792,16 +1792,16 @@ static void visit_alu(struct ac_nir_context *ctx, >>> const nir_alu_instr *instr) >>> result = emit_int_cmp(&ctx->ac, LLVMIntUGE, src[0], >>> src[1]); >>> break; >>> case nir_op_feq: >>> - result = emit_float_cmp(&ctx->ac, LLVMRealUEQ, src[0], >>> src[1]); >>> + result = emit_float_cmp(&ctx->ac, LLVMRealOEQ, src[0], >>> src[1]); >>> break; >>> case nir_op_fne: >>> - result = emit_float_cmp(&ctx->ac, LLVMRealUNE, src[0], >>> src[1]); >>> + result = emit_float_cmp(&ctx->ac, LLVMRealONE, src[0], >>> src[1]); > > > It seems we need to leave this one as is to avoid regressions. This is also > what radeonsi does.
So, the thing you have to understand is that in LLVM unordered comparisons are precisely the inverse of the ordered comparisons. That is, (a <=(ordered) b) == !(a >(unordered b), (a ==(ordered) b) == !(a !=(unordered) b), and so on. C defines that all comparsions are ordered except !=, so that (a == b) == !(a != b) always holds true. Most hardware follows this convention -- offhand, x86 SSE is the only ISA I know of with separate ordered and unordered comparisons, and LLVM appears to have copied the distinction from them, but no one else has both. I'm not even sure if it's in the IEEE spec. GLSL follows the C convention, so glsl_to_nir just uses nir_op_fne to mean unordered not-equal. spirv_to_nir generates some extra instructions, which then get stripped away later... sigh. I think the right way to untangle this mess is to define that the NIR opcodes should always match the C convention. The separate ordered and unordered opcodes are unnecesary, since one is just the logical negation of the other, and LLVM was a little overzealous -- I'm sure they would get rid of the distinction if they had the chance -- and then they were blindly copied to SPIR-V. spirv_to_nir should just negate the result if necessary rather than emitting the extra code to handle NaN, and ac should use ordered except for not-equals. > > >>> break; >>> case nir_op_flt: >>> - result = emit_float_cmp(&ctx->ac, LLVMRealULT, src[0], >>> src[1]); >>> + result = emit_float_cmp(&ctx->ac, LLVMRealOLT, src[0], >>> src[1]); >>> break; >>> case nir_op_fge: >>> - result = emit_float_cmp(&ctx->ac, LLVMRealUGE, src[0], >>> src[1]); >>> + result = emit_float_cmp(&ctx->ac, LLVMRealOGE, src[0], >>> src[1]); >>> break; >>> case nir_op_ufeq: >>> result = emit_float_cmp(&ctx->ac, LLVMRealUEQ, src[0], >>> src[1]); >>> -- >>> 2.14.3 >>> >>> _______________________________________________ >>> mesa-dev mailing list >>> mesa-dev@lists.freedesktop.org >>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev