fast-math cause undefined reference to `__pow_finite'
Asked Answered
M

2

11

on ubuntu 20.04, when I use clang-8 or clang-9 (clang version 9.0.1-12) to compile a simple code containing reference to libm, it will fail with error "undefined reference to __pow_finite"

#include <math.h>

int main()
{
    double x=1, y=1;
    x = pow(x,y);
}
clang-9 -lm test.c -ffast-math
/usr/bin/ld: /tmp/test-9b1a45.o: in function `main':
test.c:(.text+0x2a): undefined reference to `__pow_finite'

readelf -Ws /lib/x86_64-linux-gnu/libm.so.6| grep pow_finite
   626: 000000000002ed90    65 IFUNC   GLOBAL DEFAULT   17 __pow_finite@GLIBC_2.15

gcc is fine. Any idea what is wrong here?

c++ has the same problem:

#include <cmath>

int main()
{
    double x=1, y=1;
    x = pow(x,y);
}

edit

I actually used -lm, I just forgot to put in the text. If I do not add it, it is another error.

$ clang-9 test.c
/usr/bin/ld: /tmp/test-3389a6.o: in function `main':
test.c:(.text+0x25): undefined reference to `pow'

$ gcc test.c
/usr/bin/ld: /tmp/cc21n4wb.o: in function `main':
test.c:(.text+0x39): undefined reference to `pow'

F31 does not have this problem. godbolt is also fine. It must be something wrong on the system or specific subversion.

So far order does not matter, so I think it is not gcc will not properly include math.h:

clang-9 test.c -ffast-math -lm
/usr/bin/ld: /tmp/test-6dfc29.o: in function `main':
test.c:(.text+0x2a): undefined reference to `__pow_finite'

clang-9 -ffast-math test.c -lm
/usr/bin/ld: /tmp/test-6754bc.o: in function `main':
test.c:(.text+0x2a): undefined reference to `__pow_finite'

change the ld to collect2 has the same problem, so it should not be ld's issue.

clang-9 -v -fuse-ld=/usr/lib/gcc/x86_64-linux-gnu/9/collect2 test.c -ffast-math -lm

update

It seems related to libc update. There is no math-finite.h any more, so when -ffast-math generate __*finite it will fail. clang has to change its behaviour.

Midway answered 11/6, 2020 at 22:15 Comment(13)
I tried that already. Result is the same.Midway
Related, but not a duplicate (as this question seems to deal with GCC: https://mcmap.net/q/158712/-undefined-reference-to-pow-39-and-floor-39/10957435Emad
@NateEldredge unfortunately it is not the case.Midway
please noticed, if it is the order issue, it will say: undefined reference to 'pow' not __pow_infinateMidway
Okay, I can reproduce that.Wield
I agree that this looks like a bug with clang or glibc or Ubuntu 20.04's combination of them. It works with clang-10 if that is an acceptable alternative.Wield
unfortunately I have to stick to clang-9 so far.Midway
Try running the gcc command with -v. It should tell you what dirs it searches and what libm it used. Because you're using an explicit version (e.g. clang-9), you may be getting the wrong libm [for an older/newer version]. You could also run under strace. You may need -L and/or -rpath options to force linkage to the correct [version specific] libs. You can run nm or readelf/objdump on the various libm files to see which define the missing __pow_infinite symbolThomasinethomason
@CraigEstey not the case. It turns out clang-9 does not work with new glibc which drops the math-finite.hMidway
@Wang: Would you like to post an answer?Wield
@Midway I've faced this issue too. Any solution so far?Roundel
@Roundel as I described it is a compiler bug. It was fixed in later version. Just pick some up-to-date clang version. That's it.Midway
@Midway Yes, now I understand. I've switched to Clang 10.0.0. Thanks.Roundel
M
1

TL;TR: This was a bug in clang which fix in clang-10. If anyone has the same problem please either use the latest GCC or Clang version or set -fno-finite-math-only.

The root cause of this is clang wrongly called some non-API functions in libm:

They were only ever an ABI (selected by use of -ffinite-math-only or options implying it, which resulted in the headers using "asm" to redirect calls to some libm functions), not an API. The change means that ABI has turned into compat symbols (only available for existing binaries, not for anything newly linked, not included in static libm at all, not included in shared libm for future glibc ports such as RV32), so, yes, in any case where tools generate direct calls to those functions (rather than just following the "asm" annotations on function declarations in the headers), they need to stop doing so.

Bug had been tracked here and fixed with PR already in clang-10 for very long time.

For some more context on why these were removed see Proposal: Remove or reduce math-finite.h:

For some of the functions in this file; pow, powf, log, logf, log2, log2f, exp, expf, exp2, and exp2f; the default implementations have been improved to handle the special cases and the *_finite names are just aliases of the normal name and so the asm attribute isn't accomplishing anything.

Midway answered 15/10, 2022 at 22:16 Comment(0)
H
-1

Add header files when compiling, clang -L/home/xiaokuan/lib/glibc-2.32-install/lib -I/home/xiaokuan/lib/glibc-2.32-install/include -lm -ffast-math a.c

Hutch answered 22/3, 2021 at 3:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.