Opened 2 years ago

Closed 2 years ago

#7575 closed bug (fixed)

LLVM backend does not properly widen certain literal types in call expressions

Reported by: thoughtpolice Owned by:
Priority: normal Milestone:
Component: Compiler (LLVM) Version: 7.7
Keywords: llvm, codegen Cc: dterei, simonmar, mad.one@…, bgamari@…, nathan.huesken@…
Operating System: Linux Architecture: arm
Type of failure: Compile-time crash Test Case:
Blocked By: Blocking: #7589
Related Tickets: #7571, #7574 Differential Revisions:

Description

Related to #7571 and #7574, while compiling stage2 with stage1 GHC HEAD on my ODROID, my build fails in libraries/base/GHC/Word.hs with:

linaro@linaro-ubuntu-desktop ~/code/ghc
 % "inplace/bin/ghc-stage1" -static  -H64m -O0 -fasm    -package-name base-4.7.0.0 -hide-all-packages -i -ilibraries/base/. -ilibrarie-Ilibraries/base/dist-install/build -Ilibraries/base/dist-install/build/autogen -Ilibraries/base/include   -optP-DOPTIMISE_INTEGER_GCDl_macros.h -package ghc-prim-0.3.1.0 -package integer-gmp-0.5.1.0 -package rts-1.0  -package-name base -XHaskell98 -XCPP -O -fasm  -no -hidir libraries/base/dist-install/build -stubdir libraries/base/dist-install/build -hisuf hi -osuf  o -hcsuf hc -c libraries/base/./files -tmpdir tmpdir                                                                                                                  
 
when making flags consistent: Warning:
    No native code generator, so using LLVM
You are using a new version of LLVM that hasn't been tested yet!
We will try though...
/home/linaro/bin/opt: tmpdir/ghc12774_0/ghc12774_0.ll:26765:62: error: argument is not of expected type 'i64'
  %lnhvj = call ccc i32 (i64,i64)* @hs_eqWord64( i64 %lnhvi, i32 0 ) nounwind

The declaration of hs_eqWord64 is:

declare  ccc i32 @hs_eqWord64(i64, i64) align 4

And we get:

%lnhvj = call ccc i32 (i64,i64)* @hs_eqWord64( i64 %lnhvi, i32 0 ) nounwind

inside of c8Aq_info, which has a tail call from the symbol base_GHCziWord_zdfNumWord64zuzdcsignum_info or base_GHC.Word_$fNumWord64_$csignum_info - this would seem to be some specialized instance of the case:

instance Num Word64 where
    ...
    signum 0               = 0
    signum _               = 1

... I think. This seems like a fairly simple fix similar to the others, but I'm filing it for now.

Change History (13)

comment:1 Changed 2 years ago by thoughtpolice

  • Cc mad.one@… added
  • Component changed from Compiler to Compiler (LLVM)
  • Keywords llvm codegen added
  • Type of failure changed from None/Unknown to Building GHC failed
  • Version changed from 7.6.1 to 7.7

Word of note. I think I have a test for this:

{-# LANGUAGE MagicHash, UnliftedFFITypes #-}
module Main where
import GHC.Prim
import GHC.Word
import System.Environment (getArgs)

foreign import ccall unsafe "hs_eqWord64" dummy_eqWord64# :: Word64# -> Word64# -> Bool

check :: Word64 -> Word64 -> Bool
check (W64# x#) (W64# y#) = dummy_eqWord64# x# y#

main :: IO ()
main = do
  a <- (read . head) `fmap` getArgs
  print $ check a 0 

At -O2, with GHC 7.4.1 on ARM, this dumps code like:

...
%ln2EJ = call ccc i32 (i64,i64)* @hs_eqWord64( i64 %ln2EI, i64 0 ) nounwind
...

So it seems like a regression. I'm rebuilding on my ODROID at the moment and will run this test with the stage1 compiler and see what happens. Intuition tells me this should trigger it based on the code I saw under base.

Also note that this will only affect 32 bit builds obviously. On 64bit machines, Word64 is native and does not shell out to long long and ghc-prim for Word64.

comment:2 Changed 2 years ago by thoughtpolice

  • Type of failure changed from Building GHC failed to Compile-time crash

comment:3 Changed 2 years ago by thoughtpolice

Correction: this test correctly triggers the bug:

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MagicHash, UnliftedFFITypes #-}
module T7575 where
import GHC.Prim
import GHC.Word
import GHC.Types

foreign import ccall unsafe "hs_eqWord64" dummy_eqWord64# :: Word64# -> Word64# -> Bool

check :: Word64 -> Word64 -> Bool
check (W64# x#) (W64# y#) = dummy_eqWord64# x# y#

check2 :: Word64 -> Bool
check2 x = check x 0

Testing vs 7.4.1:

 $ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.4.1
 $ ghc -c -O2 -fforce-recomp T7575.hs
 $ ~/code/ghc/inplace/bin/ghc-stage1 --version                 
The Glorious Glasgow Haskell Compilation System, version 7.7.20130113
 $ ~/code/ghc/inplace/bin/ghc-stage1 -c -O2 -fforce-recomp T7575.hs
You are using a new version of LLVM that hasn't been tested yet!
We will try though...
/home/linaro/bin/opt: /tmp/ghc26188_0/ghc26188_0.ll:594:60: error: argument is not of expected type 'i64'
  %lnxh = call ccc i32 (i64,i64)* @hs_eqWord64( i64 %lnxg, i32 0 ) nounwind
                                                           ^
 $ ~/code/ghc/inplace/bin/ghc-stage1 -c -O2 -fforce-recomp T7575.hs -pgmlo opt-3.0 -pgmlc llc-3.0
opt-3.0: /tmp/ghc26199_0/ghc26199_0.ll:594:60: error: argument is not of expected type 'i64'
  %lnxh = call ccc i32 (i64,i64)* @hs_eqWord64( i64 %lnxg, i32 0 ) nounwind
                                                           ^
 $ 

So this is definitely a compiler regression in the backend somewhere.

comment:4 Changed 2 years ago by thoughtpolice

  • Architecture changed from Unknown/Multiple to arm
  • Operating System changed from Unknown/Multiple to Linux

comment:5 Changed 2 years ago by dterei

  • Blocking 7589 added

comment:6 Changed 2 years ago by dterei

  • Blocked By 7590 added

comment:7 Changed 2 years ago by bgamari

  • Cc bgamari@… added

comment:8 Changed 2 years ago by RudolfVonKrugstein

  • Cc nathan.huesken@… added

comment:9 Changed 2 years ago by RudolfVonKrugstein

I discovered that when adding the signature

instance Num Word64 where
    (...)
    signum :: Word64 -> Word64
    (...)

and of course adding

{-# LANGUAGE InstanceSigs #-}

To Word.hs, it builds.

comment:10 Changed 2 years ago by dterei

  • Blocked By 7590 removed
  • Blocking 7590 added

comment:11 Changed 2 years ago by dterei

  • Blocking 7590 removed

comment:12 Changed 2 years ago by davidterei@…

commit 1a703068117255592fb8d9d8d47a5d54640208d0

Author: David Terei <[email protected]>
Date:   Wed Jan 23 00:38:43 2013 -0800

    Fix our handling of literals and types in LLVM (#7575).
    
    This bug was introduced in the recent fix for #7571, that extended some
    existing infastructure in the LLVM backend that handled the conflict
    between LLVM's return type from comparison operations (i1) and what GHC
    expects (word). By extending it to handle literals though, we forced all
    literals to be i1 or word, breaking other code.
    
    This patch resolves this breakage and handles #7571 still, cleaning up
    the code for both a little. The overall approach is not ideal but
    changing that is left for the future.

 compiler/llvmGen/LlvmCodeGen/CodeGen.hs |   64 ++++++++++++++-----------------
 1 files changed, 29 insertions(+), 35 deletions(-)

comment:13 Changed 2 years ago by dterei

  • Resolution set to fixed
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.