Skip to content

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information