[GHC] #10334: __ctzdi2/si2/__clzdi2/si2 unknown symbols in ghc-prim on non-shared libs platform
#10334: __ctzdi2/si2/__clzdi2/si2 unknown symbols in ghc-prim on non-shared libs platform -------------------------------------+------------------------------------- Reporter: kgardas | Owner: ekmett Type: bug | Status: new Priority: normal | Milestone: Component: Core | Version: 7.11 Libraries | Operating System: Unknown/Multiple Keywords: | Type of failure: None/Unknown Architecture: | Blocked By: Unknown/Multiple | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Hello, ghc-prim is using GCC's {{{__builtin_ctz(ll)/clz(ll)}}} functions to implement functionality to count leading or trailing zeros in provided integer type variable. The problem with those GCC's builtins is that on platform which does not implement either of the operation in ISA, such function call can't be replaced by simple ISN, but needs to be replaced by the call to the libgcc library which then implements the missing operation in generic C. In ghc- prim you can already see a workaround for missing *ll functions on i386. The problem is that generic SPARC (v9) does not provide ISNs in its ISA to implement those builtins effectively so any call to builtins above is replaced by the call to the libgcc. The inserted functions calls are {{{__ctzsi2/__ctzdi2/__clzsi2/__clzdi2}}} in this case. Unfortunately this makes a lot of GHCi testcases (if not all!) failing with the error: {{{ ghc-stage2: /home/karel/src/obj-ghc-sparc-reg_ncg- head-2015-04-07-debug/libraries/ghc-prim/dist-install/build/HSghc- prim-0.4.0.0-8TmvWUcS1U1IKHT0levwg3.o: unknown symbol `__clzdi2' ghc-stage2: unable to load package `ghc-prim-0.4.0.0' }}} Please note, this happens only on platforms which does not support shared libs for GHC. On platforms with GHC shared libs support, ghc-prim is shared library which is correctly linked against the libgcc shared library and such error does not happen. (example Solaris/i386). Unfortunately we can't link ghc-prim*.o with libgcc -- it does effectively nothing so there are two solution for this issue IMHO: 1) on problematic platform implement hs_ctz*/hs_clz* functions in pure C without usage of GNU C builtin functions. or 2) enforce linking of shared libgcc with produced application binary. Such linking needs to be enforced with -shared-libgcc parameter passed to the GNU C in linking step and also by usage of either builtins in the application C code (not library code). My experimental code below shows that this is possible (tested on Solaris/SPARC). Please note that by default on static platform, the static version of libgcc is used and this does not help here. Also please note that usage of builtin in let say RTS library does not help either. I've tested RtsMain.c. The reason is the same like why it's not working in ghc-prim. We can't link *.o or *.a against shared libgcc. {{{ diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs index c86667c..7c615d1 100644 --- a/compiler/main/DriverPipeline.hs +++ b/compiler/main/DriverPipeline.hs @@ -1651,6 +1651,7 @@ mkExtraObjToLinkIntoBinary dflags = do | gopt Opt_NoHsMain dflags = Outputable.empty | otherwise = vcat [ text "#include \"Rts.h\"", + text "#include <stdio.h>", text "extern StgClosure ZCMain_main_closure;", text "int main(int argc, char *argv[])", char '{', @@ -1662,6 +1663,10 @@ mkExtraObjToLinkIntoBinary dflags = do Just opts -> ptext (sLit " __conf.rts_opts= ") <> text (show opts) <> semi, text " __conf.rts_hs_main = rtsTrue;", + text " printf(\"ctz(argc): %d\\n\", __builtin_ctz(argc));", text " return hs_main(argc,argv,&ZCMain_main_closure,__conf);", char '}', char '\n' -- final newline, to keep gcc happy }}} of course this is just a proof of concept. For real code we would need some place to save the result of the called builtin to prevent GCC from removing the call as an unused value. I guess one added value in {{{__conf}}} just for this case should do the job here. I'm free to implement either of those two solutions or even completely different one, I just need to know your preference in this case. BTW: I'm ccing people from #9340 which looks really related to this issue. If you are not interested in this issue discussion, please un-cc yourself. Thanks! Karel PS: as this is IMHO general issue, I'm not setting SPARC/Solaris as Architecture/OS here... -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10334> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#10334: __ctzdi2/si2/__clzdi2/si2 unknown symbols in ghc-prim on non-shared libs platform -------------------------------------+------------------------------------- Reporter: kgardas | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Core Libraries | Version: 7.11 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by ekmett): * owner: ekmett => Comment: I'd encourage a fix, but I'm going to relinquish control of the ticket as it is more about how the linker/RTS works than the structure of the core libraries per se. If we need a good `ctz` and `clz`, I have implementations in various libraries we could adapt back into C/C-- and contribute from various projects. e.g. https://github.com/ekmett/bits/blob/ded1403737ce26e819c1d1c1facb41a9e776eb46... gives usable De Bruijn multiplication tables and https://github.com/ekmett/bits/blob/ded1403737ce26e819c1d1c1facb41a9e776eb46... provides a working portable `ctz`. Right below it is a decent `clz` that uses our existing `popCount` primitive. You may need to adjust the answers by 1 to comply with the `__builtin_clz` and `__builtin_ctz` primitives, I forget. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10334#comment:1> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#10334: __ctzdi2/si2/__clzdi2/si2 unknown symbols in ghc-prim on non-shared libs platform -------------------------------------+------------------------------------- Reporter: kgardas | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Core Libraries | Version: 7.11 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by kgardas): Edward, thanks a lot for your reference to haskell/C ctz/clz implementations. This is good to have for reference and also for the comparison. I'm attaching my hack to enforce -shared-libgcc linking so both approaches may be compared and the best chosen. Thanks, Karel -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10334#comment:2> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#10334: __ctzdi2/si2/__clzdi2/si2 unknown symbols in ghc-prim on non-shared libs platform -------------------------------------+------------------------------------- Reporter: kgardas | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Core Libraries | Version: 7.11 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by kgardas): * cc: kgardas (added) -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10334#comment:3> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#10334: __ctzdi2/si2/__clzdi2/si2 unknown symbols in ghc-prim on non-shared libs platform -------------------------------------+------------------------------------- Reporter: kgardas | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: Core Libraries | Version: 7.11 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by thomie): * cc: ekmett (added) * status: new => patch -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10334#comment:4> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#10334: __ctzdi2/si2/__clzdi2/si2 unknown symbols in ghc-prim on non-shared libs platform -------------------------------------+------------------------------------- Reporter: kgardas | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: Core Libraries | Version: 7.11 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by slyfox): * cc: slyfox (added) Comment: changeset:a93ab43ab5f40cadbedea2f6342b93c245e91434 should add shared library support for sparc thus should be slightly less painful for you. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10334#comment:5> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#10334: __ctzdi2/si2/__clzdi2/si2 unknown symbols in ghc-prim on non-shared libs platform -------------------------------------+------------------------------------- Reporter: kgardas | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: Core Libraries | Version: 7.11 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by kgardas): Replying to [comment:5 slyfox]:
changeset:a93ab43ab5f40cadbedea2f6342b93c245e91434 should add shared library support for sparc thus should be slightly less painful for you.
yes, but I need static libs first since about twice per year I'm still trying to fix SPARC NCG. And this should be first done for static libs. So this is the reason I push static libs... -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10334#comment:6> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (1)
-
GHC