The current SPIR-V target in LLVM only supports specifying spirv32
/spirv64
in triple with the pointer size [1] but no other details. In this RFC I would like to discuss how other important target settings should be provided to the tools. While the position here is summarized from the OpenCL community we hope that it applies to other areas that are using or interested in using SPIR-V, and if it does not fit broad use cases it would be valuable to discuss and agree on a coherent strategy.
While the SPIR-V target doesn’t fall into a category of conventional LLVM targets it seems that extending the triple components makes sense and might be the best route forward considering that this avoids adding extra flags to tools that use LLVM because they can just inherit LLVM’s triple functionality. It might also be slightly more intuitive to the end users as they do not need to learn new flags.
We therefore would like to suggest the following:
1. SPIR-V version can be specified in sub-architecture component of the target triple. Following the example given in [2] we could expose the interface for setting the version using sub-architecture field in the following format, example:
-triple=spirv64v1.0
for SPIR-V 64-bit version 1.0.
Defaults: When the version is not set explicitly it is being deduced from the functionality being compiled. This is how SPIR-V generation tools have been working up to now at least for OpenCL. However LLVM tools traditionally just set some fixed default value in such cases. It might be good to discuss further what would be more valuable to the end users?
2. SPIR-V environment can be set using the system component of the target triple following examples provided in [2]. However this is currently somewhat redundant as high-level languages mostly target a specific SPIR-V environment either OpenCL or Vulkan but not both. However this flexibility might be beneficial in a longer term, example:
-triple=spirv64-unknown-opencl
for SPIR-V 64-bit conforming to the OpenCL environment specification with generic/unknown vendor.
Defaults: Currently OpenCL is a default environment and the only one supported. It might be useful to make this deducible from the high-level language default environment. However clang infrastructure is not very flexible towards the target setting being affected by the language. That means requiring components being set explicitly might be the cheapest option from the implementation/maintenance perspective and more consistent with the LLVM tooling flow too.
3. SPIR-V extensions for OpenCL are currently mainly aligned with the OpenCL kernel language extensions. Therefore they can be implicitly set through -cl-ext
flag [3]. This flag has not been exposed in the clang driver yet as this seemed like a fairly low level feature for the end user to be setting manually. For the coarse grain settings of extensions we could use vendor component of the triple, example
-triple=spirv64-arm
for 64-bit SPIR-V compatible with Arm device family.
Defaults: unknown/generic SPIR-V with all supported extensions set. This is how SPIR-V is produced currently for OpenCL by default in clang.
Note that for the finer-grained control of extensions some new flags might need to be added in the long term. It would be good to gather some feedback to this in particular to get more clear picture of the requirements.
Overall, it would be good to reach an agreement on how to move forward with the SPIR-V target evolution to make sure that the interface is consistent by all languages and tools in the LLVM project.
[1] llvm-project/Triple.cpp at main · llvm/llvm-project · GitHub
[2] Cross-compilation using Clang — Clang 16.0.0git documentation
[3] OpenCL Support — Clang 16.0.0git documentation