Skip to content

Commit a429dfc

Browse files
authored
[Driver][SPIR-V] Use consistent tools to convert between text and binary form (#120266)
Currently we produce SPIR-V text with `spirv-dis` but assemble it with `llvm-spirv`. The SPIR-V text format is different between the tools so the assemble fails. Use `spirv-as` for assembly as it uses the same format. --------- Signed-off-by: Sarnie, Nick <[email protected]>
1 parent a759176 commit a429dfc

File tree

3 files changed

+67
-5
lines changed

3 files changed

+67
-5
lines changed

clang/lib/Driver/ToolChains/SPIRV.cpp

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ void SPIRV::constructTranslateCommand(Compilation &C, const Tool &T,
2626
llvm::opt::ArgStringList CmdArgs(Args);
2727
CmdArgs.push_back(Input.getFilename());
2828

29-
if (Input.getType() == types::TY_PP_Asm)
30-
CmdArgs.push_back("-to-binary");
29+
assert(Input.getType() != types::TY_PP_Asm && "Unexpected input type");
30+
3131
if (Output.getType() == types::TY_PP_Asm)
3232
CmdArgs.push_back("--spirv-tools-dis");
3333

@@ -46,6 +46,31 @@ void SPIRV::constructTranslateCommand(Compilation &C, const Tool &T,
4646
Exec, CmdArgs, Input, Output));
4747
}
4848

49+
void SPIRV::constructAssembleCommand(Compilation &C, const Tool &T,
50+
const JobAction &JA,
51+
const InputInfo &Output,
52+
const InputInfo &Input,
53+
const llvm::opt::ArgStringList &Args) {
54+
llvm::opt::ArgStringList CmdArgs(Args);
55+
CmdArgs.push_back(Input.getFilename());
56+
57+
assert(Input.getType() == types::TY_PP_Asm && "Unexpected input type");
58+
59+
CmdArgs.append({"-o", Output.getFilename()});
60+
61+
// Try to find "spirv-as-<LLVM_VERSION_MAJOR>". Otherwise, fall back to
62+
// plain "spirv-as".
63+
using namespace std::string_literals;
64+
auto VersionedTool = "spirv-as-"s + std::to_string(LLVM_VERSION_MAJOR);
65+
std::string ExeCand = T.getToolChain().GetProgramPath(VersionedTool.c_str());
66+
if (!llvm::sys::fs::can_execute(ExeCand))
67+
ExeCand = T.getToolChain().GetProgramPath("spirv-as");
68+
69+
const char *Exec = C.getArgs().MakeArgString(ExeCand);
70+
C.addCommand(std::make_unique<Command>(JA, T, ResponseFileSupport::None(),
71+
Exec, CmdArgs, Input, Output));
72+
}
73+
4974
void SPIRV::Translator::ConstructJob(Compilation &C, const JobAction &JA,
5075
const InputInfo &Output,
5176
const InputInfoList &Inputs,
@@ -57,12 +82,29 @@ void SPIRV::Translator::ConstructJob(Compilation &C, const JobAction &JA,
5782
constructTranslateCommand(C, *this, JA, Output, Inputs[0], {});
5883
}
5984

85+
void SPIRV::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
86+
const InputInfo &Output,
87+
const InputInfoList &Inputs,
88+
const ArgList &Args,
89+
const char *AssembleOutput) const {
90+
claimNoWarnArgs(Args);
91+
if (Inputs.size() != 1)
92+
llvm_unreachable("Invalid number of input files.");
93+
constructAssembleCommand(C, *this, JA, Output, Inputs[0], {});
94+
}
95+
6096
clang::driver::Tool *SPIRVToolChain::getTranslator() const {
6197
if (!Translator)
6298
Translator = std::make_unique<SPIRV::Translator>(*this);
6399
return Translator.get();
64100
}
65101

