diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -728,6 +728,12 @@ def err_drv_riscv_unsupported_with_linker_relaxation : Error< "%0 is unsupported with RISC-V linker relaxation (-mrelax)">; +def warn_drv_loongarch_conflicting_mabi : Warning< + "the -mabi setting '%0' conflicts with that implied by -m*-float (%1); using %1">, + InGroup; +def warn_drv_loongarch_conflicting_mfpu : Warning< + "the -mfpu setting '%0' conflicts with that implied by -m*-float (%1); using %1">, + InGroup; def err_drv_loongarch_invalid_mfpu_EQ : Error< "invalid argument '%0' to -mfpu=; must be one of: 64, 32, none, 0 (alias for none)">; 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 @@ -26,16 +26,55 @@ "Unexpected triple"); bool IsLA32 = Triple.getArch() == llvm::Triple::loongarch32; + // Parse -mfpu value for later use. + int FPU = -1; + if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) { + StringRef V = A->getValue(); + if (V == "64") + FPU = 64; + else if (V == "32") + FPU = 32; + else if (V == "0" || V == "none") + FPU = 0; + else + D.Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) << V; + } + // Check -m*-float firstly since they have highest priority. if (const Arg *A = Args.getLastArg(options::OPT_mdouble_float, options::OPT_msingle_float, options::OPT_msoft_float)) { - if (A->getOption().matches(options::OPT_mdouble_float)) - return IsLA32 ? "ilp32d" : "lp64d"; - if (A->getOption().matches(options::OPT_msingle_float)) - return IsLA32 ? "ilp32f" : "lp64f"; - if (A->getOption().matches(options::OPT_msoft_float)) - return IsLA32 ? "ilp32s" : "lp64s"; + StringRef ImpliedABI; + int ImpliedFPU = -1; + if (A->getOption().matches(options::OPT_mdouble_float)) { + ImpliedABI = IsLA32 ? "ilp32d" : "lp64d"; + ImpliedFPU = 64; + } + if (A->getOption().matches(options::OPT_msingle_float)) { + ImpliedABI = IsLA32 ? "ilp32f" : "lp64f"; + ImpliedFPU = 32; + } + if (A->getOption().matches(options::OPT_msoft_float)) { + ImpliedABI = IsLA32 ? "ilp32s" : "lp64s"; + ImpliedFPU = 0; + } + + // Still consume `-mabi=` and `-mfpu=` arguments and report if the settings + // conflicts with the higher-priority settings implied by -m*-float. + if (!ImpliedABI.empty()) { + if (const Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { + StringRef MABIValue = A->getValue(); + if (ImpliedABI != MABIValue) + D.Diag(diag::warn_drv_loongarch_conflicting_mabi) + << MABIValue << ImpliedABI; + } + + // -mfpu= has already been parsed at this point. + if (FPU != -1 && ImpliedFPU != FPU) + D.Diag(diag::warn_drv_loongarch_conflicting_mfpu) << FPU << ImpliedFPU; + + return ImpliedABI; + } } // If `-mabi=` is specified, use it. @@ -43,15 +82,13 @@ return A->getValue(); // Select abi based on -mfpu=xx. - if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) { - StringRef FPU = A->getValue(); - if (FPU == "64") - return IsLA32 ? "ilp32d" : "lp64d"; - if (FPU == "32") - return IsLA32 ? "ilp32f" : "lp64f"; - if (FPU == "0" || FPU == "none") - return IsLA32 ? "ilp32s" : "lp64s"; - D.Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) << FPU; + switch (FPU) { + case 64: + return IsLA32 ? "ilp32d" : "lp64d"; + case 32: + return IsLA32 ? "ilp32f" : "lp64f"; + case 0: + return IsLA32 ? "ilp32s" : "lp64s"; } // Choose a default based on the triple. diff --git a/clang/test/Driver/loongarch-mdouble-float.c b/clang/test/Driver/loongarch-mdouble-float.c --- a/clang/test/Driver/loongarch-mdouble-float.c +++ b/clang/test/Driver/loongarch-mdouble-float.c @@ -1,12 +1,16 @@ // RUN: %clang --target=loongarch64 -mdouble-float -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1 +// RUN: %clang --target=loongarch64 -mdouble-float -mfpu=64 -mabi=lp64d -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=CC1,NOWARN // RUN: %clang --target=loongarch64 -mdouble-float -mfpu=0 -mabi=lp64s -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefixes=CC1,WARN // RUN: %clang --target=loongarch64 -mdouble-float -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR -// WARN: warning: argument unused during compilation: '-mfpu=0' -// WARN: warning: argument unused during compilation: '-mabi=lp64s' +// NOWARN-NOT: warning: argument unused during compilation: '-mfpu=64' +// NOWARN-NOT: warning: argument unused during compilation: '-mabi=lp64d' +// WARN: warning: the -mabi setting 'lp64s' conflicts with that implied by -m*-float (lp64d); using lp64d +// WARN: warning: the -mfpu setting '0' conflicts with that implied by -m*-float (64); using 64 // CC1: "-target-feature" "+f"{{.*}} "-target-feature" "+d" // CC1: "-target-abi" "lp64d" diff --git a/clang/test/Driver/loongarch-msingle-float.c b/clang/test/Driver/loongarch-msingle-float.c --- a/clang/test/Driver/loongarch-msingle-float.c +++ b/clang/test/Driver/loongarch-msingle-float.c @@ -1,12 +1,16 @@ // RUN: %clang --target=loongarch64 -msingle-float -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1 +// RUN: %clang --target=loongarch64 -msingle-float -mfpu=32 -mabi=lp64f -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=CC1,NOWARN // RUN: %clang --target=loongarch64 -msingle-float -mfpu=0 -mabi=lp64s -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefixes=CC1,WARN // RUN: %clang --target=loongarch64 -msingle-float -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR -// WARN: warning: argument unused during compilation: '-mfpu=0' -// WARN: warning: argument unused during compilation: '-mabi=lp64s' +// NOWARN-NOT: warning: argument unused during compilation: '-mfpu=32' +// NOWARN-NOT: warning: argument unused during compilation: '-mabi=lp64f' +// WARN: warning: the -mabi setting 'lp64s' conflicts with that implied by -m*-float (lp64f); using lp64f +// WARN: warning: the -mfpu setting '0' conflicts with that implied by -m*-float (32); using 32 // CC1: "-target-feature" "+f"{{.*}} "-target-feature" "-d" // CC1: "-target-abi" "lp64f" diff --git a/clang/test/Driver/loongarch-msoft-float.c b/clang/test/Driver/loongarch-msoft-float.c --- a/clang/test/Driver/loongarch-msoft-float.c +++ b/clang/test/Driver/loongarch-msoft-float.c @@ -1,12 +1,16 @@ // RUN: %clang --target=loongarch64 -msoft-float -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1 +// RUN: %clang --target=loongarch64 -msoft-float -mfpu=0 -mabi=lp64s -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=CC1,NOWARN // RUN: %clang --target=loongarch64 -msoft-float -mfpu=64 -mabi=lp64d -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefixes=CC1,WARN // RUN: %clang --target=loongarch64 -msoft-float -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR -// WARN: warning: argument unused during compilation: '-mfpu=64' -// WARN: warning: argument unused during compilation: '-mabi=lp64d' +// NOWARN-NOT: warning: argument unused during compilation: '-mfpu=0' +// NOWARN-NOT: warning: argument unused during compilation: '-mabi=lp64s' +// WARN: warning: the -mabi setting 'lp64d' conflicts with that implied by -m*-float (lp64s); using lp64s +// WARN: warning: the -mfpu setting '64' conflicts with that implied by -m*-float (0); using 0 // CC1: "-target-feature" "-f"{{.*}} "-target-feature" "-d" // CC1: "-target-abi" "lp64s"