From 396a18efce4ce25872d6d272ea3617fd1b62e76b Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Wed, 30 Apr 2025 20:03:17 +0200 Subject: [PATCH] fix variable NaN comparisons --- src/llvm_backend_expr.cpp | 4 +- src/llvm_backend_proc.cpp | 2 +- ...mparison.odin => test_nan_comparison.odin} | 44 +++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) rename tests/internal/{test_nan_constant_comparison.odin => test_nan_comparison.odin} (50%) diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index c5ea0ddac..d313d65a3 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2944,7 +2944,7 @@ gb_internal lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left case Token_GtEq: pred = LLVMRealOGE; break; case Token_Lt: pred = LLVMRealOLT; break; case Token_LtEq: pred = LLVMRealOLE; break; - case Token_NotEq: pred = LLVMRealONE; break; + case Token_NotEq: pred = LLVMRealUNE; break; } if (is_type_different_to_arch_endianness(left.type)) { @@ -2972,7 +2972,7 @@ gb_internal lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left LLVMRealPredicate pred = {}; switch (op_kind) { case Token_CmpEq: pred = LLVMRealOEQ; break; - case Token_NotEq: pred = LLVMRealONE; break; + case Token_NotEq: pred = LLVMRealUNE; break; } mask = LLVMBuildFCmp(p->builder, pred, left.value, right.value, ""); } else { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 3212abd9a..2c49d8c5c 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1442,7 +1442,7 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn LLVMRealPredicate pred = cast(LLVMRealPredicate)0; switch (builtin_id) { case BuiltinProc_simd_lanes_eq: pred = LLVMRealOEQ; break; - case BuiltinProc_simd_lanes_ne: pred = LLVMRealONE; break; + case BuiltinProc_simd_lanes_ne: pred = LLVMRealUNE; break; case BuiltinProc_simd_lanes_lt: pred = LLVMRealOLT; break; case BuiltinProc_simd_lanes_le: pred = LLVMRealOLE; break; case BuiltinProc_simd_lanes_gt: pred = LLVMRealOGT; break; diff --git a/tests/internal/test_nan_constant_comparison.odin b/tests/internal/test_nan_comparison.odin similarity index 50% rename from tests/internal/test_nan_constant_comparison.odin rename to tests/internal/test_nan_comparison.odin index 4eb3163a8..5740be477 100644 --- a/tests/internal/test_nan_constant_comparison.odin +++ b/tests/internal/test_nan_comparison.odin @@ -45,3 +45,47 @@ compare_constant_nans_f64 :: proc(t: ^testing.T) { testing.expect_value(t, NaN > NaN, false) testing.expect_value(t, NaN >= NaN, false) } + +@(test) +compare_variable_nans_f32 :: proc(t: ^testing.T) { + NaN := f32(0h7fc0_0000) + NaN2 := f32(0h7fc0_0001) + Inf := f32(0h7F80_0000) + Neg_Inf := f32(0hFF80_0000) + + testing.expect_value(t, NaN == NaN, false) + testing.expect_value(t, NaN == NaN2, false) + testing.expect_value(t, NaN != 0, true) + testing.expect_value(t, NaN != 5, true) + testing.expect_value(t, NaN != -5, true) + testing.expect_value(t, NaN != NaN, true) + testing.expect_value(t, NaN != NaN2, true) + testing.expect_value(t, NaN != Inf, true) + testing.expect_value(t, NaN != Neg_Inf, true) + testing.expect_value(t, NaN < NaN, false) + testing.expect_value(t, NaN <= NaN, false) + testing.expect_value(t, NaN > NaN, false) + testing.expect_value(t, NaN >= NaN, false) +} + +@(test) +compare_variable_nans_f64 :: proc(t: ^testing.T) { + NaN := f64(0h7fff_0000_0000_0000) + NaN2 := f64(0h7fff_0000_0000_0001) + Inf := f64(0h7FF0_0000_0000_0000) + Neg_Inf := f64(0hFFF0_0000_0000_0000) + + testing.expect_value(t, NaN == NaN, false) + testing.expect_value(t, NaN == NaN2, false) + testing.expect_value(t, NaN != 0, true) + testing.expect_value(t, NaN != 5, true) + testing.expect_value(t, NaN != -5, true) + testing.expect_value(t, NaN != NaN, true) + testing.expect_value(t, NaN != NaN2, true) + testing.expect_value(t, NaN != Inf, true) + testing.expect_value(t, NaN != Neg_Inf, true) + testing.expect_value(t, NaN < NaN, false) + testing.expect_value(t, NaN <= NaN, false) + testing.expect_value(t, NaN > NaN, false) + testing.expect_value(t, NaN >= NaN, false) +}