Merge pull request #5098 from laytan/fix-nan-comparisons

fix variable NaN comparisons
This commit is contained in:
gingerBill
2025-05-02 13:00:42 +01:00
committed by GitHub
3 changed files with 47 additions and 3 deletions
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -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;
@@ -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)
}