https://github.com/Mintsuki created https://github.com/llvm/llvm-project/pull/231441
For a LoongArch triple without an environment, such as loongarch32-unknown-none-elf, the driver defaults to the double-float ABI (ilp32d), but none of the 32-bit architectures (loongarch32, la32v1.0, la32rv1.0) has an FPU, so the driver passes `-target-abi ilp32d` together with features that cannot implement it. Compiling anything then warns: ``` warning: both target-abi and the triple-implied ABI are invalid, ignoring and using feature-implied ABI ``` and the parts disagree on the ABI: the backend falls back to ilp32s, while clang lowers calls and defines the predefined macros for ilp32d (`__loongarch_double_float` is 1 while `__loongarch_frlen` is 0), and records ilp32d in the "target-abi" module flag. With no environment the triple implies no ABI, and the backend then uses the ABI that the features imply. Make the driver choose the same default: the widest floating-point ABI the selected architecture's FPU supports. loongarch64 is unaffected, as every 64-bit architecture has an FPU and keeps lp64d; the 32-bit ones get ilp32s. Triples with an environment, and explicit -mabi, -mfpu and -m*-float options, behave as before. Assisted-by: Claude Code (Claude Opus 5.5) Signed-off-by: Mintsuki <[email protected]> >From 5728bec181386c098c2731aea1ee49240c15d97a Mon Sep 17 00:00:00 2001 From: Mintsuki <[email protected]> Date: Tue, 13 Oct 2026 11:59:54 +0200 Subject: [PATCH] Pick the default ABI of environment-less triples from the architecture For a LoongArch triple without an environment, such as loongarch32-unknown-none-elf, the driver defaults to the double-float ABI (ilp32d), but none of the 32-bit architectures (loongarch32, la32v1.0, la32rv1.0) has an FPU, so the driver passes `-target-abi ilp32d` together with features that cannot implement it. Compiling anything then warns: ``` warning: both target-abi and the triple-implied ABI are invalid, ignoring and using feature-implied ABI ``` and the parts disagree on the ABI: the backend falls back to ilp32s, while clang lowers calls and defines the predefined macros for ilp32d (`__loongarch_double_float` is 1 while `__loongarch_frlen` is 0), and records ilp32d in the "target-abi" module flag. With no environment the triple implies no ABI, and the backend then uses the ABI that the features imply. Make the driver choose the same default: the widest floating-point ABI the selected architecture's FPU supports. loongarch64 is unaffected, as every 64-bit architecture has an FPU and keeps lp64d; the 32-bit ones get ilp32s. Triples with an environment, and explicit -mabi, -mfpu and -m*-float options, behave as before. Assisted-by: Claude Code (Claude Opus 5.5) Signed-off-by: Mintsuki <[email protected]> --- clang/lib/Driver/ToolChains/Arch/LoongArch.cpp | 16 ++++++++++++++++ .../CodeGen/LoongArch/abi-default-no-warning.c | 8 ++++++++ .../CodeGen/LoongArch/target-abi-module-flag.c | 5 +++++ clang/test/Driver/loongarch-abi.c | 6 ++++++ clang/test/Driver/loongarch-ias.s | 2 +- clang/test/Driver/loongarch-march.c | 4 ++-- clang/test/Preprocessor/init-loongarch.c | 2 ++ 7 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGen/LoongArch/abi-default-no-warning.c diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp index 3c129c84f6929..e6a0e35511a3d 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -108,6 +108,22 @@ StringRef loongarch::getLoongArchABI(const Driver &D, const ArgList &Args, case llvm::Triple::GNUF32: case llvm::Triple::MuslF32: return IsLA32 ? "ilp32f" : "lp64f"; + case llvm::Triple::UnknownEnvironment: { + // Without an environment, the triple implies no ABI. Use the widest + // floating-point ABI that the architecture's FPU supports, which is also + // what the backend picks when it is given no ABI. + std::string ArchName; + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + ArchName = A->getValue(); + std::vector<StringRef> ArchFeatures; + llvm::LoongArch::getArchFeatures( + postProcessTargetCPUString(ArchName, Triple), ArchFeatures); + if (llvm::is_contained(ArchFeatures, "+d")) + return IsLA32 ? "ilp32d" : "lp64d"; + if (llvm::is_contained(ArchFeatures, "+f")) + return IsLA32 ? "ilp32f" : "lp64f"; + return IsLA32 ? "ilp32s" : "lp64s"; + } case llvm::Triple::GNUF64: // This was originally permitted (and indeed the canonical way) to // represent the {ILP32,LP64}D ABIs, but in Feb 2023 Loongson decided to diff --git a/clang/test/CodeGen/LoongArch/abi-default-no-warning.c b/clang/test/CodeGen/LoongArch/abi-default-no-warning.c new file mode 100644 index 0000000000000..ec695957a0415 --- /dev/null +++ b/clang/test/CodeGen/LoongArch/abi-default-no-warning.c @@ -0,0 +1,8 @@ +// REQUIRES: loongarch-registered-target + +// The default ABI the driver picks for a triple without an environment is one +// that the default features support, so the backend does not warn about it. +// RUN: %clang --target=loongarch32-unknown-none-elf -S -o /dev/null %s 2>&1 | count 0 +// RUN: %clang --target=loongarch64-unknown-none-elf -S -o /dev/null %s 2>&1 | count 0 + +float f(float a, float b) { return a + b; } diff --git a/clang/test/CodeGen/LoongArch/target-abi-module-flag.c b/clang/test/CodeGen/LoongArch/target-abi-module-flag.c index 5a4826aff180b..a6b096cbaf579 100644 --- a/clang/test/CodeGen/LoongArch/target-abi-module-flag.c +++ b/clang/test/CodeGen/LoongArch/target-abi-module-flag.c @@ -5,6 +5,11 @@ // RUN: %clang_cc1 -triple loongarch32 -emit-llvm -o - %s | FileCheck --check-prefix=ILP32D %s // RUN: %clang_cc1 -triple loongarch64 -emit-llvm -o - %s | FileCheck --check-prefix=LP64D %s +// The driver's default for a triple without an environment follows the +// architecture's FPU, which the 32-bit architectures lack. +// RUN: %clang --target=loongarch32-unknown-none-elf -S -emit-llvm -o - %s | FileCheck --check-prefix=ILP32S %s +// RUN: %clang --target=loongarch64-unknown-none-elf -S -emit-llvm -o - %s | FileCheck --check-prefix=LP64D %s + // Explicit -target-abi overrides differing from the triple default. // RUN: %clang_cc1 -triple loongarch32 -target-abi ilp32f -emit-llvm -o - %s | FileCheck --check-prefix=ILP32F %s // RUN: %clang_cc1 -triple loongarch32 -target-abi ilp32s -emit-llvm -o - %s | FileCheck --check-prefix=ILP32S %s diff --git a/clang/test/Driver/loongarch-abi.c b/clang/test/Driver/loongarch-abi.c index 12a81d6645584..d37122e17a42f 100644 --- a/clang/test/Driver/loongarch-abi.c +++ b/clang/test/Driver/loongarch-abi.c @@ -1,4 +1,8 @@ // RUN: %clang --target=loongarch32-unknown-elf %s -fsyntax-only -### 2>&1 \ +// RUN: | FileCheck --check-prefix=ILP32S %s +// RUN: %clang --target=loongarch32-unknown-none-elf %s -fsyntax-only -### 2>&1 \ +// RUN: | FileCheck --check-prefix=ILP32S %s +// RUN: %clang --target=loongarch32-unknown-elf %s -fsyntax-only -### -mfpu=64 2>&1 \ // RUN: | FileCheck --check-prefix=ILP32D %s // RUN: %clang --target=loongarch32-unknown-elf %s -fsyntax-only -### -mabi=ilp32s 2>&1 \ // RUN: | FileCheck --check-prefix=ILP32S %s @@ -9,6 +13,8 @@ // RUN: %clang --target=loongarch64-unknown-elf %s -fsyntax-only -### 2>&1 \ // RUN: | FileCheck --check-prefix=LP64D %s +// RUN: %clang --target=loongarch64-unknown-none-elf %s -fsyntax-only -### 2>&1 \ +// RUN: | FileCheck --check-prefix=LP64D %s // RUN: %clang --target=loongarch64-unknown-elf %s -fsyntax-only -### -mabi=lp64s 2>&1 \ // RUN: | FileCheck --check-prefix=LP64S %s // RUN: %clang --target=loongarch64-unknown-elf %s -fsyntax-only -### -mabi=lp64f 2>&1 \ diff --git a/clang/test/Driver/loongarch-ias.s b/clang/test/Driver/loongarch-ias.s index 6fec9e6e15919..1abb939450d92 100644 --- a/clang/test/Driver/loongarch-ias.s +++ b/clang/test/Driver/loongarch-ias.s @@ -2,7 +2,7 @@ /// Check `-target-abi`. // RUN: %clang --target=loongarch32 -### -fintegrated-as -c %s 2>&1 | \ -// RUN: FileCheck -DABI=ilp32d --check-prefix=ABI %s +// RUN: FileCheck -DABI=ilp32s --check-prefix=ABI %s // RUN: %clang --target=loongarch32 -mabi=ilp32d -### -fintegrated-as -c %s 2>&1 | \ // RUN: FileCheck -DABI=ilp32d --check-prefix=ABI %s // RUN: %clang --target=loongarch32 -mabi=ilp32f -### -fintegrated-as -c %s 2>&1 | \ diff --git a/clang/test/Driver/loongarch-march.c b/clang/test/Driver/loongarch-march.c index 046b3b16fa10e..e15d6c0bb9c0b 100644 --- a/clang/test/Driver/loongarch-march.c +++ b/clang/test/Driver/loongarch-march.c @@ -31,13 +31,13 @@ // CC1-LA32V1P0-NOT: "-target-feature" // CC1-LA32V1P0: "-target-feature" "+32bit" "-target-feature" "+32s" // CC1-LA32V1P0-NOT: "-target-feature" -// CC1-LA32V1P0: "-target-abi" "ilp32d" +// CC1-LA32V1P0: "-target-abi" "ilp32s" // CC1-LA32RV1P0: "-target-cpu" "loongarch32" // CC1-LA32RV1P0-NOT: "-target-feature" // CC1-LA32RV1P0: "-target-feature" "+32bit" // CC1-LA32RV1P0-NOT: "-target-feature" -// CC1-LA32RV1P0: "-target-abi" "ilp32d" +// CC1-LA32RV1P0: "-target-abi" "ilp32s" // CC1-LOONGARCH64: "-target-cpu" "loongarch64" // CC1-LOONGARCH64-NOT: "-target-feature" diff --git a/clang/test/Preprocessor/init-loongarch.c b/clang/test/Preprocessor/init-loongarch.c index ef9a043a8ddde..8db53f5d047b9 100644 --- a/clang/test/Preprocessor/init-loongarch.c +++ b/clang/test/Preprocessor/init-loongarch.c @@ -744,6 +744,8 @@ // RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU0-ILP32S %s // RUN: %clang --target=loongarch32 -msoft-float -x c -E -dM %s -o - \ // RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU0-ILP32S %s +// RUN: %clang --target=loongarch32 -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU0-ILP32S %s // LA32-FPU0-ILP32S-NOT: #define __loongarch_double_float // LA32-FPU0-ILP32S: #define __loongarch_frlen 0 // LA32-FPU0-ILP32S: #define __loongarch_grlen 32 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
