1// RUN: mlir-opt -spirv-lower-abi-attrs -verify-diagnostics %s -o - | FileCheck %s
2
3module attributes {
4  spv.target_env = #spv.target_env<
5    #spv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, {}>
6} {
7
8// CHECK-LABEL: spv.module
9spv.module Logical GLSL450 {
10  // CHECK-DAG: spv.globalVariable [[WORKGROUPSIZE:@.*]] built_in("WorkgroupSize")
11  spv.globalVariable @__builtin_var_WorkgroupSize__ built_in("WorkgroupSize") : !spv.ptr<vector<3xi32>, Input>
12  // CHECK-DAG: spv.globalVariable [[NUMWORKGROUPS:@.*]] built_in("NumWorkgroups")
13  spv.globalVariable @__builtin_var_NumWorkgroups__ built_in("NumWorkgroups") : !spv.ptr<vector<3xi32>, Input>
14  // CHECK-DAG: spv.globalVariable [[LOCALINVOCATIONID:@.*]] built_in("LocalInvocationId")
15  spv.globalVariable @__builtin_var_LocalInvocationId__ built_in("LocalInvocationId") : !spv.ptr<vector<3xi32>, Input>
16  // CHECK-DAG: spv.globalVariable [[WORKGROUPID:@.*]] built_in("WorkgroupId")
17  spv.globalVariable @__builtin_var_WorkgroupId__ built_in("WorkgroupId") : !spv.ptr<vector<3xi32>, Input>
18  // CHECK-DAG: spv.globalVariable [[VAR0:@.*]] bind(0, 0) : !spv.ptr<!spv.struct<(!spv.array<12 x !spv.array<4 x f32, stride=4>, stride=16> [0])>, StorageBuffer>
19  // CHECK-DAG: spv.globalVariable [[VAR1:@.*]] bind(0, 1) : !spv.ptr<!spv.struct<(!spv.array<12 x !spv.array<4 x f32, stride=4>, stride=16> [0])>, StorageBuffer>
20  // CHECK-DAG: spv.globalVariable [[VAR2:@.*]] bind(0, 2) : !spv.ptr<!spv.struct<(!spv.array<12 x !spv.array<4 x f32, stride=4>, stride=16> [0])>, StorageBuffer>
21  // CHECK-DAG: spv.globalVariable [[VAR3:@.*]] bind(0, 3) : !spv.ptr<!spv.struct<(i32 [0])>, StorageBuffer>
22  // CHECK-DAG: spv.globalVariable [[VAR4:@.*]] bind(0, 4) : !spv.ptr<!spv.struct<(i32 [0])>, StorageBuffer>
23  // CHECK-DAG: spv.globalVariable [[VAR5:@.*]] bind(0, 5) : !spv.ptr<!spv.struct<(i32 [0])>, StorageBuffer>
24  // CHECK-DAG: spv.globalVariable [[VAR6:@.*]] bind(0, 6) : !spv.ptr<!spv.struct<(i32 [0])>, StorageBuffer>
25  // CHECK: spv.func [[FN:@.*]]()
26  spv.func @load_store_kernel(
27    %arg0: !spv.ptr<!spv.struct<(!spv.array<12 x !spv.array<4 x f32>>)>, StorageBuffer>
28    {spv.interface_var_abi = #spv.interface_var_abi<(0, 0)>},
29    %arg1: !spv.ptr<!spv.struct<(!spv.array<12 x !spv.array<4 x f32>>)>, StorageBuffer>
30    {spv.interface_var_abi = #spv.interface_var_abi<(0, 1)>},
31    %arg2: !spv.ptr<!spv.struct<(!spv.array<12 x !spv.array<4 x f32>>)>, StorageBuffer>
32    {spv.interface_var_abi = #spv.interface_var_abi<(0, 2)>},
33    %arg3: i32
34    {spv.interface_var_abi = #spv.interface_var_abi<(0, 3), StorageBuffer>},
35    %arg4: i32
36    {spv.interface_var_abi = #spv.interface_var_abi<(0, 4), StorageBuffer>},
37    %arg5: i32
38    {spv.interface_var_abi = #spv.interface_var_abi<(0, 5), StorageBuffer>},
39    %arg6: i32
40    {spv.interface_var_abi = #spv.interface_var_abi<(0, 6), StorageBuffer>}) "None"
41  attributes  {spv.entry_point_abi = {local_size = dense<[32, 1, 1]> : vector<3xi32>}} {
42    // CHECK: [[ADDRESSARG6:%.*]] = spv.mlir.addressof [[VAR6]]
43    // CHECK: [[CONST6:%.*]] = spv.constant 0 : i32
44    // CHECK: [[ARG6PTR:%.*]] = spv.AccessChain [[ADDRESSARG6]]{{\[}}[[CONST6]]
45    // CHECK: {{%.*}} = spv.Load "StorageBuffer" [[ARG6PTR]]
46    // CHECK: [[ADDRESSARG5:%.*]] = spv.mlir.addressof [[VAR5]]
47    // CHECK: [[CONST5:%.*]] = spv.constant 0 : i32
48    // CHECK: [[ARG5PTR:%.*]] = spv.AccessChain [[ADDRESSARG5]]{{\[}}[[CONST5]]
49    // CHECK: {{%.*}} = spv.Load "StorageBuffer" [[ARG5PTR]]
50    // CHECK: [[ADDRESSARG4:%.*]] = spv.mlir.addressof [[VAR4]]
51    // CHECK: [[CONST4:%.*]] = spv.constant 0 : i32
52    // CHECK: [[ARG4PTR:%.*]] = spv.AccessChain [[ADDRESSARG4]]{{\[}}[[CONST4]]
53    // CHECK: [[ARG4:%.*]] = spv.Load "StorageBuffer" [[ARG4PTR]]
54    // CHECK: [[ADDRESSARG3:%.*]] = spv.mlir.addressof [[VAR3]]
55    // CHECK: [[CONST3:%.*]] = spv.constant 0 : i32
56    // CHECK: [[ARG3PTR:%.*]] = spv.AccessChain [[ADDRESSARG3]]{{\[}}[[CONST3]]
57    // CHECK: [[ARG3:%.*]] = spv.Load "StorageBuffer" [[ARG3PTR]]
58    // CHECK: [[ADDRESSARG2:%.*]] = spv.mlir.addressof [[VAR2]]
59    // CHECK: [[ARG2:%.*]] = spv.Bitcast [[ADDRESSARG2]]
60    // CHECK: [[ADDRESSARG1:%.*]] = spv.mlir.addressof [[VAR1]]
61    // CHECK: [[ARG1:%.*]] = spv.Bitcast [[ADDRESSARG1]]
62    // CHECK: [[ADDRESSARG0:%.*]] = spv.mlir.addressof [[VAR0]]
63    // CHECK: [[ARG0:%.*]] = spv.Bitcast [[ADDRESSARG0]]
64    %0 = spv.mlir.addressof @__builtin_var_WorkgroupId__ : !spv.ptr<vector<3xi32>, Input>
65    %1 = spv.Load "Input" %0 : vector<3xi32>
66    %2 = spv.CompositeExtract %1[0 : i32] : vector<3xi32>
67    %3 = spv.mlir.addressof @__builtin_var_WorkgroupId__ : !spv.ptr<vector<3xi32>, Input>
68    %4 = spv.Load "Input" %3 : vector<3xi32>
69    %5 = spv.CompositeExtract %4[1 : i32] : vector<3xi32>
70    %6 = spv.mlir.addressof @__builtin_var_WorkgroupId__ : !spv.ptr<vector<3xi32>, Input>
71    %7 = spv.Load "Input" %6 : vector<3xi32>
72    %8 = spv.CompositeExtract %7[2 : i32] : vector<3xi32>
73    %9 = spv.mlir.addressof @__builtin_var_LocalInvocationId__ : !spv.ptr<vector<3xi32>, Input>
74    %10 = spv.Load "Input" %9 : vector<3xi32>
75    %11 = spv.CompositeExtract %10[0 : i32] : vector<3xi32>
76    %12 = spv.mlir.addressof @__builtin_var_LocalInvocationId__ : !spv.ptr<vector<3xi32>, Input>
77    %13 = spv.Load "Input" %12 : vector<3xi32>
78    %14 = spv.CompositeExtract %13[1 : i32] : vector<3xi32>
79    %15 = spv.mlir.addressof @__builtin_var_LocalInvocationId__ : !spv.ptr<vector<3xi32>, Input>
80    %16 = spv.Load "Input" %15 : vector<3xi32>
81    %17 = spv.CompositeExtract %16[2 : i32] : vector<3xi32>
82    %18 = spv.mlir.addressof @__builtin_var_NumWorkgroups__ : !spv.ptr<vector<3xi32>, Input>
83    %19 = spv.Load "Input" %18 : vector<3xi32>
84    %20 = spv.CompositeExtract %19[0 : i32] : vector<3xi32>
85    %21 = spv.mlir.addressof @__builtin_var_NumWorkgroups__ : !spv.ptr<vector<3xi32>, Input>
86    %22 = spv.Load "Input" %21 : vector<3xi32>
87    %23 = spv.CompositeExtract %22[1 : i32] : vector<3xi32>
88    %24 = spv.mlir.addressof @__builtin_var_NumWorkgroups__ : !spv.ptr<vector<3xi32>, Input>
89    %25 = spv.Load "Input" %24 : vector<3xi32>
90    %26 = spv.CompositeExtract %25[2 : i32] : vector<3xi32>
91    %27 = spv.mlir.addressof @__builtin_var_WorkgroupSize__ : !spv.ptr<vector<3xi32>, Input>
92    %28 = spv.Load "Input" %27 : vector<3xi32>
93    %29 = spv.CompositeExtract %28[0 : i32] : vector<3xi32>
94    %30 = spv.mlir.addressof @__builtin_var_WorkgroupSize__ : !spv.ptr<vector<3xi32>, Input>
95    %31 = spv.Load "Input" %30 : vector<3xi32>
96    %32 = spv.CompositeExtract %31[1 : i32] : vector<3xi32>
97    %33 = spv.mlir.addressof @__builtin_var_WorkgroupSize__ : !spv.ptr<vector<3xi32>, Input>
98    %34 = spv.Load "Input" %33 : vector<3xi32>
99    %35 = spv.CompositeExtract %34[2 : i32] : vector<3xi32>
100    // CHECK: spv.IAdd [[ARG3]]
101    %36 = spv.IAdd %arg3, %2 : i32
102    // CHECK: spv.IAdd [[ARG4]]
103    %37 = spv.IAdd %arg4, %11 : i32
104    // CHECK: spv.AccessChain [[ARG0]]
105    %c0 = spv.constant 0 : i32
106    %38 = spv.AccessChain %arg0[%c0, %36, %37] : !spv.ptr<!spv.struct<(!spv.array<12 x !spv.array<4 x f32>>)>, StorageBuffer>, i32, i32, i32
107    %39 = spv.Load "StorageBuffer" %38 : f32
108    // CHECK: spv.AccessChain [[ARG1]]
109    %40 = spv.AccessChain %arg1[%c0, %36, %37] : !spv.ptr<!spv.struct<(!spv.array<12 x !spv.array<4 x f32>>)>, StorageBuffer>, i32, i32, i32
110    %41 = spv.Load "StorageBuffer" %40 : f32
111    %42 = spv.FAdd %39, %41 : f32
112    // CHECK: spv.AccessChain [[ARG2]]
113    %43 = spv.AccessChain %arg2[%c0, %36, %37] : !spv.ptr<!spv.struct<(!spv.array<12 x !spv.array<4 x f32>>)>, StorageBuffer>, i32, i32, i32
114    spv.Store "StorageBuffer" %43, %42 : f32
115    spv.Return
116  }
117  // CHECK: spv.EntryPoint "GLCompute" [[FN]], [[WORKGROUPID]], [[LOCALINVOCATIONID]], [[NUMWORKGROUPS]], [[WORKGROUPSIZE]]
118  // CHECK-NEXT: spv.ExecutionMode [[FN]] "LocalSize", 32, 1, 1
119} // end spv.module
120
121} // end module
122