silly assembly for comparing the result of comparisons that return Int# against 0#
Consider the module
{-# LANGUAGE MagicHash #-}
module Min where
import GHC.Exts
fgood :: Int# -> Int# -> Int
fgood x# y# = case isTrue# (x# <# y#) of
False -> I# y#
True -> I# x#
fbad :: Int# -> Int# -> Int
fbad x# y# = case x# <# y# of
0# -> I# y#
_ -> I# x#
The code for fgood
looks fine:
0000000000000130 <Min_fgood_info>:
130: 49 83 c4 10 add $0x10,%r12
134: 4d 3b a5 58 03 00 00 cmp 0x358(%r13),%r12
13b: 77 1a ja 157 <Min_fgood_info+0x27>
13d: 49 39 f6 cmp %rsi,%r14
140: 7c 29 jl 16b <Min_fgood_info+0x3b>
142: 49 c7 44 24 f8 00 00 movq $0x0,-0x8(%r12)
149: 00 00
147: R_X86_64_32S ghczmprim_GHCziTypes_Izh_con_info
14b: 49 89 34 24 mov %rsi,(%r12)
14f: 49 8d 5c 24 f9 lea -0x7(%r12),%rbx
154: ff 65 00 jmpq *0x0(%rbp)
157: 49 c7 85 88 03 00 00 movq $0x10,0x388(%r13)
15e: 10 00 00 00
162: bb 00 00 00 00 mov $0x0,%ebx
163: R_X86_64_32 Min_fgood_closure
167: 41 ff 65 f8 jmpq *-0x8(%r13)
16b: 49 c7 44 24 f8 00 00 movq $0x0,-0x8(%r12)
172: 00 00
170: R_X86_64_32S ghczmprim_GHCziTypes_Izh_con_info
174: 4d 89 34 24 mov %r14,(%r12)
178: 49 8d 5c 24 f9 lea -0x7(%r12),%rbx
17d: ff 65 00 jmpq *0x0(%rbp)
But the code for fbad
has several problems:
0000000000000018 <Min_fbad_info>:
18: 48 8d 45 f0 lea -0x10(%rbp),%rax
1c: 4c 39 f8 cmp %r15,%rax
1f: 72 3a jb 5b <Min_fbad_info+0x43>
21: 48 89 f0 mov %rsi,%rax
24: 4c 89 f3 mov %r14,%rbx
27: 49 39 f6 cmp %rsi,%r14
2a: 0f 9c c1 setl %cl
2d: 0f b6 c9 movzbl %cl,%ecx
30: 48 85 c9 test %rcx,%rcx
33: 75 51 jne 86 <c1Sm_info+0xe>
35: 49 83 c4 10 add $0x10,%r12
39: 4d 3b a5 58 03 00 00 cmp 0x358(%r13),%r12
40: 0f 87 aa 00 00 00 ja f0 <c1Su_info+0x10>
46: 49 c7 44 24 f8 00 00 movq $0x0,-0x8(%r12)
4d: 00 00
4b: R_X86_64_32S ghczmprim_GHCziTypes_Izh_con_info
4f: 49 89 04 24 mov %rax,(%r12)
53: 49 8d 5c 24 f9 lea -0x7(%r12),%rbx
58: ff 65 00 jmpq *0x0(%rbp)
5b: bb 00 00 00 00 mov $0x0,%ebx
5c: R_X86_64_32 Min_fbad_closure
60: 41 ff 65 f8 jmpq *-0x8(%r13)
...
; c1Sm_info is the other case with its own heap check and GC entry code
; c1Su_info is another GC entry
; in total, another 160 bytes of code
For some reason, the heap checks were moved into the alternatives, which was not a good decision in this case. But the silly thing here is the cmp/setl/movzbl/test/jne
sequence in Min_fbad_info
, which should be replaced by a cmp/jl
as in Min_fgood_info
.
Same behavior in 7.8 and HEAD.
Trac metadata
Trac field | Value |
---|---|
Version | 7.10.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler (CodeGen) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |