diff --git a/lld/test/COFF/lto-opt-level.ll b/lld/test/COFF/lto-opt-level.ll --- a/lld/test/COFF/lto-opt-level.ll +++ b/lld/test/COFF/lto-opt-level.ll @@ -4,6 +4,10 @@ ; RUN: FileCheck --check-prefix=CHECK-O0 %s < %t0.map ; RUN: lld-link /out:%t2.exe /entry:main /subsystem:console /opt:lldlto=2 /lldmap:%t2.map %t.obj ; RUN: FileCheck --check-prefix=CHECK-O2 %s < %t2.map +; RUN: lld-link /out:%ts.exe /entry:main /subsystem:console /opt:lldlto=s /lldmap:%ts.map %t.obj +; RUN: FileCheck --check-prefix=CHECK-O2 %s < %ts.map +; RUN: lld-link /out:%tz.exe /entry:main /subsystem:console /opt:lldlto=z /lldmap:%tz.map %t.obj +; RUN: FileCheck --check-prefix=CHECK-O2 %s < %tz.map ; RUN: lld-link /out:%t2a.exe /entry:main /subsystem:console /lldmap:%t2a.map %t.obj ; RUN: FileCheck --check-prefix=CHECK-O2 %s < %t2a.map diff --git a/lld/test/ELF/lto/opt-level.ll b/lld/test/ELF/lto/opt-level.ll --- a/lld/test/ELF/lto/opt-level.ll +++ b/lld/test/ELF/lto/opt-level.ll @@ -6,6 +6,10 @@ ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s ; RUN: ld.lld -o %t2 -e main --lto-O2 %t.o ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s +; RUN: ld.lld -o %ts -e main --lto-Os %t.o +; RUN: llvm-nm %ts | FileCheck --check-prefix=CHECK-O2 %s +; RUN: ld.lld -o %tz -e main --lto-Oz %t.o +; RUN: llvm-nm %tz | FileCheck --check-prefix=CHECK-O2 %s ; RUN: ld.lld -o %t2a -e main %t.o ; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s ; RUN: ld.lld -o %t2 -e main %t.o --plugin-opt O2 @@ -19,14 +23,14 @@ ; RUN: FileCheck --check-prefix=INVALID1 %s ; RUN: not ld.lld -o %t3 -e main --plugin-opt=Ofoo %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALID2 %s -; INVALID2: --plugin-opt=Ofoo: number expected, but got 'foo' +; INVALID2: invalid optimization level for LTO: foo ; RUN: not ld.lld -o %t3 -e main --lto-O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE1 %s -; INVALIDNEGATIVE1: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE1: invalid optimization level for LTO: -1 ; RUN: not ld.lld -o %t3 -e main --plugin-opt=O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE2 %s -; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE2: invalid optimization level for LTO: -1 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/wasm/lto/opt-level.ll b/lld/test/wasm/lto/opt-level.ll --- a/lld/test/wasm/lto/opt-level.ll +++ b/lld/test/wasm/lto/opt-level.ll @@ -3,6 +3,10 @@ ; RUN: obj2yaml %t0 | FileCheck --check-prefix=CHECK-O0 %s ; RUN: wasm-ld -o %t2 -e main --lto-O2 %t.o ; RUN: obj2yaml %t2 | FileCheck --check-prefix=CHECK-O2 %s +; RUN: wasm-ld -o %ts -e main --lto-Os %t.o +; RUN: obj2yaml %ts | FileCheck --check-prefix=CHECK-O2 %s +; RUN: wasm-ld -o %tz -e main --lto-Oz %t.o +; RUN: obj2yaml %tz | FileCheck --check-prefix=CHECK-O2 %s ; RUN: wasm-ld -o %t2a -e main %t.o ; RUN: obj2yaml %t2a | FileCheck --check-prefix=CHECK-O2 %s @@ -13,7 +17,7 @@ ; RUN: not wasm-ld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE %s -; INVALIDNEGATIVE: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE: invalid optimization level for LTO: -1 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown-wasm" diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -155,6 +155,9 @@ default: llvm_unreachable("Invalid optimization level!"); + case 0: + return PassBuilder::O0; + case 1: return PassBuilder::O1; @@ -315,8 +318,10 @@ if (!Conf.OptPipeline.empty()) runNewPMCustomPasses(Mod, TM, Conf.OptPipeline, Conf.AAPipeline, Conf.DisableVerify); - auto runPasses = Conf.UseNewPM ? runNewPMPasses : runOldPMPasses; - runPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary); + else { + auto runPasses = Conf.UseNewPM ? runNewPMPasses : runOldPMPasses; + runPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary); + } return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod); } diff --git a/llvm/test/tools/gold/X86/opt-level.ll b/llvm/test/tools/gold/X86/opt-level.ll --- a/llvm/test/tools/gold/X86/opt-level.ll +++ b/llvm/test/tools/gold/X86/opt-level.ll @@ -11,6 +11,14 @@ ; RUN: -m elf_x86_64 \ ; RUN: -plugin-opt=O2 -r -o %t.o %t.bc ; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -plugin-opt=save-temps \ +; RUN: -m elf_x86_64 \ +; RUN: -plugin-opt=Os -r -o %t.o %t.bc +; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -plugin-opt=save-temps \ +; RUN: -m elf_x86_64 \ +; RUN: -plugin-opt=Oz -r -o %t.o %t.bc +; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s ; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -plugin-opt=save-temps \ ; RUN: -m elf_x86_64 --plugin-opt=new-pass-manager \ @@ -24,6 +32,14 @@ ; RUN: -m elf_x86_64 --plugin-opt=new-pass-manager \ ; RUN: -plugin-opt=O2 -r -o %t.o %t.bc ; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -plugin-opt=save-temps \ +; RUN: -m elf_x86_64 --plugin-opt=new-pass-manager \ +; RUN: -plugin-opt=Os -r -o %t.o %t.bc +; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -plugin-opt=save-temps \ +; RUN: -m elf_x86_64 --plugin-opt=new-pass-manager \ +; RUN: -plugin-opt=Oz -r -o %t.o %t.bc +; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s ; CHECK-O0: define internal void @foo( ; CHECK-O1: define internal void @foo( diff --git a/llvm/test/tools/lto/opt-level.ll b/llvm/test/tools/lto/opt-level.ll --- a/llvm/test/tools/lto/opt-level.ll +++ b/llvm/test/tools/lto/opt-level.ll @@ -3,6 +3,10 @@ ; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O0 %s ; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O2 -o %t.dylib %t.o ; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -Os -o %t.dylib %t.o +; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -Oz -o %t.dylib %t.o +; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O2 %s target triple = "x86_64-apple-macosx10.8.0" diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -131,8 +131,8 @@ OT_SAVE_TEMPS }; static OutputType TheOutputType = OT_NORMAL; - static unsigned OptLevel; - static unsigned SizeLevel; + static unsigned OptLevel = 2; + static unsigned SizeLevel = 0; // Default parallelism of 0 used to indicate that user did not specify. // Actual parallelism default value depends on implementation. // Currently only affects ThinLTO, where the default is diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp --- a/llvm/tools/llvm-lto2/llvm-lto2.cpp +++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp @@ -29,10 +29,11 @@ using namespace llvm; using namespace lto; -static cl::opt - OptLevel("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " - "(default = '-O2')"), - cl::Prefix, cl::ZeroOrMore, cl::init('2')); +static cl::opt + OptLevel("O", + cl::desc("Optimization level. [-O0, -O1, -O2, -Os, -Oz, or " + "-O3] (default = '-O2')"), + cl::Prefix, cl::ZeroOrMore, cl::init("2")); static cl::opt CGOptLevel( "cg-opt-level", @@ -244,7 +245,10 @@ Conf.OptPipeline = OptPipeline; Conf.AAPipeline = AAPipeline; - Conf.OptLevel = OptLevel - '0'; + Conf.OptLevel = + check(llvm::lto::getOptLevel(OptLevel), "invalid optimization level"); + Conf.SizeLevel = + check(llvm::lto::getSizeLevel(OptLevel), "invalid optimization level"); Conf.UseNewPM = UseNewPM; switch (CGOptLevel) { case '0':