1; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s 2; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} 3 4; CHECK-DAG: OpName %[[I9:.*]] "_ZN13BaseIncrement9incrementEPi" 5; CHECK-DAG: OpName %[[I29:.*]] "_ZN12IncrementBy29incrementEPi" 6; CHECK-DAG: OpName %[[I49:.*]] "_ZN12IncrementBy49incrementEPi" 7; CHECK-DAG: OpName %[[I89:.*]] "_ZN12IncrementBy89incrementEPi" 8; CHECK-DAG: OpName %[[Foo:.*]] "foo" 9 10; CHECK-DAG: %[[TyVoid:.*]] = OpTypeVoid 11; CHECK-DAG: %[[TyInt32:.*]] = OpTypeInt 32 0 12; CHECK-DAG: %[[TyInt8:.*]] = OpTypeInt 8 0 13; CHECK-DAG: %[[Const8:.*]] = OpConstant %[[TyInt32]] 8 14; CHECK-DAG: %[[TyArr:.*]] = OpTypeArray %[[TyInt8]] %[[Const8]] 15; CHECK-DAG: %[[TyStruct1:.*]] = OpTypeStruct %[[TyArr]] 16; CHECK-DAG: %[[TyStruct2:.*]] = OpTypeStruct %[[TyStruct1]] 17; CHECK-DAG: %[[TyPtrStruct2:.*]] = OpTypePointer Generic %[[TyStruct2]] 18; CHECK-DAG: %[[TyFun:.*]] = OpTypeFunction %[[TyVoid]] %[[TyPtrStruct2]] %[[#]] 19; CHECK-DAG: %[[TyPtrFun:.*]] = OpTypePointer Generic %[[TyFun]] 20; CHECK-DAG: %[[TyPtrPtrFun:.*]] = OpTypePointer Generic %[[TyPtrFun]] 21 22; CHECK-DAG: %[[I9]] = OpFunction 23; CHECK-DAG: %[[I29]] = OpFunction 24; CHECK-DAG: %[[I49]] = OpFunction 25; CHECK-DAG: %[[I89]] = OpFunction 26 27; CHECK: %[[Foo]] = OpFunction 28; CHECK-4: OpFunctionParameter 29 30; CHECK: %[[Arg1:.*]] = OpPhi %[[TyPtrStruct2]] 31; CHECK: %[[VTbl:.*]] = OpBitcast %[[TyPtrPtrFun]] %[[#]] 32; CHECK: %[[FP:.*]] = OpLoad %[[TyPtrFun]] %[[VTbl]] 33; CHECK: %[[#]] = OpFunctionPointerCallINTEL %[[TyVoid]] %[[FP]] %[[Arg1]] %[[#]] 34 35; CHECK-NO: OpFunction 36 37%"cls::id" = type { %"cls::detail::array" } 38%"cls::detail::array" = type { [1 x i64] } 39%struct.obj_storage_t = type { %"struct.aligned_storage<BaseIncrement, IncrementBy2, IncrementBy4, IncrementBy8>::type" } 40%"struct.aligned_storage<BaseIncrement, IncrementBy2, IncrementBy4, IncrementBy8>::type" = type { [8 x i8] } 41 42@_ZTV12IncrementBy8 = linkonce_odr dso_local unnamed_addr addrspace(1) constant { [3 x ptr addrspace(4)] } { [3 x ptr addrspace(4)] [ptr addrspace(4) null, ptr addrspace(4) null, ptr addrspace(4) addrspacecast (ptr @_ZN12IncrementBy89incrementEPi to ptr addrspace(4))] }, align 8 43@_ZTV13BaseIncrement = linkonce_odr dso_local unnamed_addr addrspace(1) constant { [3 x ptr addrspace(4)] } { [3 x ptr addrspace(4)] [ptr addrspace(4) null, ptr addrspace(4) null, ptr addrspace(4) addrspacecast (ptr @_ZN13BaseIncrement9incrementEPi to ptr addrspace(4))] }, align 8 44@_ZTV12IncrementBy4 = linkonce_odr dso_local unnamed_addr addrspace(1) constant { [3 x ptr addrspace(4)] } { [3 x ptr addrspace(4)] [ptr addrspace(4) null, ptr addrspace(4) null, ptr addrspace(4) addrspacecast (ptr @_ZN12IncrementBy49incrementEPi to ptr addrspace(4))] }, align 8 45@_ZTV12IncrementBy2 = linkonce_odr dso_local unnamed_addr addrspace(1) constant { [3 x ptr addrspace(4)] } { [3 x ptr addrspace(4)] [ptr addrspace(4) null, ptr addrspace(4) null, ptr addrspace(4) addrspacecast (ptr @_ZN12IncrementBy29incrementEPi to ptr addrspace(4))] }, align 8 46@__spirv_BuiltInWorkgroupId = external dso_local local_unnamed_addr addrspace(1) constant <3 x i64>, align 32 47@__spirv_BuiltInGlobalLinearId = external dso_local local_unnamed_addr addrspace(1) constant i64, align 8 48@__spirv_BuiltInWorkgroupSize = external dso_local local_unnamed_addr addrspace(1) constant <3 x i64>, align 32 49 50define weak_odr dso_local spir_kernel void @foo(ptr addrspace(1) noundef align 8 %_arg_StorageAcc, ptr noundef byval(%"cls::id") align 8 %_arg_StorageAcc3, i32 noundef %_arg_TestCase, ptr addrspace(1) noundef align 4 %_arg_DataAcc) { 51entry: 52 %r0 = load i64, ptr %_arg_StorageAcc3, align 8 53 %add.ptr.i = getelementptr inbounds %struct.obj_storage_t, ptr addrspace(1) %_arg_StorageAcc, i64 %r0 54 %arrayidx.ascast.i = addrspacecast ptr addrspace(1) %add.ptr.i to ptr addrspace(4) 55 %cmp.i = icmp ugt i32 %_arg_TestCase, 3 56 br i1 %cmp.i, label %entry.critedge, label %if.end.1 57 58entry.critedge: ; preds = %entry 59 %vtable.i.pre = load ptr addrspace(4), ptr addrspace(4) null, align 8 60 br label %exit 61 62if.end.1: ; preds = %entry 63 switch i32 %_arg_TestCase, label %if.end.5 [ 64 i32 0, label %if.end.2 65 i32 1, label %if.end.3 66 i32 2, label %if.end.4 67 ] 68 69if.end.5: ; preds = %if.end.1 70 store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) (i8, ptr addrspace(1) @_ZTV12IncrementBy8, i64 16), ptr addrspace(1) %add.ptr.i, align 8 71 br label %exit 72 73if.end.4: ; preds = %if.end.1 74 store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) (i8, ptr addrspace(1) @_ZTV12IncrementBy4, i64 16), ptr addrspace(1) %add.ptr.i, align 8 75 br label %exit 76 77if.end.3: ; preds = %if.end.1 78 store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) (i8, ptr addrspace(1) @_ZTV12IncrementBy2, i64 16), ptr addrspace(1) %add.ptr.i, align 8 79 br label %exit 80 81if.end.2: ; preds = %if.end.1 82 store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) (i8, ptr addrspace(1) @_ZTV13BaseIncrement, i64 16), ptr addrspace(1) %add.ptr.i, align 8 83 br label %exit 84 85exit: ; preds = %if.end.2, %if.end.3, %if.end.4, %if.end.5, %entry.critedge 86 %vtable.i = phi ptr addrspace(4) [ %vtable.i.pre, %entry.critedge ], [ inttoptr (i64 ptrtoint (ptr addrspace(1) getelementptr inbounds inrange(-16, 8) (i8, ptr addrspace(1) @_ZTV12IncrementBy8, i64 16) to i64) to ptr addrspace(4)), %if.end.5 ], [ inttoptr (i64 ptrtoint (ptr addrspace(1) getelementptr inbounds inrange(-16, 8) (i8, ptr addrspace(1) @_ZTV12IncrementBy4, i64 16) to i64) to ptr addrspace(4)), %if.end.4 ], [ inttoptr (i64 ptrtoint (ptr addrspace(1) getelementptr inbounds inrange(-16, 8) (i8, ptr addrspace(1) @_ZTV12IncrementBy2, i64 16) to i64) to ptr addrspace(4)), %if.end.3 ], [ inttoptr (i64 ptrtoint (ptr addrspace(1) getelementptr inbounds inrange(-16, 8) (i8, ptr addrspace(1) @_ZTV13BaseIncrement, i64 16) to i64) to ptr addrspace(4)), %if.end.2 ] 87 %retval.0.i = phi ptr addrspace(4) [ null, %entry.critedge ], [ %arrayidx.ascast.i, %if.end.5 ], [ %arrayidx.ascast.i, %if.end.4 ], [ %arrayidx.ascast.i, %if.end.3 ], [ %arrayidx.ascast.i, %if.end.2 ] 88 %r1 = addrspacecast ptr addrspace(1) %_arg_DataAcc to ptr addrspace(4) 89 %r2 = load ptr addrspace(4), ptr addrspace(4) %vtable.i, align 8 90 tail call spir_func addrspace(4) void %r2(ptr addrspace(4) noundef align 8 dereferenceable_or_null(8) %retval.0.i, ptr addrspace(4) noundef %r1) 91 ret void 92} 93 94declare dso_local spir_func void @_ZN13BaseIncrement9incrementEPi(ptr addrspace(4) noundef align 8 dereferenceable_or_null(8), ptr addrspace(4) noundef) 95declare dso_local spir_func void @_ZN12IncrementBy29incrementEPi(ptr addrspace(4) noundef align 8 dereferenceable_or_null(8), ptr addrspace(4) noundef) 96declare dso_local spir_func void @_ZN12IncrementBy49incrementEPi(ptr addrspace(4) noundef align 8 dereferenceable_or_null(8), ptr addrspace(4) noundef) 97declare dso_local spir_func void @_ZN12IncrementBy89incrementEPi(ptr addrspace(4) noundef align 8 dereferenceable_or_null(8), ptr addrspace(4) noundef) 98