Skip to content

Commit a65771f

Browse files
authored
[SPIR-V] Prefer llvm-spirv-<LLVM_VERSION_MAJOR> tool (#77897)
Prefer using `llvm-spirv-<LLVM_VERSION_MAJOR>` tool (i.e. `llvm-spirv-18`) over plain `llvm-spirv`. If the versioned tool is not found in PATH, fall back to use the plain `llvm-spirv`. An issue with the using `llvm-spirv` is that the one found in PATH might be compiled against older LLVM version which could lead to crashes or obscure bugs. For example, `llvm-spirv` distributed by Ubuntu links against different LLVM version depending on the Ubuntu release (LLVM-10 in 20.04LTS, LLVM-13 in 22.04LTS).
1 parent c8fad4f commit a65771f

File tree

5 files changed

+37
-5
lines changed

5 files changed

+37
-5
lines changed

clang/docs/UsersManual.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4430,9 +4430,9 @@ To generate SPIR-V binaries, Clang uses the external ``llvm-spirv`` tool from th
44304430
Prior to the generation of SPIR-V binary with Clang, ``llvm-spirv``
44314431
should be built or installed. Please refer to `the following instructions
44324432
<https://github.com/KhronosGroup/SPIRV-LLVM-Translator#build-instructions>`_
4433-
for more details. Clang will expect the ``llvm-spirv`` executable to
4434-
be present in the ``PATH`` environment variable. Clang uses ``llvm-spirv``
4435-
with `the widely adopted assembly syntax package
4433+
for more details. Clang will look for ``llvm-spirv-<LLVM-major-version>`` and
4434+
``llvm-spirv`` executables, in this order, in the ``PATH`` environment variable.
4435+
Clang uses ``llvm-spirv`` with `the widely adopted assembly syntax package
44364436
<https://github.com/KhronosGroup/SPIRV-LLVM-Translator/#build-with-spirv-tools>`_.
44374437

44384438
`The versioning

clang/lib/Driver/ToolChains/SPIRV.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88
#include "SPIRV.h"
99
#include "CommonArgs.h"
10+
#include "clang/Basic/Version.h"
1011
#include "clang/Driver/Compilation.h"
1112
#include "clang/Driver/Driver.h"
1213
#include "clang/Driver/InputInfo.h"
@@ -32,8 +33,15 @@ void SPIRV::constructTranslateCommand(Compilation &C, const Tool &T,
3233

3334
CmdArgs.append({"-o", Output.getFilename()});
3435

35-
const char *Exec =
36-
C.getArgs().MakeArgString(T.getToolChain().GetProgramPath("llvm-spirv"));
36+
// Try to find "llvm-spirv-<LLVM_VERSION_MAJOR>". Otherwise, fall back to
37+
// plain "llvm-spirv".
38+
using namespace std::string_literals;
39+
auto VersionedTool = "llvm-spirv-"s + std::to_string(LLVM_VERSION_MAJOR);
40+
std::string ExeCand = T.getToolChain().GetProgramPath(VersionedTool.c_str());
41+
if (!llvm::sys::fs::can_execute(ExeCand))
42+
ExeCand = T.getToolChain().GetProgramPath("llvm-spirv");
43+
44+
const char *Exec = C.getArgs().MakeArgString(ExeCand);
3745
C.addCommand(std::make_unique<Command>(JA, T, ResponseFileSupport::None(),
3846
Exec, CmdArgs, Input, Output));
3947
}

clang/test/Driver/hipspv-toolchain.hip

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,16 @@
3434
// CHECK-SAME: "-o" [[OBJ_HOST:".*o"]] "-x" "hip"
3535

3636
// CHECK: {{".*ld.*"}} {{.*}}[[OBJ_HOST]]
37+
38+
//-----------------------------------------------------------------------------
39+
// Check llvm-spirv-<LLVM_VERSION_MAJOR> is used if it is found in PATH.
40+
// RUN: mkdir -p %t/versioned
41+
// RUN: touch %t/versioned/llvm-spirv-%llvm-version-major \
42+
// RUN: && chmod +x %t/versioned/llvm-spirv-%llvm-version-major
43+
// RUN: env "PATH=%t/versioned" %clang -### -target x86_64-linux-gnu \
44+
// RUN: --offload=spirv64 --hip-path=%S/Inputs/hipspv -nohipwrapperinc \
45+
// RUN: %s 2>&1 \
46+
// RUN: | FileCheck -DVERSION=%llvm-version-major \
47+
// RUN: --check-prefix=VERSIONED %s
48+
49+
// VERSIONED: {{.*}}llvm-spirv-[[VERSION]]

clang/test/Driver/spirv-toolchain.cl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,13 @@
7777

7878
// XTOR: {{llvm-spirv.*"}}
7979
// BACKEND-NOT: {{llvm-spirv.*"}}
80+
81+
//-----------------------------------------------------------------------------
82+
// Check llvm-spirv-<LLVM_VERSION_MAJOR> is used if it is found in PATH.
83+
// RUN: mkdir -p %t/versioned
84+
// RUN: touch %t/versioned/llvm-spirv-%llvm-version-major \
85+
// RUN: && chmod +x %t/versioned/llvm-spirv-%llvm-version-major
86+
// RUN: env "PATH=%t/versioned" %clang -### --target=spirv64 -x cl -c %s 2>&1 \
87+
// RUN: | FileCheck -DVERSION=%llvm-version-major --check-prefix=VERSIONED %s
88+
89+
// VERSIONED: {{.*}}llvm-spirv-[[VERSION]]

clang/test/lit.site.cfg.py.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ config.llvm_external_lit = path(r"@LLVM_EXTERNAL_LIT@")
4343
config.standalone_build = @CLANG_BUILT_STANDALONE@
4444
config.ppc_linux_default_ieeelongdouble = @PPC_LINUX_DEFAULT_IEEELONGDOUBLE@
4545
config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@
46+
config.substitutions.append(("%llvm-version-major", "@LLVM_VERSION_MAJOR@"))
4647

4748
import lit.llvm
4849
lit.llvm.initialize(lit_config, config)

0 commit comments

Comments
 (0)