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,9 @@ def err_drv_riscv_unsupported_with_linker_relaxation : Error< "%0 is unsupported with RISC-V linker relaxation (-mrelax)">; +def warn_drv_loongarch_conflicting_implied_val : Warning< + "ignoring '%0' as it conflicts with that implied by '%1' (%2)">, + 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,32 +26,75 @@ "Unexpected triple"); bool IsLA32 = Triple.getArch() == llvm::Triple::loongarch32; + // Record -mabi value for later use. + const Arg *MABIArg = Args.getLastArg(options::OPT_mabi_EQ); + StringRef MABIValue; + if (MABIArg) { + MABIValue = MABIArg->getValue(); + } + + // Parse -mfpu value for later use. + const Arg *MFPUArg = Args.getLastArg(options::OPT_mfpu_EQ); + int FPU = -1; + if (MFPUArg) { + StringRef V = MFPUArg->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; + } + + // Check `-mabi=` and `-mfpu=` settings and report if they conflict with + // the higher-priority settings implied by -m*-float. + // + // ImpliedABI and ImpliedFPU are guaranteed to have valid values because + // one of the match arms must match if execution can arrive here at all. + if (!MABIValue.empty() && ImpliedABI != MABIValue) + D.Diag(diag::warn_drv_loongarch_conflicting_implied_val) + << MABIArg->getAsString(Args) << A->getAsString(Args) << ImpliedABI; + + if (FPU != -1 && ImpliedFPU != FPU) + D.Diag(diag::warn_drv_loongarch_conflicting_implied_val) + << MFPUArg->getAsString(Args) << A->getAsString(Args) << ImpliedFPU; + + return ImpliedABI; } // If `-mabi=` is specified, use it. - if (const Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) - return A->getValue(); + if (!MABIValue.empty()) + return MABIValue; // 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,18 @@ // 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: FileCheck %s --check-prefixes=CC1,WARN,WARN-FPU0 +// RUN: %clang --target=loongarch64 -mdouble-float -mfpu=none -mabi=lp64s -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=CC1,WARN,WARN-FPUNONE // 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: +// WARN: warning: ignoring '-mabi=lp64s' as it conflicts with that implied by '-mdouble-float' (lp64d) +// WARN-FPU0: warning: ignoring '-mfpu=0' as it conflicts with that implied by '-mdouble-float' (64) +// WARN-FPUNONE: warning: ignoring '-mfpu=none' as it conflicts with that implied by '-mdouble-float' (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,15 @@ // RUN: %clang --target=loongarch64 -msingle-float -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1 -// RUN: %clang --target=loongarch64 -msingle-float -mfpu=0 -mabi=lp64s -fsyntax-only %s -### 2>&1 | \ +// 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=64 -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: +// WARN: warning: ignoring '-mabi=lp64s' as it conflicts with that implied by '-msingle-float' (lp64f) +// WARN: warning: ignoring '-mfpu=64' as it conflicts with that implied by '-msingle-float' (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,15 @@ // 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: +// WARN: warning: ignoring '-mabi=lp64d' as it conflicts with that implied by '-msoft-float' (lp64s) +// WARN: warning: ignoring '-mfpu=64' as it conflicts with that implied by '-msoft-float' (0) // CC1: "-target-feature" "-f"{{.*}} "-target-feature" "-d" // CC1: "-target-abi" "lp64s"