Skip to content

silly assembly for comparing Doubles

A function like f x = if x > 0.0 then ... else ... compiles to the assembly

        movsd 7(%rbx),%xmm0
        xorpd %xmm1,%xmm1
        ucomisd %xmm1,%xmm0
        seta %al
        movzbl %al,%eax
        cmpq $1,%rax
        jb _c1tb

This seta/movzbl/cmpq/jb is bad, we can just generate ja (and 7.10 did).

The cause is that the code generator produces Cmm like

           switch [0 .. 1] %MO_F_Gt_W64(_s1sv::F64, 0.0 :: W64)::I64 {
               case 0 : goto c1tb;
               case 1 : goto c1tc;
           }

which turns into

      if (%MO_F_Gt_W64(_s1sv::F64,
                       0.0 :: W64) < 1) goto c1tb; else goto c1tc;

and then GHC is stuck. It knows how to turn condition >= 1 into condition, and it knows how to turn condition < 1 into a negated version of condition when possible, but there is no negated version of MO_F_Gt_W64 (it's not MO_F_Le_W64 because of NaNs and signed zeros). It doesn't know how to turn a negated conditional into a conditional with the branches swapped because it doesn't look at that much at once.

Presumably more fallout from #10137 (closed), and maybe can be fixed simultaneously with #10677 (closed).

Trac metadata
Trac field Value
Version 7.11
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler (CodeGen)
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information