Skip to content

Commit 89b0fe0

Browse files
committed
[clang][Driver][SPIR-V] Allow linking IR using llvm-link
Signed-off-by: Nick Sarnie <[email protected]>
1 parent dea330b commit 89b0fe0

File tree

4 files changed

+75
-3
lines changed

4 files changed

+75
-3
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4265,8 +4265,11 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args,
42654265
Args.AddFlagArg(nullptr,
42664266
getOpts().getOption(options::OPT_frtlib_add_rpath));
42674267
}
4268-
// Emitting LLVM while linking disabled except in HIPAMD Toolchain
4269-
if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4268+
// Emitting LLVM while linking disabled except in the HIPAMD or SPIR-V
4269+
// Toolchains
4270+
if (Args.hasArg(options::OPT_emit_llvm) &&
4271+
!Args.hasArg(options::OPT_hip_link) &&
4272+
!C.getDefaultToolChain().getTriple().isSPIRV())
42704273
Diag(clang::diag::err_drv_emit_llvm_link);
42714274
if (C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
42724275
LTOMode != LTOK_None &&
@@ -4595,7 +4598,14 @@ void Driver::BuildDefaultActions(Compilation &C, DerivedArgList &Args,
45954598
LA->propagateHostOffloadInfo(C.getActiveOffloadKinds(),
45964599
/*BoundArch=*/nullptr);
45974600
} else {
4598-
LA = C.MakeAction<LinkJobAction>(LinkerInputs, types::TY_Image);
4601+
// If we are linking but were passed -emit-llvm, we will be calling
4602+
// llvm-link, so set the output type accordingly. This is only allowed in
4603+
// rare cases, so make sure we aren't going to error about it.
4604+
types::ID LT =
4605+
Args.hasArg(options::OPT_emit_llvm) && !Diags.hasErrorOccurred()
4606+
? types::TY_LLVM_BC
4607+
: types::TY_Image;
4608+
LA = C.MakeAction<LinkJobAction>(LinkerInputs, LT);
45994609
}
46004610
if (!UseNewOffloadingDriver)
46014611
LA = OffloadBuilder->processHostLinkAction(LA);

clang/lib/Driver/ToolChains/SPIRV.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,28 @@ void SPIRV::constructAssembleCommand(Compilation &C, const Tool &T,
7070
Exec, CmdArgs, Input, Output));
7171
}
7272

