Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linker errors on division #52

Open
niels-moller opened this issue Oct 18, 2024 · 2 comments
Open

Linker errors on division #52

niels-moller opened this issue Oct 18, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@niels-moller
Copy link

My understanding is that there are no division hardware on the tkey, hence the compiler needs to issue calls to library functions for division operations. However, some (or all?) of those functions are missing, resulting in linker errors. (When compiling with gcc, those functions live in libgcc.{a,so}, but I don't have much clue about corresponding clang functions).

I compile the below program as follows:

$ TKEY_LIBS=$HOME/hack/tkey/tkey-libs ; clang-15 --target=riscv32-unknown-none-elf -march=rv32iczmmul -mabi=ilp32 -mcmodel=medany -nostdlib -fno-common -fno-builtin-printf -fno-builtin-putchar -mno-relax -O2 -Wall -T ${TKEY_LIBS}/app.lds -L ${TKEY_LIBS} -lcommon -lcrt0 tkey-div.c
ld.lld: error: undefined symbol: __udivdi3
>>> referenced by tkey-div.c
>>>               /tmp/tkey-div-f2b903.o:(main)
clang: error: ld.lld command failed with exit code 1 (use -v to see invocation)

I would expect an implementation of __udivdi3 for this target to be included with clang, but if it is, for some reason it isn't found by the linker.

Example program (the use of volatile is just a hack to not get the interesting part all optimized away):

/* Compile with 
   TKEY_LIBS=... ; clang-15 --target=riscv32-unknown-none-elf -march=rv32iczmmul -mabi=ilp32 -mcmodel=medany -nostdlib -fno-common -fno-builtin-printf -fno-builtin-putchar -mno-relax -O2 -Wall -T ${TKEY_LIBS}/app.lds -L ${TKEY_LIBS} -lcommon -lcrt0 tkey-div.c
 */

#include <stdint.h>
#include <stddef.h>

static void
to_decimal (char *buf, volatile uint64_t x) 
{
  size_t n;
  /* Generates digits in reverse order. */
  for (n = 0; x > 0; n++)
    {
      unsigned d = x % 10;
      x /= 10;
      buf[n] = "0123456789"[d];
    }
}

int 
main(void)
{
  char buf[20];
  to_decimal(buf, 1000000);
  return 0;
}
@quite
Copy link

quite commented Oct 18, 2024

I can build exactly this with clang >= 16. With clang == 15 it fails like you show.

@niels-moller
Copy link
Author

I can confirm that my code compiles fine with clang-16. But it is unclear to me if that means that division in general works, or if it's just division-by-constant that is improved. Looking at the generated code, I see no division instructions (obviously), and also no function calls, just a bunch of shift and mul.

So it would be good to verify that general division works for all supported integer sizes, before closing.

@SallSim SallSim added the bug Something isn't working label Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants