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:
9
specs.md
9
specs.md
@@ -85,6 +85,15 @@ GLSL;
|
||||
| `<<=` | left shift assign |
|
||||
| `>>=` | right shift assign |
|
||||
|
||||
**Float comparison and NaN.** Float `==` is *ordered* and `!=` is *unordered*,
|
||||
matching IEEE 754: `==` is false whenever either operand is NaN (`nan == x` is
|
||||
false for every `x`, including `nan`), and `!=` is true whenever either operand
|
||||
is NaN (`nan != x` is true for every `x`, including `nan`). So `!=` is the exact
|
||||
complement of `==` for all float inputs, and the canonical NaN test `x != x` is
|
||||
true exactly when `x` is NaN. The ordered relations `<`, `<=`, `>`, `>=` are all
|
||||
false when either operand is NaN. For all non-NaN operands these reduce to the
|
||||
ordinary comparisons. Native codegen and the comptime interpreter agree on this.
|
||||
|
||||
### Delimiters and Punctuation
|
||||
|
||||
| Token | Meaning |
|
||||
|
||||
Reference in New Issue
Block a user