1ec7baca1SMichal Paszkowski; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV1_4 2*0a443f13SVyacheslav Levytskyy; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} 31268cf64SAndrey Tretyakov 4f8a21dffSNatalie Chouinard; TODO(#60133): Requires updates following opaque pointer migration. 5f8a21dffSNatalie Chouinard; XFAIL: * 6f8a21dffSNatalie Chouinard 71268cf64SAndrey Tretyakov;; There are no blocks in SPIR-V. Therefore they are translated into regular 81268cf64SAndrey Tretyakov;; functions. An LLVM module which uses blocks, also contains some auxiliary 91268cf64SAndrey Tretyakov;; block-specific instructions, which are redundant in SPIR-V and should be 101268cf64SAndrey Tretyakov;; removed 111268cf64SAndrey Tretyakov 121268cf64SAndrey Tretyakov;; kernel void block_kernel(__global int* res) { 131268cf64SAndrey Tretyakov;; typedef int (^block_t)(int); 141268cf64SAndrey Tretyakov;; constant block_t b1 = ^(int i) { return i + 1; }; 151268cf64SAndrey Tretyakov;; *res = b1(5); 161268cf64SAndrey Tretyakov;; } 171268cf64SAndrey Tretyakov 181268cf64SAndrey Tretyakov; CHECK-SPIRV1_4: OpEntryPoint Kernel %[[#]] "block_kernel" %[[#InterfaceId:]] 191268cf64SAndrey Tretyakov; CHECK-SPIRV1_4: OpName %[[#InterfaceId]] "__block_literal_global" 201268cf64SAndrey Tretyakov; CHECK-SPIRV: OpName %[[#block_invoke:]] "_block_invoke" 211268cf64SAndrey Tretyakov; CHECK-SPIRV: %[[#int:]] = OpTypeInt 32 221268cf64SAndrey Tretyakov; CHECK-SPIRV: %[[#int8:]] = OpTypeInt 8 231268cf64SAndrey Tretyakov; CHECK-SPIRV: %[[#int8Ptr:]] = OpTypePointer Generic %[[#int8]] 241268cf64SAndrey Tretyakov; CHECK-SPIRV: %[[#block_invoke_type:]] = OpTypeFunction %[[#int]] %[[#int8Ptr]] %[[#int]] 251268cf64SAndrey Tretyakov; CHECK-SPIRV: %[[#five:]] = OpConstant %[[#int]] 5 261268cf64SAndrey Tretyakov 271268cf64SAndrey Tretyakov; CHECK-SPIRV: %[[#]] = OpFunctionCall %[[#int]] %[[#block_invoke]] %[[#]] %[[#five]] 281268cf64SAndrey Tretyakov 291268cf64SAndrey Tretyakov; CHECK-SPIRV: %[[#block_invoke]] = OpFunction %[[#int]] DontInline %[[#block_invoke_type]] 301268cf64SAndrey Tretyakov; CHECK-SPIRV-NEXT: %[[#]] = OpFunctionParameter %[[#int8Ptr]] 311268cf64SAndrey Tretyakov; CHECK-SPIRV-NEXT: %[[#]] = OpFunctionParameter %[[#int]] 321268cf64SAndrey Tretyakov 331268cf64SAndrey Tretyakov%struct.__opencl_block_literal_generic = type { i32, i32, i8 addrspace(4)* } 341268cf64SAndrey Tretyakov 351268cf64SAndrey Tretyakov@block_kernel.b1 = internal addrspace(2) constant %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* @__block_literal_global to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), align 4 361268cf64SAndrey Tretyakov@__block_literal_global = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 12, i32 4, i8 addrspace(4)* addrspacecast (i8* bitcast (i32 (i8 addrspace(4)*, i32)* @_block_invoke to i8*) to i8 addrspace(4)*) }, align 4 371268cf64SAndrey Tretyakov 381268cf64SAndrey Tretyakovdefine dso_local spir_kernel void @block_kernel(i32 addrspace(1)* noundef %res) { 391268cf64SAndrey Tretyakoventry: 401268cf64SAndrey Tretyakov %res.addr = alloca i32 addrspace(1)*, align 4 411268cf64SAndrey Tretyakov store i32 addrspace(1)* %res, i32 addrspace(1)** %res.addr, align 4 421268cf64SAndrey Tretyakov %call = call spir_func i32 @_block_invoke(i8 addrspace(4)* noundef addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* @__block_literal_global to i8 addrspace(1)*) to i8 addrspace(4)*), i32 noundef 5) 431268cf64SAndrey Tretyakov %0 = load i32 addrspace(1)*, i32 addrspace(1)** %res.addr, align 4 441268cf64SAndrey Tretyakov store i32 %call, i32 addrspace(1)* %0, align 4 451268cf64SAndrey Tretyakov ret void 461268cf64SAndrey Tretyakov} 471268cf64SAndrey Tretyakov 481268cf64SAndrey Tretyakovdefine internal spir_func i32 @_block_invoke(i8 addrspace(4)* noundef %.block_descriptor, i32 noundef %i) #0 { 491268cf64SAndrey Tretyakoventry: 501268cf64SAndrey Tretyakov %.block_descriptor.addr = alloca i8 addrspace(4)*, align 4 511268cf64SAndrey Tretyakov %i.addr = alloca i32, align 4 521268cf64SAndrey Tretyakov %block.addr = alloca <{ i32, i32, i8 addrspace(4)* }> addrspace(4)*, align 4 531268cf64SAndrey Tretyakov store i8 addrspace(4)* %.block_descriptor, i8 addrspace(4)** %.block_descriptor.addr, align 4 541268cf64SAndrey Tretyakov %block = bitcast i8 addrspace(4)* %.block_descriptor to <{ i32, i32, i8 addrspace(4)* }> addrspace(4)* 551268cf64SAndrey Tretyakov store i32 %i, i32* %i.addr, align 4 561268cf64SAndrey Tretyakov store <{ i32, i32, i8 addrspace(4)* }> addrspace(4)* %block, <{ i32, i32, i8 addrspace(4)* }> addrspace(4)** %block.addr, align 4 571268cf64SAndrey Tretyakov %0 = load i32, i32* %i.addr, align 4 581268cf64SAndrey Tretyakov %add = add nsw i32 %0, 1 591268cf64SAndrey Tretyakov ret i32 %add 601268cf64SAndrey Tretyakov} 611268cf64SAndrey Tretyakov 621268cf64SAndrey Tretyakovattributes #0 = { noinline } 63