@@ -17,7 +17,7 @@ an obvious way. These include:
17
17
* SPIR-V types mapped to LLVM types
18
18
* SPIR-V instructions mapped to LLVM function calls
19
19
* SPIR-V extended instructions mapped to LLVM function calls
20
- * SPIR-V builtins variables mapped to LLVM global variables
20
+ * SPIR-V builtins variables mapped to LLVM function calls or LLVM global variables
21
21
* SPIR-V instructions mapped to LLVM metadata
22
22
* SPIR-V types mapped to LLVM opaque types
23
23
* SPIR-V decorations mapped to LLVM metadata or named attributes
@@ -203,11 +203,57 @@ where
203
203
* {VectorLoadOpCodeName} = vloadn|vload_half|vload_halfn|vloada_halfn
204
204
205
205
206
- SPIR-V Builtins Variables Mapped to LLVM Global Variables
207
- =========================================================
206
+ SPIR-V Builtin Variables Mapped to LLVM Function Calls or LLVM Global Variables
207
+ ===============================================================================
208
208
209
- SPIR-V builtin variables are mapped to LLVM global variables with unmangled
210
- name __spirv_BuiltIn{Name}.
209
+ By default each access of SPIR-V builtin variable's value is mapped to LLVM
210
+ function call. The unmangled names of these functions follow the convention:
211
+ .. code-block :: c
212
+
213
+ __spirv_BuiltIn{VariableName}
214
+
215
+ In case SPIR-V builtin variable has vector type, the corresponding
216
+ LLVM function will have an integer argument, so each access of the variable's
217
+ scalar component is mapped to a function call with index argument, i.e.:
218
+
219
+ .. code-block :: c
220
+
221
+ ; For scalar variables
222
+ ; SPIR-V
223
+ OpDecorate %__spirv_BuiltInGlobalInvocationId BuiltIn GlobalInvocationId
224
+ %13 = OpLoad %uint %__spirv_BuiltInGlobalLinearId Aligned 4
225
+
226
+ ; Will be transformed to the following LLVM IR:
227
+ %0 = call spir_func i32 @_Z29__spirv_BuiltInGlobalLinearIdv()
228
+
229
+ ; For vector variables
230
+ ; SPIRV
231
+ OpDecorate %__spirv_BuiltInGlobalInvocationId BuiltIn GlobalInvocationId
232
+ %14 = OpLoad %v3ulong %__spirv_BuiltInGlobalInvocationId Aligned 32
233
+ %15 = OpCompositeExtract %ulong %14 1
234
+
235
+ ; Can be transformed to the following LLVM IR:
236
+ %0 = call spir_func i64 @_Z33__spirv_BuiltInGlobalInvocationIdi(i32 1)
237
+
238
+ ; However SPIRV-LLVM translator will transform it to the following pattern:
239
+ %1 = call spir_func i64 @_Z33__spirv_BuiltInGlobalInvocationIdi(i32 0)
240
+ %2 = insertelement <3 x i64> undef, i64 %1, i32 0
241
+ %3 = call spir_func i64 @_Z33__spirv_BuiltInGlobalInvocationIdi(i32 1)
242
+ %4 = insertelement <3 x i64> %2, i64 %3, i32 1
243
+ %5 = call spir_func i64 @_Z33__spirv_BuiltInGlobalInvocationIdi(i32 2)
244
+ %6 = insertelement <3 x i64> %4, i64 %5, i32 2
245
+ %7 = extractelement <3 x i64> %6, i32 1
246
+ ; In case some actions are performed with the variable's value in vector form.
247
+
248
+ SPIR-V builtin variables can also be mapped to LLVM global variables with
249
+ unmangled name __spirv_BuiltIn{Name}.
250
+
251
+ The representation with variables is closer to SPIR-V, so it is easier to
252
+ translate from SPIR-V to LLVM and back using it.
253
+ Hovewer in languages like OpenCL the functionality covered by SPIR-V builtin
254
+ variables is usually represented by builtin functions, so it is easier to
255
+ translate from/to SPIR-V friendly IR to/from LLVM IR produced from OpenCL-like
256
+ source languages. That is why both forms of mapping are supported.
211
257
212
258
SPIR-V instructions mapped to LLVM metadata
213
259
===========================================
0 commit comments