Page MenuHomePhabricator

[Clang][LoongArch] Add initial LoongArch target and driver support
ClosedPublic

Authored by SixWeining on Jul 21 2022, 5:16 AM.

Details

Summary

With the initial support added, clang can compile helloworld C
to executable file for loongarch64. For example:

$ cat hello.c
#include <stdio.h>
int main() {
  printf("Hello, world!\n");
  return 0;
}
$ clang --target=loongarch64-unknown-linux-gnu --gcc-toolchain=xxx --sysroot=xxx hello.c

The output a.out can run within qemu or native machine. For example:

$ file ./a.out
./a.out: ELF 64-bit LSB pie executable, LoongArch, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-loongarch-lp64d.so.1, for GNU/Linux 5.19.0, with debug_info, not stripped
$ ./a.out
Hello, world!

Currently gcc toolchain and sysroot can be found here:
https://github.com/loongson/build-tools/releases/download/2022.08.11/loongarch64-clfs-5.1-cross-tools-gcc-glibc.tar.xz

Reference: https://github.com/loongson/LoongArch-Documentation
The last commit hash (main branch) is:
99016636af64d02dee05e39974d4c1e55875c45b

Note loongarch32 is not fully tested because there is no reference
gcc toolchain yet.

Diff Detail

Event Timeline

SixWeining created this revision.Jul 21 2022, 5:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 21 2022, 5:16 AM
SixWeining requested review of this revision.Jul 21 2022, 5:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 21 2022, 5:16 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

This looks great, thanks!

Exciting that we can finally go all the way from C source to LoongArch binary.

The changes look good to me, other than a few nits. But please wait for a day or two for other people to review on their own time.

clang/lib/Basic/Targets/LoongArch.h
70

nit: this should use setABI. Right now, there's no difference, but once the function does more (like setting other ABI flags), you won't need to change it here. Same for the 64-bit version.

clang/lib/Driver/ToolChains/Arch/LoongArch.h
26

nit: comment mismatch "end"

clang/test/Driver/loongarch-abi.c
42

please, split between pass and error by adding a new loongarch-abi-error.c and adding the error tests to it.

SixWeining marked 3 inline comments as done.

Address @rengolin's comments.

This looks great, thanks!

Exciting that we can finally go all the way from C source to LoongArch binary.

The changes look good to me, other than a few nits. But please wait for a day or two for other people to review on their own time.

Thanks, Renato.

Because relocation hasn't been added to the backend, complex code (e.g. with function call) can't been compiled currently.
But at least, as you said, we finally go all the way from C source to LoongArch binary. This is a start and further implementation will be added later.

clang/lib/Basic/Targets/LoongArch.h
70

Thanks. No problem.

clang/lib/Driver/ToolChains/Arch/LoongArch.h
26

Thanks.

clang/test/Driver/loongarch-abi.c
42

Thanks. No problem.

MaskRay added inline comments.Jul 21 2022, 7:32 PM
clang/lib/Basic/Targets/LoongArch.cpp
27

return {}

clang/test/Driver/frame-pointer.c
60

Use --target= for new tests. -target is a legacy syntax.

71

remove // from the otherwise empty line

clang/test/Driver/loongarch-abi-error.c
2

-fsyntax and remove -o %t.o

clang/test/Driver/loongarch-abi.c
2

The line isn't very song, no need to break it into two.

clang/test/Preprocessor/init-loongarch.c
2

remove <

MaskRay added inline comments.Jul 21 2022, 7:35 PM
clang/lib/Driver/ToolChains/Linux.cpp
473

avoid simple variable which is only used once

