// Float `!=` is UNORDERED not-equal: `nan != nan` is true (the canonical
// `x != x` NaN idiom), and `!=` is the exact complement of `==` for every
// float input — including NaN, where `nan == nan` is false (ordered `==`).
// For all non-NaN operands unordered `!=` matches ordered `!=`, so finite
// comparisons are unchanged. The native backend agrees with the interpreter.
//
// Regression (issue 0091): the LLVM backend lowered float `!=` to ordered
// not-equal (LLVMRealONE), so `nan != nan` was false in native code.
#import "modules/std.sx";

main :: () {
    // Produce a genuine NaN without any numeric-limit accessor: 0.0 / 0.0.
    z := 0.0;
    nan := z / z;

    // The fix: `!=` is unordered, `==` is ordered.
    print("nan != nan: {}\n", nan != nan);   // true
    print("nan == nan: {}\n", nan == nan);   // false
    print("nan != 1.0: {}\n", nan != 1.0);   // true
    print("nan == 1.0: {}\n", nan == 1.0);   // false

    // Complementarity holds for finite operands too (unchanged behavior).
    print("1.0 != 2.0: {}\n", 1.0 != 2.0);   // true
    print("1.0 != 1.0: {}\n", 1.0 != 1.0);   // false
    print("2.0 != 2.0: {}\n", 2.0 != 2.0);   // false

    // Native codegen converges with the comptime interpreter.
    print("comptime nan != nan: {}\n", #run nan_ne_nan());
}

nan_ne_nan :: () -> bool {
    z := 0.0;
    n := z / z;
    return n != n;
}
