[clang][LoongArch] Emit "target-abi" module flag (#223647)

The LoongArch backend reads the ABI from the "target-abi" module flag,
but clang only emits that flag for ARM, PowerPC and RISC-V. Since LTO code
generation doesn't see the -target-abi option passed to clang, it falls
back to the default ABI of the target, which is lp64d for
loongarch64-unknown-elf, regardless of the ABI the code was compiled for.

When an FPU is enabled, this silently miscompiles code built for another
ABI. For example, with -mabi=lp64s, functions get the lp64d calling
convention after LTO, passing and returning floating-point values in FP registers 
instead of general-purpose ones, and the output is marked as double-float. Nothing
reports this if every object goes through LTO. For instance, a shared library
built this way links without error, and so does lp64s code built without LTO that
uses it. Without an FPU, the generated code keeps the soft-float calling
convention, but the output is still marked as double-float.

The mismatch only shows up as an error when LTO output is linked
together with relocatable objects built without LTO, which LLD rejects with "cannot
link object files with different ABI".

This patch adds LoongArch to the targets for which clang emits the flag,
so LTO uses the ABI the code was compiled for. It follows the per-target
approach taken for ARM (#217601) and PowerPC (#221669), and leaves the existing 
TODO about emitting the flag for every target with a non-empty ABI name as is.

With the flag present, LTO-linking bitcode built for different LoongArch
ABIs now fails with "linking module flags 'target-abi': IDs have conflicting
values" instead of silently picking a single ABI. A -target-abi given to the LTO
backend that disagrees with the flag is now also an error. Both match the
existing RISC-V behavior.

Assisted-by: Claude Code (Claude Opus 5)

Signed-off-by: Mintsuki <mintsuki@protonmail.com>
2 files changed
tree: b682613108aa207c3495efde93b532180e5dbebd
  1. .ci/
  2. .github/
  3. bolt/
  4. clang/
  5. clang-tools-extra/
  6. cmake/
  7. compiler-rt/
  8. cross-project-tests/
  9. flang/
  10. flang-rt/
  11. libc/
  12. libclc/
  13. libcxx/
  14. libcxxabi/
  15. libsycl/
  16. libunwind/
  17. lld/
  18. lldb/
  19. llvm/
  20. llvm-libgcc/
  21. mlir/
  22. offload/
  23. openmp/
  24. orc-rt/
  25. polly/
  26. runtimes/
  27. third-party/
  28. utils/
  29. .clang-format
  30. .clang-format-ignore
  31. .clang-tidy
  32. .git-blame-ignore-revs
  33. .gitattributes
  34. .gitignore
  35. .mailmap
  36. CODE_OF_CONDUCT.md
  37. CONTRIBUTING.md
  38. LICENSE.TXT
  39. pyproject.toml
  40. README.md
  41. SECURITY.md
README.md

The LLVM Compiler Infrastructure

OpenSSF Scorecard OpenSSF Best Practices libc++

Welcome to the LLVM project!

This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.

The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.

C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.

Other components include: the libc++ C++ standard library, the LLD linker, and more.

Getting the Source Code and Building LLVM

Consult the Getting Started with LLVM page for information on building and running LLVM.

For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.

Getting in touch

Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.

The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.