__ctzdi2/si2/__clzdi2/si2 unknown symbols in ghc-prim on non-shared libs platform
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:
- on problematic platform implement hs_ctz*/hs_clz* functions in pure C without usage of GNU C builtin functions.
or
- 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 (closed) 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...
Trac metadata
Trac field | Value |
---|---|
Version | 7.11 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Core Libraries |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | core-libraries-committee@haskell.org, hvr, simonmar, thoughtpolice |
Operating system | |
Architecture |