
#10750: silly assembly for comparing Doubles -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.11 (CodeGen) | Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: Runtime Unknown/Multiple | performance bug Test Case: | Blocked By: Blocking: | Related Tickets: #10137, #10677 Differential Revisions: | -------------------------------------+------------------------------------- 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, and maybe can be fixed simultaneously with #10677. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10750 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler