fix(backend): float != must be UNORDERED so nan != nan is true [F0.9]
emitCmpNe lowered float `!=` to `LLVMRealONE` (ordered not-equal), which is false when either operand is NaN. That made `nan != nan` false in native code — breaking the canonical `x != x` NaN test, making `!=` non-complementary with `==` for NaN, and disagreeing with the interpreter. Change the float predicate to `LLVMRealUNE` (unordered not-equal): true if either operand is NaN OR they are unequal. For all non-NaN operands `UNE` ≡ `ONE`, so only NaN-involving comparisons change (toward correct). The integer predicate (`LLVMIntNE`) and `emitCmpEq` (`OEQ`) are unchanged, so `nan == nan` stays false and `!=` is now the exact complement of `==`. - Regression: examples/0150-types-float-ne-unordered-nan.sx (fails before, passes after; also pins #run/comptime == runtime agreement). - specs.md: documents float comparison / NaN semantics (Operators). - Resolves issue 0091 (issues/0091-float-ne-ordered-nan.md).
This commit is contained in:
@@ -274,7 +274,10 @@ pub const Ops = struct {
|
||||
}
|
||||
|
||||
pub fn emitCmpNe(self: Ops, instruction: *const Inst, bin: BinOp) void {
|
||||
self.e.emitCmp(bin, instruction.ty, c.LLVMIntNE, c.LLVMRealONE);
|
||||
// Float `!=` is UNORDERED not-equal: true if either operand is NaN, so
|
||||
// `nan != nan` is true (IEEE 754 / the `x != x` NaN idiom) and `!=` stays
|
||||
// the exact complement of `==` (OEQ). UNE == ONE for all non-NaN operands.
|
||||
self.e.emitCmp(bin, instruction.ty, c.LLVMIntNE, c.LLVMRealUNE);
|
||||
}
|
||||
|
||||
pub fn emitCmpLt(self: Ops, instruction: *const Inst, bin: BinOp) void {
|
||||
|
||||
Reference in New Issue
Block a user