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.

MSalters
  • 173,980
  • 10
  • 155
  • 350
Wang
  • 7,250
  • 4
  • 35
  • 66
  • I tried that already. Result is the same. – Wang Jun 11 '20 at 22:20
  • Related, but not a duplicate (as this question seems to deal with GCC: https://stackoverflow.com/q/8671366/10957435 –  Jun 11 '20 at 22:23
  • @NateEldredge unfortunately it is not the case. – Wang Jun 11 '20 at 22:36
  • please noticed, if it is the order issue, it will say: `undefined reference to 'pow'` not `__pow_infinate` – Wang Jun 11 '20 at 22:38
  • Okay, I can reproduce that. – Nate Eldredge Jun 11 '20 at 22:42
  • 2
    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. – Nate Eldredge Jun 11 '20 at 22:47
  • unfortunately I have to stick to clang-9 so far. – Wang Jun 11 '20 at 23:23
  • 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` symbol – Craig Estey Jun 12 '20 at 00:40
  • @CraigEstey not the case. It turns out clang-9 does not work with new glibc which drops the `math-finite.h` – Wang Jun 12 '20 at 18:06
  • 1
    @Wang: Would you like to post an answer? – Nate Eldredge Jun 14 '20 at 17:16
  • @Wang I've faced this issue too. Any solution so far? – pmor Oct 13 '22 at 15:03
  • @pmor 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. – Wang Oct 15 '22 at 21:54
  • @Wang Yes, now I understand. I've switched to Clang 10.0.0. Thanks. – pmor Oct 17 '22 at 15:08

2 Answers2

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.

Martin Valgur
  • 5,793
  • 1
  • 33
  • 45
Wang
  • 7,250
  • 4
  • 35
  • 66
-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

Ivan Rubinson
  • 3,001
  • 4
  • 19
  • 48
kuan
  • 19
  • 1