[GHC] #15094: unknown symbol `___divmoddi4' error with clock on 32-bit windows
GHC
ghc-devs at haskell.org
Tue May 1 20:58:27 UTC 2018
#15094: unknown symbol `___divmoddi4' error with clock on 32-bit windows
---------------------------------+------------------------------
Reporter: simonmic | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone: 8.6.1
Component: Compiler | Version: 8.4.2
Resolution: | Keywords:
Operating System: Windows | Architecture: x86
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
---------------------------------+------------------------------
Comment (by Phyx-):
It does. It's right there in
{{{
void hs_clock_win32_gettime_monotonic(long long* t)
{
LARGE_INTEGER time;
LARGE_INTEGER frequency;
QueryPerformanceCounter(&time);
QueryPerformanceFrequency(&frequency);
// seconds
t[0] = time.QuadPart / frequency.QuadPart;
// nanos =
t[1] = ticks_to_nanos(time.QuadPart % frequency.QuadPart,
frequency.QuadPart);
}
}}}
At the optimization level `clock` is requesting, namely `-O3` GCC will do
multiplication widening optimizations. This optimize `time.QuadPart /
frequency.QuadPart` and `time.QuadPart % frequency.QuadPart` into a single
`divmod`.
It even says so
{{{
Pass statistics of "widening_mul": ----------------
divmod calls inserted: 1
hs_clock_win32_gettime_monotonic (long long intD.8 * tD.60113)
{
# PT = nonlocal null
long long intD.8 * t_9(D) = tD.60113;
union LARGE_INTEGERD.2224 frequencyD.60117;
union LARGE_INTEGERD.2224 timeD.60116;
long long intD.8 _1;
long long intD.8 _2;
long long intD.8 _3;
long long intD.8 _4;
long long intD.8 _5;
doubleD.23 _11;
doubleD.23 _15;
doubleD.23 _16;
doubleD.23 _17;
long intD.3 _18;
__complex__ long long intD.8 divmod_tmp_19;
;; basic block 2, loop depth 0, count 0, freq 10000, maybe hot
;; prev block 0, next block 1, flags: (NEW, REACHABLE, VISITED)
;; pred: ENTRY [100.0%] (FALLTHRU,EXECUTABLE)
# .MEM_7 = VDEF <.MEM_6(D)>
# USE = nonlocal { D.60116 D.60117 } (escaped)
# CLB = nonlocal { D.60116 D.60117 } (escaped)
QueryPerformanceCounter at 4D.8347 (&timeD.60116);
# .MEM_8 = VDEF <.MEM_7>
# USE = nonlocal { D.60116 D.60117 } (escaped)
# CLB = nonlocal { D.60116 D.60117 } (escaped)
QueryPerformanceFrequency at 4D.8349 (&frequencyD.60117);
# VUSE <.MEM_8>
_1 = timeD.60116.QuadPartD.2223;
# VUSE <.MEM_8>
_2 = frequencyD.60117.QuadPartD.2223;
divmod_tmp_19 = DIVMOD (_1, _2); <---- divmod inserted here. - Phyx
_3 = REALPART_EXPR <divmod_tmp_19>;
# .MEM_10 = VDEF <.MEM_8>
*t_9(D) = _3;
# RANGE [-9223372036854775807, 9223372036854775807]
_4 = IMAGPART_EXPR <divmod_tmp_19>;
_11 = (doubleD.23) _4;
_15 = _11 * 1.0e+9;
_16 = (doubleD.23) _2;
_17 = _15 / _16;
_18 = (long intD.3) _17;
# RANGE [-2147483648, 2147483647]
_5 = (long long intD.8) _18;
# .MEM_12 = VDEF <.MEM_10>
MEM[(long long intD.8 *)t_9(D) + 8B] = _5;
# .MEM_13 = VDEF <.MEM_12>
timeD.60116 ={v} {CLOBBER};
# .MEM_14 = VDEF <.MEM_13>
frequencyD.60117 ={v} {CLOBBER};
# VUSE <.MEM_14>
return;
;; succ: EXIT [100.0%] (EXECUTABLE)
}
}}}
This entire file, always uses 64 bit types. You have no hardware support
for 64 bit `divmod`. The compiler is smart enough to know this and expands
the built-in `DIVMOD` to a library call which is expected to do the
operation. The implementation for the call is in `libgcc`.
The explicit purpose for `libgcc` is to handle these calls the compiler
emits to do the software emulation[1].
{{{
GCC provides a low-level runtime library, libgcc.a or libgcc_s.so.1 on
some platforms. GCC
generates calls to routines in this library automatically, whenever it
needs to perform some
operation that is too complicated to emit inline code for.
Most of the routines in libgcc handle arithmetic operations that the
target processor cannot
perform directly. This includes integer multiply and divide on some
machines, and all
floating-point and fixed-point operations on other machines. libgcc also
includes routines
for exception handling, and a handful of miscellaneous operations.
}}}
So yes, using a complex operation that the architecture has no support for
requires explicit software emulation, and thus requires compiling against
`libgcc`. Or turning off the optimization. Possibly for that function
alone using an attribute. Either way, this is not a GHC bug.
[1] https://gcc.gnu.org/onlinedocs/gccint/Libgcc.html
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15094#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list