[clang-cl] Handle -O correctly
We had multiple bugs here:
- We didn't support multiple optimization options in one argument.
e.g. -O2y-
- We didn't correctly expand -O[12dx] to their respective options.
- We treated -O1 as clang -O1 instead of clang -Os.
- We treated -Ox as clang -O3 instead of clang -O2. In fact, cl's -Ox
option is *less* powerful than cl's -O2 option despite -Ox described
as "Full Optimization".
This fixes PR24003.
llvm-svn: 243261
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 96cf7fc..0377bc5 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -8828,17 +8828,31 @@
Args.AddAllArgs(CmdArgs, options::OPT_I);
// Optimization level.
+ if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
+ CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
+ : "/Oi-");
if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
if (A->getOption().getID() == options::OPT_O0) {
CmdArgs.push_back("/Od");
} else {
+ CmdArgs.push_back("/Og");
+
StringRef OptLevel = A->getValue();
- if (OptLevel == "1" || OptLevel == "2" || OptLevel == "s")
- A->render(Args, CmdArgs);
- else if (OptLevel == "3")
- CmdArgs.push_back("/Ox");
+ if (OptLevel == "s" || OptLevel == "z")
+ CmdArgs.push_back("/Os");
+ else
+ CmdArgs.push_back("/Ot");
+
+ CmdArgs.push_back("/Ob2");
}
}
+ if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
+ options::OPT_fno_omit_frame_pointer))
+ CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
+ ? "/Oy"
+ : "/Oy-");
+ if (!Args.hasArg(options::OPT_fwritable_strings))
+ CmdArgs.push_back("/GF");
// Flags for which clang-cl has an alias.
// FIXME: How can we ensure this stays in sync with relevant clang-cl options?