Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -68,6 +68,7 @@ bool GcSections; bool GnuHash = false; bool ICF; + bool LtoFastIsel; bool Mips64EL = false; bool NoGnuUnique; bool NoUndefined; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -332,6 +332,7 @@ Config->ExportDynamic = Args.hasArg(OPT_export_dynamic); Config->GcSections = Args.hasArg(OPT_gc_sections); Config->ICF = Args.hasArg(OPT_icf); + Config->LtoFastIsel = Args.hasArg(OPT_lto_fast_isel); Config->NoGnuUnique = Args.hasArg(OPT_no_gnu_unique); Config->NoUndefined = Args.hasArg(OPT_no_undefined); Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec); Index: ELF/LTO.cpp =================================================================== --- ELF/LTO.cpp +++ ELF/LTO.cpp @@ -199,8 +199,10 @@ Reloc::Model R = Config->Pic ? Reloc::PIC_ : Reloc::Static; auto CreateTargetMachine = [&]() { - return std::unique_ptr( + auto TM = std::unique_ptr( T->createTargetMachine(TheTriple, "", "", Options, R)); + TM->setFastISel(Config->LtoFastIsel); + return TM; }; std::unique_ptr TM = CreateTargetMachine(); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -253,6 +253,7 @@ def alias_version_script_version_script : Joined<["--"], "version-script=">, Alias; // LTO-related options. +def lto_fast_isel : Flag<["--"], "lto-fast-isel">; def lto_jobs : Joined<["--"], "lto-jobs=">, HelpText<"Number of threads to run codegen">; def disable_verify : Flag<["-"], "disable-verify">; Index: test/ELF/lto/fast-isel.ll =================================================================== --- /dev/null +++ test/ELF/lto/fast-isel.ll @@ -0,0 +1,38 @@ +; Test the -lto-fast-isel option. + +; REQUIRES: x86 +; RUN: rm -f %t.so.lto.bc %t.so.lto.opt.bc %t.so.lto.o +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps --lto-fast-isel -shared +; RUN: llvm-objdump -d %t.so | FileCheck %s +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2.so -save-temps -shared +; RUN: llvm-objdump -d %t2.so | FileCheck %s --check-prefix=NOISEL + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-none-linux" + +define i32* @foo(i32* %p, i32* %q, i32** %z) { +entry: + %r = load i32, i32* %p + %s = load i32, i32* %q + %y = load i32*, i32** %z + + %t0 = add i32 %r, %s + %t1 = add i32 %t0, 1 + %t2 = getelementptr i32, i32* %y, i32 1 + %t3 = getelementptr i32, i32* %t2, i32 %t1 + + ret i32* %t3 +} + +; CHECK: addl $1, %eax +; CHECK-NEXT: addq $4, %rcx +; CHECK-NEXT: cltq +; CHECK-NEXT: shlq $2, %rax +; CHECK-NEXT: addq %rcx, %rax +; CHECK-NEXT: retq + +; NOISEL: leal 1(%rax,%rcx), %eax +; NOISEL-NEXT: cltq +; NOISEL-NEXT: leaq 4(%rdx,%rax,4), %rax +; NOISEL-NEXT: retq