Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -2035,6 +2035,12 @@ HelpText<"Use 64-bit floating point registers (MIPS only)">; def mfp32 : Flag<["-"], "mfp32">, Group, HelpText<"Use 32-bit floating point registers (MIPS only)">; +def mgpopt : Flag<["-"], "mgpopt">, Group, + HelpText<"Use GP relative accesses for symbols known to be in a small" + " data section (MIPS)">; +def mno_gpopt : Flag<["-"], "mno-gpopt">, Group, + HelpText<"Do not use GP relative accesses for symbols known to be in a small" + " data section (MIPS)">; def mnan_EQ : Joined<["-"], "mnan=">, Group; def mabicalls : Flag<["-"], "mabicalls">, Group, HelpText<"Enable SVR4-style position-independent code (Mips only)">; Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -1462,6 +1462,33 @@ A->claim(); } + Arg *GPOpt = Args.getLastArg(options::OPT_mgpopt, options::OPT_mno_gpopt); + Arg *ABICalls = Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls); + + // -mabicalls is the default for many MIPS environments, even with -fno-pic. + // -mgpopt is the default for static, -fno-pic environments but these two + // options conflict. We want to be certain that -mno-abicalls -mgpopt is + // the only case where -mllvm -mgpopt is passed. + // NOTE: We need a warning here or in the backend to warn when -mgpopt is + // passed explicitly when compiling something with -mabicalls + // (implictly) in affect. Currently the warning is in the backend. + bool WantABICalls = + ABICalls && ABICalls->getOption().matches(options::OPT_mabicalls); + bool WantGPOpt = GPOpt && GPOpt->getOption().matches(options::OPT_mgpopt); + bool DefaultABICalls = !ABICalls; + if (!DefaultABICalls && !WantABICalls) { + if (!GPOpt || WantGPOpt) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-mgpopt=1"); + } else { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-mgpopt=0"); + } + + if (GPOpt) + GPOpt->claim(); + } + if (Arg *A = Args.getLastArg(options::OPT_mcompact_branches_EQ)) { StringRef Val = StringRef(A->getValue()); if (mips::hasCompactBranches(CPUName)) { Index: test/Driver/mips-features.c =================================================================== --- test/Driver/mips-features.c +++ test/Driver/mips-features.c @@ -10,6 +10,31 @@ // RUN: | FileCheck --check-prefix=CHECK-MNOABICALLS %s // CHECK-MNOABICALLS: "-target-feature" "+noabicalls" // +// -mgpopt +// RUN: %clang -target mips-linux-gnu -### -c %s -mno-gpopt -mgpopt 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-MGPOPT-DEF-ABICALLS %s +// CHECK-MGPOPT-DEF-ABICALLS-NOT: "-mllvm" "-mgpopt" +// +// -mabicalls -mgpopt +// RUN: %clang -target mips-linux-gnu -### -c %s -mabicalls -mno-gpopt -mgpopt 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-MGPOPT-EXPLICIT-ABICALLS %s +// CHECK-MGPOPT-EXPLICIT-ABICALLS-NOT: "-mllvm" "-mgpopt" +// +// -mno-abicalls -mgpopt +// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mno-gpopt -mgpopt 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-MGPOPT %s +// CHECK-MGPOPT: "-mllvm" "-mgpopt=1" +// +// -mno-abicalls -mno-gpopt +// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mgpopt -mno-gpopt 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-MNOGPOPT %s +// CHECK-MNOGPOPT: "-mllvm" "-mgpopt=0" +// +// -mno-abicalls +// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-MGPOPTDEF %s +// CHECK-MGPOPTDEF: "-mllvm" "-mgpopt=1" +// // -mips16 // RUN: %clang -target mips-linux-gnu -### -c %s \ // RUN: -mno-mips16 -mips16 2>&1 \