1// RUN: mlir-opt -test-spirv-module-combiner -split-input-file -verify-diagnostics %s | FileCheck %s
2
3// Deduplicate 2 global variables with the same descriptor set and binding.
4
5// CHECK:      module {
6// CHECK-NEXT:   spv.module Logical GLSL450 {
7// CHECK-NEXT:     spv.globalVariable @foo
8
9// CHECK-NEXT:     spv.func @use_foo
10// CHECK-NEXT:       spv.mlir.addressof @foo
11// CHECK-NEXT:       spv.Load
12// CHECK-NEXT:       spv.ReturnValue
13// CHECK-NEXT:     }
14
15// CHECK-NEXT:     spv.func @use_bar
16// CHECK-NEXT:       spv.mlir.addressof @foo
17// CHECK-NEXT:       spv.Load
18// CHECK-NEXT:       spv.FAdd
19// CHECK-NEXT:       spv.ReturnValue
20// CHECK-NEXT:     }
21// CHECK-NEXT:   }
22// CHECK-NEXT: }
23
24module {
25spv.module Logical GLSL450 {
26  spv.globalVariable @foo bind(1, 0) : !spv.ptr<f32, Input>
27
28  spv.func @use_foo() -> f32 "None" {
29    %0 = spv.mlir.addressof @foo : !spv.ptr<f32, Input>
30    %1 = spv.Load "Input" %0 : f32
31    spv.ReturnValue %1 : f32
32  }
33}
34
35spv.module Logical GLSL450 {
36  spv.globalVariable @bar bind(1, 0) : !spv.ptr<f32, Input>
37
38  spv.func @use_bar() -> f32 "None" {
39    %0 = spv.mlir.addressof @bar : !spv.ptr<f32, Input>
40    %1 = spv.Load "Input" %0 : f32
41    %2 = spv.FAdd %1, %1 : f32
42    spv.ReturnValue %2 : f32
43  }
44}
45}
46
47// -----
48
49// Deduplicate 2 global variables with the same descriptor set and binding but different types.
50
51// CHECK:      module {
52// CHECK-NEXT: spv.module Logical GLSL450 {
53// CHECK-NEXT:   spv.globalVariable @foo bind(1, 0)
54
55// CHECK-NEXT:   spv.globalVariable @bar bind(1, 0)
56
57// CHECK-NEXT:   spv.func @use_bar
58// CHECK-NEXT:     spv.mlir.addressof @bar
59// CHECK-NEXT:     spv.Load
60// CHECK-NEXT:     spv.ReturnValue
61// CHECK-NEXT:   }
62// CHECK-NEXT: }
63// CHECK-NEXT: }
64
65module {
66spv.module Logical GLSL450 {
67  spv.globalVariable @foo bind(1, 0) : !spv.ptr<i32, Input>
68}
69
70spv.module Logical GLSL450 {
71  spv.globalVariable @bar bind(1, 0) : !spv.ptr<f32, Input>
72
73  spv.func @use_bar() -> f32 "None" {
74    %0 = spv.mlir.addressof @bar : !spv.ptr<f32, Input>
75    %1 = spv.Load "Input" %0 : f32
76    spv.ReturnValue %1 : f32
77  }
78}
79}
80
81// -----
82
83// Deduplicate 2 global variables with the same built-in attribute.
84
85// CHECK:      module {
86// CHECK-NEXT:   spv.module Logical GLSL450 {
87// CHECK-NEXT:     spv.globalVariable @foo built_in("GlobalInvocationId")
88// CHECK-NEXT:     spv.func @use_bar
89// CHECK-NEXT:       spv.mlir.addressof @foo
90// CHECK-NEXT:       spv.Load
91// CHECK-NEXT:       spv.ReturnValue
92// CHECK-NEXT:     }
93// CHECK-NEXT:   }
94// CHECK-NEXT: }
95
96module {
97spv.module Logical GLSL450 {
98  spv.globalVariable @foo built_in("GlobalInvocationId") : !spv.ptr<vector<3xi32>, Input>
99}
100
101spv.module Logical GLSL450 {
102  spv.globalVariable @bar built_in("GlobalInvocationId") : !spv.ptr<vector<3xi32>, Input>
103
104  spv.func @use_bar() -> vector<3xi32> "None" {
105    %0 = spv.mlir.addressof @bar : !spv.ptr<vector<3xi32>, Input>
106    %1 = spv.Load "Input" %0 : vector<3xi32>
107    spv.ReturnValue %1 : vector<3xi32>
108  }
109}
110}
111
112// -----
113
114// CHECK:      module {
115// CHECK-NEXT:   spv.module Logical GLSL450 {
116// CHECK-NEXT:     spv.specConstant @foo spec_id(5)
117
118// CHECK-NEXT:     spv.func @use_foo()
119// CHECK-NEXT:       %0 = spv.mlir.referenceof @foo
120// CHECK-NEXT:       spv.ReturnValue
121// CHECK-NEXT:     }
122
123// CHECK-NEXT:     spv.func @use_bar()
124// CHECK-NEXT:       %0 = spv.mlir.referenceof @foo
125// CHECK-NEXT:       spv.FAdd
126// CHECK-NEXT:       spv.ReturnValue
127// CHECK-NEXT:     }
128// CHECK-NEXT:   }
129// CHECK-NEXT: }
130
131module {
132spv.module Logical GLSL450 {
133  spv.specConstant @foo spec_id(5) = 1. : f32
134
135  spv.func @use_foo() -> (f32) "None" {
136    %0 = spv.mlir.referenceof @foo : f32
137    spv.ReturnValue %0 : f32
138  }
139}
140
141spv.module Logical GLSL450 {
142  spv.specConstant @bar spec_id(5) = 1. : f32
143
144  spv.func @use_bar() -> (f32) "None" {
145    %0 = spv.mlir.referenceof @bar : f32
146    %1 = spv.FAdd %0, %0 : f32
147    spv.ReturnValue %1 : f32
148  }
149}
150}
151
152// -----
153
154// CHECK:      module {
155// CHECK-NEXT:   spv.module Logical GLSL450 {
156// CHECK-NEXT:     spv.specConstant @bar spec_id(5)
157
158// CHECK-NEXT:     spv.func @foo(%arg0: f32)
159// CHECK-NEXT:       spv.ReturnValue
160// CHECK-NEXT:     }
161
162// CHECK-NEXT:     spv.func @foo_different_body(%arg0: f32)
163// CHECK-NEXT:       spv.mlir.referenceof
164// CHECK-NEXT:       spv.ReturnValue
165// CHECK-NEXT:     }
166
167// CHECK-NEXT:     spv.func @baz(%arg0: i32)
168// CHECK-NEXT:       spv.ReturnValue
169// CHECK-NEXT:     }
170
171// CHECK-NEXT:     spv.func @baz_no_return(%arg0: i32)
172// CHECK-NEXT:       spv.Return
173// CHECK-NEXT:     }
174
175// CHECK-NEXT:     spv.func @baz_no_return_different_control
176// CHECK-NEXT:       spv.Return
177// CHECK-NEXT:     }
178
179// CHECK-NEXT:     spv.func @baz_no_return_another_control
180// CHECK-NEXT:       spv.Return
181// CHECK-NEXT:     }
182
183// CHECK-NEXT:     spv.func @kernel
184// CHECK-NEXT:       spv.Return
185// CHECK-NEXT:     }
186
187// CHECK-NEXT:     spv.func @kernel_different_attr
188// CHECK-NEXT:       spv.Return
189// CHECK-NEXT:     }
190// CHECK-NEXT:   }
191// CHECK-NEXT:   }
192
193module {
194spv.module Logical GLSL450 {
195  spv.specConstant @bar spec_id(5) = 1. : f32
196
197  spv.func @foo(%arg0: f32) -> (f32) "None" {
198    spv.ReturnValue %arg0 : f32
199  }
200
201  spv.func @foo_duplicate(%arg0: f32) -> (f32) "None" {
202    spv.ReturnValue %arg0 : f32
203  }
204
205  spv.func @foo_different_body(%arg0: f32) -> (f32) "None" {
206    %0 = spv.mlir.referenceof @bar : f32
207    spv.ReturnValue %arg0 : f32
208  }
209
210  spv.func @baz(%arg0: i32) -> (i32) "None" {
211    spv.ReturnValue %arg0 : i32
212  }
213
214  spv.func @baz_no_return(%arg0: i32) "None" {
215    spv.Return
216  }
217
218  spv.func @baz_no_return_duplicate(%arg0: i32) -> () "None" {
219    spv.Return
220  }
221
222  spv.func @baz_no_return_different_control(%arg0: i32) -> () "Inline" {
223    spv.Return
224  }
225
226  spv.func @baz_no_return_another_control(%arg0: i32) -> () "Inline|Pure" {
227    spv.Return
228  }
229
230  spv.func @kernel(
231    %arg0: f32,
232    %arg1: !spv.ptr<!spv.struct<(!spv.array<12 x f32>)>, CrossWorkgroup>) "None"
233  attributes {spv.entry_point_abi = {local_size = dense<[32, 1, 1]> : vector<3xi32>}} {
234    spv.Return
235  }
236
237  spv.func @kernel_different_attr(
238    %arg0: f32,
239    %arg1: !spv.ptr<!spv.struct<(!spv.array<12 x f32>)>, CrossWorkgroup>) "None"
240  attributes {spv.entry_point_abi = {local_size = dense<[64, 1, 1]> : vector<3xi32>}} {
241    spv.Return
242  }
243}
244}
245