73+
void SPIRV::constructLLVMLinkCommand(Compilation &C, const Tool &T,
74+
const JobAction &JA,
75+
const InputInfo &Output,
76+
const InputInfoList &Inputs,
77+
const llvm::opt::ArgStringList &Args) {
78+
// Construct llvm-link command.
79+
// The output from llvm-link is a bitcode file.
80+
ArgStringList LlvmLinkArgs;
81+
82+
assert(!Inputs.empty() && "Must have at least one input.");
83+
84+
LlvmLinkArgs.append({"-o", Output.getFilename()});
85+
for (auto Input : Inputs)
86+
LlvmLinkArgs.push_back(Input.getFilename());
87+
88+
const char *LlvmLink =
89+
C.getArgs().MakeArgString(T.getToolChain().GetProgramPath("llvm-link"));
90+
C.addCommand(std::make_unique<Command>(JA, T, ResponseFileSupport::None(),
91+
LlvmLink, LlvmLinkArgs, Inputs,
92+
Output));
93+
}
94+
7395
void SPIRV::Translator::ConstructJob(Compilation &C, const JobAction &JA,
7496
const InputInfo &Output,
7597
const InputInfoList &Inputs,
@@ -121,6 +143,10 @@ void SPIRV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
121143
const InputInfoList &Inputs,
122144
const ArgList &Args,
123145
const char *LinkingOutput) const {
146+
if (JA.getType() == types::TY_LLVM_BC) {
147+
constructLLVMLinkCommand(C, *this, JA, Output, Inputs, {});
148+
return;
149+
}
124150
const ToolChain &ToolChain = getToolChain();
125151
std::string Linker = ToolChain.GetProgramPath(getShortName());
126152
ArgStringList CmdArgs;

clang/lib/Driver/ToolChains/SPIRV.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ void constructAssembleCommand(Compilation &C, const Tool &T,
2727
const InputInfo &Input,
2828
const llvm::opt::ArgStringList &Args);
2929

30+
void constructLLVMLinkCommand(Compilation &C, const Tool &T,
31+
const JobAction &JA, const InputInfo &Output,
32+
const InputInfoList &Inputs,
33+
const llvm::opt::ArgStringList &Args);
34+
3035
class LLVM_LIBRARY_VISIBILITY Translator : public Tool {
3136
public:
3237
Translator(const ToolChain &TC)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Check BC input
2+
// RUN: mkdir -p %t
3+
// RUN: touch %t/a.bc
4+
// RUN: touch %t/b.bc
5+
// RUN: %clang -### --target=spirv64 -emit-llvm %t/a.bc %t/b.bc 2>&1 | FileCheck --check-prefix=CHECK-TOOL-BC %s
6+
7+
// CHECK-TOOL-BC: "-cc1" {{.*}} "-o" "[[TMP1_BC:.+]]" "-x" "ir" "{{.*}}.bc"
8+
// CHECK-TOOL-BC: "-cc1" {{.*}} "-o" "[[TMP2_BC:.+]]" "-x" "ir" "{{.*}}.bc"
9+
// CHECK-TOOL-BC: llvm-link{{.*}} "-o" {{.*}} "[[TMP1_BC]]" "[[TMP2_BC]]"
10+
11+
// RUN: %clang -ccc-print-bindings --target=spirv64 -emit-llvm %t/a.bc %t/b.bc 2>&1 | FileCheck -check-prefix=CHECK-BINDINGS-BC %s
12+
13+
// CHECK-BINDINGS-BC: "spirv64" - "clang", inputs: ["{{.*}}.bc"], output: "[[TMP1_BINDINGS_BC:.+]]"
14+
// CHECK-BINDINGS-BC: "spirv64" - "clang", inputs: ["{{.*}}.bc"], output: "[[TMP2_BINDINGS_BC:.+]]"
15+
// CHECK-BINDINGS-BC: "spirv64" - "SPIR-V::Linker", inputs: ["[[TMP1_BINDINGS_BC]]", "[[TMP2_BINDINGS_BC]]"], output: "{{.*}}.bc"
16+
17+
// Check source input
18+
// RUN: touch %t/foo.c
19+
// RUN: touch %t/bar.c
20+
21+
// RUN: %clang -### --target=spirv64 -emit-llvm %t/foo.c %t/bar.c 2>&1 | FileCheck --check-prefix=CHECK-TOOL-SRC %s
22+
23+
// CHECK-TOOL-SRC: "-cc1" {{.*}} "-o" "[[TMP1_SRC_BC:.+]]" "-x" "c" "{{.*}}foo.c"
24+
// CHECK-TOOL-SRC: "-cc1" {{.*}} "-o" "[[TMP2_SRC_BC:.+]]" "-x" "c" "{{.*}}bar.c"
25+
// CHECK-TOOL-SRC: llvm-link{{.*}} "-o" {{.*}} "[[TMP1_SRC_BC]]" "[[TMP2_SRC_BC]]"
26+
27+
// RUN: %clang -ccc-print-bindings --target=spirv64 -emit-llvm %t/foo.c %t/bar.c 2>&1 | FileCheck -check-prefix=CHECK-BINDINGS-SRC %s
28+
29+
// CHECK-BINDINGS-SRC: "spirv64" - "clang", inputs: ["{{.*}}foo.c"], output: "[[TMP1_BINDINGS_SRC_BC:.+]]"
30+
// CHECK-BINDINGS-SRC: "spirv64" - "clang", inputs: ["{{.*}}bar.c"], output: "[[TMP2_BINDINGS_SRC_BC:.+]]"
31+
// CHECK-BINDINGS-SRC: "spirv64" - "SPIR-V::Linker", inputs: ["[[TMP1_BINDINGS_SRC_BC]]", "[[TMP2_BINDINGS_SRC_BC]]"], output: "{{.*}}.bc"

0 commit comments

Comments
 (0)