[GHC] #10334: __ctzdi2/si2/__clzdi2/si2 unknown symbols in ghc-prim on non-shared libs platform
GHC
ghc-devs at haskell.org
Tue Apr 21 11:54:34 UTC 2015
#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
More information about the ghc-tickets
mailing list