diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.h b/clang/lib/Driver/ToolChains/Arch/RISCV.h --- a/clang/lib/Driver/ToolChains/Arch/RISCV.h +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.h @@ -26,6 +26,10 @@ const llvm::Triple &Triple); StringRef getRISCVArch(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); + +void addRISCVTargetABIArgs(const ToolChain &ToolChain, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs); } // end namespace riscv } // namespace tools } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -723,3 +723,13 @@ return "rv64imafdc"; } } + +void riscv::addRISCVTargetABIArgs(const ToolChain &ToolChain, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) { + // We need to pass target-abi option to check it is equal to module's + // target-abi information. + StringRef ABIName = getRISCVABI(Args, ToolChain.getTriple()); + CmdArgs.push_back( + Args.MakeArgString(Twine("-plugin-opt=-target-abi=") + ABIName)); +} diff --git a/clang/lib/Driver/ToolChains/BareMetal.h b/clang/lib/Driver/ToolChains/BareMetal.h --- a/clang/lib/Driver/ToolChains/BareMetal.h +++ b/clang/lib/Driver/ToolChains/BareMetal.h @@ -40,6 +40,7 @@ public: bool useIntegratedAs() const override { return true; } + bool HasNativeLLVMSupport() const override { return true; } bool isCrossCompiling() const override { return true; } bool isPICDefault() const override { return false; } bool isPIEDefault() const override { return false; } diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -319,6 +319,13 @@ CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); + const Driver &D = TC.getDriver(); + if (D.isUsingLTO()) { + assert(!Inputs.empty() && "Must have at least one input."); + addLTOOptions(TC, Args, CmdArgs, Output, Inputs[0], + D.getLTOMode() == LTOK_Thin); + } + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), Args.MakeArgString(TC.GetLinkerPath()), CmdArgs, Inputs, Output)); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -12,6 +12,7 @@ #include "Arch/M68k.h" #include "Arch/Mips.h" #include "Arch/PPC.h" +#include "Arch/RISCV.h" #include "Arch/SystemZ.h" #include "Arch/VE.h" #include "Arch/X86.h" @@ -629,6 +630,17 @@ addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/true); + // pass more options in specific target + switch (ToolChain.getArch()) { + default: + break; + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: { + riscv::addRISCVTargetABIArgs(ToolChain, Args, CmdArgs); + break; + } + } + // Handle remark diagnostics on screen options: '-Rpass-*'. renderRpassOptions(Args, CmdArgs); diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.h b/clang/lib/Driver/ToolChains/RISCVToolchain.h --- a/clang/lib/Driver/ToolChains/RISCVToolchain.h +++ b/clang/lib/Driver/ToolChains/RISCVToolchain.h @@ -29,6 +29,7 @@ RuntimeLibType GetDefaultRuntimeLibType() const override; UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const override; + bool HasNativeLLVMSupport() const override { return true; } void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp --- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp +++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "RISCVToolchain.h" +#include "Arch/RISCV.h" #include "CommonArgs.h" #include "InputInfo.h" #include "clang/Driver/Compilation.h" @@ -158,6 +159,12 @@ CmdArgs.push_back("elf32lriscv"); } + if (D.isUsingLTO()) { + assert(!Inputs.empty() && "Must have at least one input."); + addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs[0], + D.getLTOMode() == LTOK_Thin); + } + std::string Linker = getToolChain().GetLinkerPath(); bool WantCRTs = diff --git a/clang/test/Driver/lto.c b/clang/test/Driver/lto.c --- a/clang/test/Driver/lto.c +++ b/clang/test/Driver/lto.c @@ -85,3 +85,53 @@ // FLTO-AUTO: -flto=full // FLTO-JOBSERVER: -flto=full // + +// RUN: %clang -target x86_64-unknown-linux-gnu %s -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TARGET-ABI +// CHECK-NO-TARGET-ABI-NOT: "-plugin-opt=-target-abi + +// Need to pass -target-abi option in RISC-V target. +// RUN: %clang -target riscv32 %s -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=RV32-DEFAULT +// RUN: %clang -target riscv64 %s -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=RV64-DEFAULT +// RV32-DEFAULT: "-plugin-opt=-target-abi=ilp32" +// RV64-DEFAULT: "-plugin-opt=-target-abi=lp64" +// +// RUN: %clang -target riscv32-unknown-elf %s -fuse-ld=gold -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=RV32-DEFAULT-ELF +// RUN: %clang -target riscv32-unknown-elf %s -fuse-ld=lld -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=RV32-DEFAULT-ELF +// RUN: %clang -target riscv32-unknown-linux-gnu %s -fuse-ld=gold -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=RV32-DEFAULT-LINUX +// RUN: %clang -target riscv32-unknown-linux-gnu %s -fuse-ld=lld -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=RV32-DEFAULT-LINUX +// +// RV32-DEFAULT-ELF: "-plugin-opt=-target-abi=ilp32" +// RV32-DEFAULT-LINUX: "-plugin-opt=-target-abi=ilp32d" + +// RUN: %clang -target riscv64-unknown-elf %s -fuse-ld=gold -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=RV64-DEFAULT-ELF +// RUN: %clang -target riscv64-unknown-elf %s -fuse-ld=lld -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=RV64-DEFAULT-ELF +// RUN: %clang -target riscv64-unknown-linux-gnu %s -fuse-ld=gold -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=RV64-DEFAULT-LINUX +// RUN: %clang -target riscv64-unknown-linux-gnu %s -fuse-ld=lld -flto \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=RV64-DEFAULT-LINUX +// +// RV64-DEFAULT-ELF: "-plugin-opt=-target-abi=lp64" +// RV64-DEFAULT-LINUX: "-plugin-opt=-target-abi=lp64d" + +// RUN: %clang -target riscv32-unknown-linux-gnu %s -fuse-ld=gold -flto \ +// RUN: -mabi=ilp32f -### 2>&1 | FileCheck %s --check-prefix=RISCV-SPEC-ABI-1 +// RUN: %clang -target riscv32-unknown-linux-gnu %s -fuse-ld=gold -flto \ +// RUN: -mabi=ilp32d -### 2>&1 | FileCheck %s --check-prefix=RISCV-SPEC-ABI-2 +// RUN: %clang -target riscv64-unknown-linux-gnu %s -fuse-ld=lld -flto \ +// RUN: -mabi=lp64 -### 2>&1 | FileCheck %s --check-prefix=RISCV-SPEC-ABI-3 +// RUN: %clang -target riscv64-unknown-linux-gnu %s -fuse-ld=lld -flto \ +// RUN: -mabi=lp64f -### 2>&1 | FileCheck %s --check-prefix=RISCV-SPEC-ABI-4 +// +// RISCV-SPEC-ABI-1: "-plugin-opt=-target-abi=ilp32f" +// RISCV-SPEC-ABI-2: "-plugin-opt=-target-abi=ilp32d" +// RISCV-SPEC-ABI-3: "-plugin-opt=-target-abi=lp64" +// RISCV-SPEC-ABI-4: "-plugin-opt=-target-abi=lp64f"