clang/test/Driver/loongarch64-toolchain.c
4 ↗(On Diff #446688)

Just remove -no-canonical-prefixes and clang{{.*}} below. "-cc1" is sufficient to anchor a cc1 line.

clang/test/Preprocessor/init-loongarch.c
22

Consider using -NEXT for related values

SixWeining marked 9 inline comments as done.

Address @MaskRay's comments. Thanks.

SixWeining added inline comments.Jul 21 2022, 10:01 PM
clang/lib/Basic/Targets/LoongArch.cpp
27

Thanks.

MaskRay added inline comments.Jul 23 2022, 11:09 AM
clang/lib/Basic/Targets/LoongArch.h
25

LLVM_LIBRARY_VISIBILITY

36

Define WCharType

clang/lib/Driver/ToolChains/Arch/LoongArch.h
16

Delete unused <string> <vector>

clang/lib/Driver/ToolChains/Gnu.cpp
309

Can be added before mips. Seems that some cases are unsorted. Just ignore them.

2236

I don't know which of /lib64, /lib has been used. For purity, I'd hope that we just have /lib, no multilib style /lib64

2488

Just add loongarch32 in this patch. It is trivial

clang/test/Driver/loongarch64-toolchain.c
20 ↗(On Diff #446736)

Not using NEXT is somewhat brittle.

Perhaps add loongarch-toolchain.c instead. riscv*-toolchain.c are not good examples to follow. You may check out linux-cross.cpp

SixWeining marked 5 inline comments as done.

Continue to address @MaskRay's comments: LLVM_LIBRARY_VISIBILITY ...

clang/lib/Driver/ToolChains/Gnu.cpp
2236

I also don't know the actual usage of /lib64 but I just tried and it works fine if I remove /lib64.

2488

But I don't know how to handle loongarch32 because there isn't a loongarch32 gcc toolchain available yet.

clang/test/Driver/loongarch64-toolchain.c
20 ↗(On Diff #446736)

Thanks.

xry111 added inline comments.Jul 25 2022, 2:27 AM
clang/lib/Driver/ToolChains/Gnu.cpp
2236

I don't like lib64 too. But for LoongArch LP64D, the path to ELF interpreter is hard coded /lib64/ld-linux-loongarch-lp64d.so.1 and it seems too late to change it. And LoongArch GCC installs libstdc++ etc. for LP64D into $PREFIX/lib64 by default (like x86_64).

As a distro (LFS) maintainer: we are already hacking GCC code to get rid of /usr/lib64.

SixWeining added inline comments.Jul 25 2022, 2:29 AM
clang/lib/Driver/ToolChains/Gnu.cpp
2236

Thanks for the quick reply. So I should keep the /lib64 here?

xry111 added inline comments.Jul 25 2022, 2:40 AM
clang/lib/Driver/ToolChains/Gnu.cpp
2236

I think you should keep it. A multilib distro may have /usr/lib64, /usr/lib32, and /usr/lib32sf (sf for soft float or whatever) and make /usr/lib a symlink. A "mostly 32-bit distro" may have symlink /usr/lib -> /usr/lib32, but still capable to build & run LA64 programs with libraries in /usr/lib64. Removing lib64 will break clang on such distros with -mabi=64.

Personally, I don't like lib64. But we can't really predict what the distro maintainers will do (unless you say something explicitly like "a LP64D capable distro SHALL have LP64D libraries in /usr/lib" in a spec).

keep /lib64

MaskRay added inline comments.Jul 25 2022, 5:44 PM
clang/lib/Driver/ToolChains/Gnu.cpp
2236

Dynamic loader selection is orthogonal to the LibDirs variable here. You can use /lib64/ld-linux-loongarch-lp64d.so.1 while the library paths are from /lib .

If anything, riscv multilib support is quite broken at this point so probably don't use it as a reference.
If there is ever a 32-bit distro which wants to do 64-bit compilation, you can leverage multiarch, which is less broken. https://maskray.me/blog/2021-03-28-compiler-driver-and-cross-compilation

xen0n accepted this revision.Aug 21 2022, 9:56 AM
xen0n added inline comments.
clang/lib/Driver/ToolChains/Gnu.cpp
2236

FWIW this is actually beneficial for Gentoo (which consistently uses lib64 for its 64-bit-capable profiles since forever, at least for all of the 64-bit arches/profiles I have used). Otherwise the libdir is really more-or-less freely chosen. And I think most if not all distros already patch downstream for this libdir tweaking...

The ELF interpreter path is indeed hardcoded, and I'll admit I referred to many lib64-using precedents when reviewing the initial proposal. I think many ideas were thrown around and every of them was strictly better than the MIPS carryover /lib/ld.so.1 I think. That ship has long sailed though, and even a lib64 just for housing the symlink to the real ld.so seems okay to me.

So overall personally I don't feel this is too problematic; sorry if I sounded like a grumpy old guy defending his favorite /lib64 (and all its old split-usr glory ;-)

This revision is now accepted and ready to land.Aug 21 2022, 9:56 AM
MaskRay accepted this revision.Aug 21 2022, 11:17 AM
MaskRay added inline comments.
clang/test/Preprocessor/init-loongarch.c
2

-triple . The CC1 option is a Separate (yes, inconsistent).

-triple= to -triple

Use -fsyntax-only; -check-prefix to --check-prefix.

SixWeining edited the summary of this revision. (Show Details)Aug 22 2022, 3:58 AM