clr 2026-07-14

Thanks. I'll take a look.

I answered the question over there. Here's the gist: It's a bug that only occurs when calling a one of <, <=, >, >= on two arguments in a context where both arguments have known types and the types are both double, and the context of the call is the test in a conditional. So only when we have something like (if (<= ^double x ^double y) ... ). And the generated code gives an incorrect answer only when one or both of the arguments is NaN.

👀 1

ah yeah, that makes sense. comparing NaNs is fraught, glad you caught it

The problem was an incorrect negation. Conditionals are coded as

test
if false goto A:
then-clause
goto B:
A: 
else-clause
B:
...
For integers, it okay to change
cle       # Compare <=
brfalse   # Branch if false
with
bgt   # Branch if >
But not for doubles, because (not <= ) is not the same as (>) when there is a NaN in the house. I had used the same code for both longs and doubles. Wrong.

👍 1

In fact, I have to disable two of the intrinsic replacements because though I have opcodes cgt and clt, there is no cge and no cle. The C# compiler deals with this lack by reordering the sense of the test and whether you branch to the 'then' or to the 'else'. The very simple intrinsics rewriting mechanism used here is not capable of switching like this.