[GHC] #10750: silly assembly for comparing Doubles

#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

#10750: silly assembly for comparing Doubles -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.11 (CodeGen) | Resolution: | 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: -------------------------------------+------------------------------------- Comment (by nomeata): Can you provide me with a working example? For some reason, if I try to reproduce it, I get code that actually calls `GHC.Classes.>_info`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10750#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10750: silly assembly for comparing Doubles -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.11 (CodeGen) | Resolution: | 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: -------------------------------------+------------------------------------- Comment (by nomeata): Anyways, with #10677 resp. D1137, the conditions should be `condition != 0`, which will hopefully be turned into `condition`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10750#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10750: silly assembly for comparing Doubles -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.11 (CodeGen) | Resolution: | 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: -------------------------------------+------------------------------------- Comment (by rwbarton): Replying to [comment:2 nomeata]:
Anyways, with #10677 resp. D1137, the conditions should be `condition != 0`, which will hopefully be turned into `condition`.
Yes, I believe that case is handled already. Here is an example (build with `-O`): {{{ f :: Double -> Double f x = if x > 0 then 1 else 2 }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10750#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10750: silly assembly for comparing Doubles -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.11 (CodeGen) | Resolution: | 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: -------------------------------------+------------------------------------- Comment (by nomeata): Weird. With your example, compiled with `./inplace/bin/ghc-stage2 -fforce-recomp -O -ddump-asm T10677.hs`, I get assembly like this: {{{ ==================== Asm code ==================== .text .align 8 .long S1vB_srt-(Zero.f_info)+0 .long 0 .quad 4294967301 .quad 0 .quad 12884901903 .globl Zero.f_info .type Zero.f_info, @object Zero.f_info: _c1vs: leaq -32(%rbp),%rax cmpq %r15,%rax jb _c1vt _c1vu: movq $block_c1vm_info,-8(%rbp) movq %r14,%rax movl $GHC.Classes.$fOrdDouble_closure,%r14d movq $stg_ap_pp_info,-32(%rbp) movq %rax,-24(%rbp) movq $Zero.f3_closure+1,-16(%rbp) addq $-32,%rbp jmp GHC.Classes.>_info .text .align 8 .quad 0 .quad 32 block_c1vm_info: _c1vm: andl $7,%ebx cmpq $1,%rbx jne _c1vq _c1vp: movl $Zero.f2_closure+1,%ebx addq $8,%rbp jmp *(%rbp) _c1vq: movl $Zero.f1_closure+1,%ebx addq $8,%rbp jmp *(%rbp) _c1vt: movl $Zero.f_closure,%ebx jmp *-8(%r13) .size Zero.f_info, .-Zero.f_info }}} so unless I am reading this wrong, it did not inline specialize or `>`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10750#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10750: silly assembly for comparing Doubles -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.11 (CodeGen) | Resolution: | 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: -------------------------------------+------------------------------------- Comment (by rwbarton): Maybe you built GHC's libraries at too low an optimization level? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10750#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10750: silly assembly for comparing Doubles -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.11 (CodeGen) | Resolution: fixed | 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: -------------------------------------+------------------------------------- Changes (by nomeata): * status: new => closed * resolution: => fixed Comment:
Maybe you built GHC's libraries at too low an optimization level?
Heh, that’s it. I switched to `quickest` earlier to do a bisect, and did not switch back :-) Anyways, this produces a `ja` command now: {{{ _c36F: movsd 7(%rbx),%xmm0 xorpd %xmm1,%xmm1 ucomisd %xmm1,%xmm0 ja _c36U }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10750#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC