diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -54,7 +54,17 @@ } // Choose a default based on the triple. - return IsLA32 ? "ilp32d" : "lp64d"; + // Honor the explicit ABI modifier suffix in triple's environment part if + // present, falling back to {ILP32,LP64}D otherwise. + switch (Triple.getEnvironment()) { + case llvm::Triple::GNUSF: + return IsLA32 ? "ilp32s" : "lp64s"; + case llvm::Triple::GNUF32: + return IsLA32 ? "ilp32f" : "lp64f"; + case llvm::Triple::GNUF64: + default: + return IsLA32 ? "ilp32d" : "lp64d"; + } } void loongarch::getLoongArchTargetFeatures(const Driver &D, diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -86,6 +86,36 @@ case llvm::Triple::aarch64_be: return "aarch64_be-linux-gnu"; + case llvm::Triple::loongarch64: { + const char *Libc; + const char *FPFlavor; + + if (TargetTriple.isGNUEnvironment()) { + Libc = "gnu"; + } else if (TargetTriple.isMusl()) { + Libc = "musl"; + } else { + return TargetTriple.str(); + } + + switch (TargetEnvironment) { + default: + return TargetTriple.str(); + case llvm::Triple::GNUSF: + FPFlavor = "sf"; + break; + case llvm::Triple::GNUF32: + FPFlavor = "f32"; + break; + case llvm::Triple::GNU: + case llvm::Triple::GNUF64: + FPFlavor = "f64"; + break; + } + + return std::string("loongarch64-linux-") + Libc + FPFlavor; + } + case llvm::Triple::m68k: return "m68k-linux-gnu"; diff --git a/clang/test/Driver/loongarch-abi.c b/clang/test/Driver/loongarch-abi.c --- a/clang/test/Driver/loongarch-abi.c +++ b/clang/test/Driver/loongarch-abi.c @@ -16,6 +16,26 @@ // RUN: %clang --target=loongarch64-unknown-elf %s -fsyntax-only -### -mabi=lp64d 2>&1 \ // RUN: | FileCheck --check-prefix=LP64D %s +// RUN: %clang --target=loongarch32-linux-gnusf %s -fsyntax-only -### 2>&1 \ +// RUN: | FileCheck --check-prefix=ILP32S %s +// RUN: %clang --target=loongarch32-linux-gnuf32 %s -fsyntax-only -### 2>&1 \ +// RUN: | FileCheck --check-prefix=ILP32F %s +// RUN: %clang --target=loongarch32-linux-gnuf64 %s -fsyntax-only -### 2>&1 \ +// RUN: | FileCheck --check-prefix=ILP32D %s + +// RUN: %clang --target=loongarch64-linux-gnusf %s -fsyntax-only -### 2>&1 \ +// RUN: | FileCheck --check-prefix=LP64S %s +// RUN: %clang --target=loongarch64-linux-gnuf32 %s -fsyntax-only -### 2>&1 \ +// RUN: | FileCheck --check-prefix=LP64F %s +// RUN: %clang --target=loongarch64-linux-gnuf64 %s -fsyntax-only -### 2>&1 \ +// RUN: | FileCheck --check-prefix=LP64D %s + +// Check that -mabi prevails in case of conflicts with the triple-implied ABI. +// RUN: %clang --target=loongarch32-linux-gnuf64 %s -fsyntax-only -### -mabi=ilp32s 2>&1 \ +// RUN: | FileCheck --check-prefix=ILP32S %s +// RUN: %clang --target=loongarch64-linux-gnuf64 %s -fsyntax-only -### -mabi=lp64s 2>&1 \ +// RUN: | FileCheck --check-prefix=LP64S %s + // ILP32S: "-target-abi" "ilp32s" // ILP32F: "-target-abi" "ilp32f" // ILP32D: "-target-abi" "ilp32d"