102+
clang::driver::Tool *SPIRVToolChain::getAssembler() const {
103+
if (!Assembler)
104+
Assembler = std::make_unique<SPIRV::Assembler>(*this);
105+
return Assembler.get();
106+
}
107+
66108
clang::driver::Tool *SPIRVToolChain::SelectTool(const JobAction &JA) const {
67109
Action::ActionClass AC = JA.getKind();
68110
return SPIRVToolChain::getTool(AC);
@@ -73,8 +115,9 @@ clang::driver::Tool *SPIRVToolChain::getTool(Action::ActionClass AC) const {
73115
default:
74116
break;
75117
case Action::BackendJobClass:
76-
case Action::AssembleJobClass:
77118
return SPIRVToolChain::getTranslator();
119+
case Action::AssembleJobClass:
120+
return SPIRVToolChain::getAssembler();
78121
}
79122
return ToolChain::getTool(AC);
80123
}

clang/lib/Driver/ToolChains/SPIRV.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ void constructTranslateCommand(Compilation &C, const Tool &T,
2222
const InputInfo &Input,
2323
const llvm::opt::ArgStringList &Args);
2424

25+
void constructAssembleCommand(Compilation &C, const Tool &T,
26+
const JobAction &JA, const InputInfo &Output,
27+
const InputInfo &Input,
28+
const llvm::opt::ArgStringList &Args);
29+
2530
class LLVM_LIBRARY_VISIBILITY Translator : public Tool {
2631
public:
2732
Translator(const ToolChain &TC)
@@ -47,13 +52,25 @@ class LLVM_LIBRARY_VISIBILITY Linker final : public Tool {
4752
const char *LinkingOutput) const override;
4853
};
4954

55+
class LLVM_LIBRARY_VISIBILITY Assembler final : public Tool {
56+
public:
57+
Assembler(const ToolChain &TC) : Tool("SPIRV::Assembler", "spirv-as", TC) {}
58+
bool hasIntegratedAssembler() const override { return false; }
59+
bool hasIntegratedCPP() const override { return false; }
60+
void ConstructJob(Compilation &C, const JobAction &JA,
61+
const InputInfo &Output, const InputInfoList &Inputs,
62+
const llvm::opt::ArgList &TCArgs,
63+
const char *AssembleOutput) const override;
64+
};
65+
5066
} // namespace SPIRV
5167
} // namespace tools
5268

5369
namespace toolchains {
5470

5571
class LLVM_LIBRARY_VISIBILITY SPIRVToolChain : public ToolChain {
5672
mutable std::unique_ptr<Tool> Translator;
73+
mutable std::unique_ptr<Tool> Assembler;
5774

5875
public:
5976
SPIRVToolChain(const Driver &D, const llvm::Triple &Triple,
@@ -81,6 +98,8 @@ class LLVM_LIBRARY_VISIBILITY SPIRVToolChain : public ToolChain {
8198

8299
private:
83100
clang::driver::Tool *getTranslator() const;
101+
clang::driver::Tool *getAssembler() const;
102+
84103
bool NativeLLVMSupport;
85104
};
86105

clang/test/Driver/spirv-toolchain.cl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
// Check assembly input -> object output
4444
// RUN: %clang -### --target=spirv64 -x assembler -c %s 2>&1 | FileCheck --check-prefix=ASM %s
4545
// RUN: %clang -### --target=spirv32 -x assembler -c %s 2>&1 | FileCheck --check-prefix=ASM %s
46-
// ASM: {{llvm-spirv.*"}} {{".*"}} "-to-binary" "-o" {{".*o"}}
46+
// ASM: {{spirv-as.*"}} {{".*"}} "-o" {{".*o"}}
4747

4848
//-----------------------------------------------------------------------------
4949
// Check --save-temps.
@@ -56,7 +56,7 @@
5656
// TMP-SAME: "-o" [[BC:".*bc"]]
5757
// TMP-SAME: [[I]]
5858
// TMP: {{llvm-spirv.*"}} [[BC]] "--spirv-tools-dis" "-o" [[S:".*s"]]
59-
// TMP: {{llvm-spirv.*"}} [[S]] "-to-binary" "-o" {{".*o"}}
59+
// TMP: {{spirv-as.*"}} [[S]] "-o" {{".*o"}}
6060

6161
//-----------------------------------------------------------------------------
6262
// Check linking when multiple input files are passed.

0 commit comments

Comments
 (0)