Opened 6 years ago

Last modified 5 years ago

#8311 new feature request

suboptimal code generated for even :: Int -> Bool by NCG (x86, x86_64)

Reported by: rwbarton Owned by:
Priority: normal Milestone:
Component: Compiler (NCG) Version: 7.7
Keywords: Cc: simonmar, carter.schonwald@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime performance bug Test Case:
Blocked By: Blocking:
Related Tickets: #5615 Differential Rev(s):
Wiki Page:

Description

This appears to be the x86 assembly for a specialization for even :: Int -> Bool that's produced by a SPECIALISE pragma for (^) :: Int -> Int -> Int in GHC.Real. The relevant bit is offsets 0x2c through 0x3b.

0000000c <base_GHCziReal_evenzuzdseven1_info>:
   c:   8b 45 00                mov    0x0(%ebp),%eax
   f:   c7 45 00 2c 00 00 00    movl   $0x2c,0x0(%ebp)
                        12: R_386_32    .text
  16:   89 c6                   mov    %eax,%esi
  18:   f7 c6 03 00 00 00       test   $0x3,%esi
  1e:   75 0c                   jne    2c <c8gO_info>
  20:   ff 26                   jmp    *(%esi)
  22:   66 90                   xchg   %ax,%ax
  24:   00 00                   add    %al,(%eax)
  26:   00 00                   add    %al,(%eax)
  28:   20 00                   and    %al,(%eax)
        ...

0000002c <c8gO_info>:
  2c:   b8 02 00 00 00          mov    $0x2,%eax
  31:   89 c1                   mov    %eax,%ecx
  33:   8b 46 03                mov    0x3(%esi),%eax
  36:   99                      cltd   
  37:   f7 f9                   idiv   %ecx
  39:   85 d2                   test   %edx,%edx
  3b:   75 0b                   jne    48 <c8gO_info+0x1c>
  3d:   be 02 00 00 00          mov    $0x2,%esi
                        3e: R_386_32    ghczmprim_GHCziTypes_True_closure
  42:   83 c5 04                add    $0x4,%ebp
  45:   ff 65 00                jmp    *0x0(%ebp)
  48:   be 01 00 00 00          mov    $0x1,%esi
                        49: R_386_32    ghczmprim_GHCziTypes_False_closure
  4d:   83 c5 04                add    $0x4,%ebp
  50:   ff 65 00                jmp    *0x0(%ebp)

It would be much better to do a simple testb $0x1,0x3(%esi) in place of the first six instructions of c8gO_info.

The NCG generates similar code on x86_64.

Change History (6)

comment:1 Changed 6 years ago by simonpj

Cc: simonmar added

comment:2 Changed 6 years ago by simonpj

Could you give us the source Haskell code, and how you compiled it, that gives this sub-optimal result? Thanks!

Simon

comment:3 Changed 6 years ago by rwbarton

The source of that code is in GHC.Real in base, but for reproducing, use this:

module Even where
myEven :: Int -> Bool
myEven n = n `rem` 2 == 0

compiled with ghc -O2 -o Even.o -c Even.hs.

The LLVM backend (ghc -O2 -fllvm -o Even.o -c Even.hs) does produce a testb $0x1,0x3(%esi) instruction.

comment:4 Changed 5 years ago by carter

Cc: carter.schonwald@… added

comment:5 Changed 5 years ago by rwbarton

comment:6 Changed 5 years ago by thomie

Type of failure: None/UnknownRuntime performance bug

#9188 was closed as a duplicate of #5615.

Note: See TracTickets for help on using tickets.