1// RUN: mlir-opt -test-spirv-module-combiner -split-input-file -verify-diagnostics %s | FileCheck %s
2
3// Test basic renaming of conflicting funcOps.
4
5// CHECK:      module {
6// CHECK-NEXT:   spv.module Logical GLSL450 {
7// CHECK-NEXT:     spv.func @foo
8// CHECK-NEXT:       spv.ReturnValue
9// CHECK-NEXT:     }
10
11// CHECK-NEXT:     spv.func @foo_1
12// CHECK-NEXT:       spv.ReturnValue
13// CHECK-NEXT:     }
14// CHECK-NEXT:   }
15// CHECK-NEXT: }
16
17module {
18spv.module Logical GLSL450 {
19  spv.func @foo(%arg0 : i32) -> i32 "None" {
20    spv.ReturnValue %arg0 : i32
21  }
22}
23
24spv.module Logical GLSL450 {
25  spv.func @foo(%arg0 : f32) -> f32 "None" {
26    spv.ReturnValue %arg0 : f32
27  }
28}
29}
30
31// -----
32
33// Test basic renaming of conflicting funcOps across 3 modules.
34
35// CHECK:      module {
36// CHECK-NEXT:   spv.module Logical GLSL450 {
37// CHECK-NEXT:     spv.func @foo
38// CHECK-NEXT:       spv.ReturnValue
39// CHECK-NEXT:     }
40
41// CHECK-NEXT:     spv.func @foo_1
42// CHECK-NEXT:       spv.FAdd
43// CHECK-NEXT:       spv.ReturnValue
44// CHECK-NEXT:     }
45
46// CHECK-NEXT:     spv.func @foo_2
47// CHECK-NEXT:       spv.ISub
48// CHECK-NEXT:       spv.ReturnValue
49// CHECK-NEXT:     }
50// CHECK-NEXT:   }
51// CHECK-NEXT: }
52
53module {
54spv.module Logical GLSL450 {
55  spv.func @foo(%arg0 : i32) -> i32 "None" {
56    spv.ReturnValue %arg0 : i32
57  }
58}
59
60spv.module Logical GLSL450 {
61  spv.func @foo(%arg0 : f32) -> f32 "None" {
62    %0 = spv.FAdd %arg0, %arg0 : f32
63    spv.ReturnValue %0 : f32
64  }
65}
66
67spv.module Logical GLSL450 {
68  spv.func @foo(%arg0 : i32) -> i32 "None" {
69    %0 = spv.ISub %arg0, %arg0 : i32
70    spv.ReturnValue %0 : i32
71  }
72}
73}
74
75// -----
76
77// Test properly updating references to a renamed funcOp.
78
79// CHECK:      module {
80// CHECK-NEXT:   spv.module Logical GLSL450 {
81// CHECK-NEXT:     spv.func @foo
82// CHECK-NEXT:       spv.ReturnValue
83// CHECK-NEXT:     }
84
85// CHECK-NEXT:     spv.func @foo_1
86// CHECK-NEXT:       spv.ReturnValue
87// CHECK-NEXT:     }
88
89// CHECK-NEXT:     spv.func @bar
90// CHECK-NEXT:       spv.FunctionCall @foo_1
91// CHECK-NEXT:       spv.ReturnValue
92// CHECK-NEXT:     }
93// CHECK-NEXT:   }
94// CHECK-NEXT: }
95
96module {
97spv.module Logical GLSL450 {
98  spv.func @foo(%arg0 : i32) -> i32 "None" {
99    spv.ReturnValue %arg0 : i32
100  }
101}
102
103spv.module Logical GLSL450 {
104  spv.func @foo(%arg0 : f32) -> f32 "None" {
105    spv.ReturnValue %arg0 : f32
106  }
107
108  spv.func @bar(%arg0 : f32) -> f32 "None" {
109    %0 = spv.FunctionCall @foo(%arg0) : (f32) ->  (f32)
110    spv.ReturnValue %0 : f32
111  }
112}
113}
114
115// -----
116
117// Test properly updating references to a renamed funcOp if the functionCallOp
118// preceeds the callee funcOp definition.
119
120// CHECK:      module {
121// CHECK-NEXT:   spv.module Logical GLSL450 {
122// CHECK-NEXT:     spv.func @foo
123// CHECK-NEXT:       spv.ReturnValue
124// CHECK-NEXT:     }
125
126// CHECK-NEXT:     spv.func @bar
127// CHECK-NEXT:       spv.FunctionCall @foo_1
128// CHECK-NEXT:       spv.ReturnValue
129// CHECK-NEXT:     }
130
131// CHECK-NEXT:     spv.func @foo_1
132// CHECK-NEXT:       spv.ReturnValue
133// CHECK-NEXT:     }
134// CHECK-NEXT:   }
135// CHECK-NEXT: }
136
137module {
138spv.module Logical GLSL450 {
139  spv.func @foo(%arg0 : i32) -> i32 "None" {
140    spv.ReturnValue %arg0 : i32
141  }
142}
143
144spv.module Logical GLSL450 {
145  spv.func @bar(%arg0 : f32) -> f32 "None" {
146    %0 = spv.FunctionCall @foo(%arg0) : (f32) ->  (f32)
147    spv.ReturnValue %0 : f32
148  }
149
150  spv.func @foo(%arg0 : f32) -> f32 "None" {
151    spv.ReturnValue %arg0 : f32
152  }
153}
154}
155
156// -----
157
158// Test properly updating entryPointOp and executionModeOp attached to renamed
159// funcOp.
160
161// CHECK:      module {
162// CHECK-NEXT:   spv.module Logical GLSL450 {
163// CHECK-NEXT:     spv.func @foo
164// CHECK-NEXT:       spv.ReturnValue
165// CHECK-NEXT:     }
166
167// CHECK-NEXT:     spv.func @foo_1
168// CHECK-NEXT:       spv.ReturnValue
169// CHECK-NEXT:     }
170
171// CHECK-NEXT:     spv.EntryPoint "GLCompute" @foo_1
172// CHECK-NEXT:     spv.ExecutionMode @foo_1 "ContractionOff"
173// CHECK-NEXT:   }
174// CHECK-NEXT: }
175
176module {
177spv.module Logical GLSL450 {
178  spv.func @foo(%arg0 : i32) -> i32 "None" {
179    spv.ReturnValue %arg0 : i32
180  }
181}
182
183spv.module Logical GLSL450 {
184  spv.func @foo(%arg0 : f32) -> f32 "None" {
185    spv.ReturnValue %arg0 : f32
186  }
187
188  spv.EntryPoint "GLCompute" @foo
189  spv.ExecutionMode @foo "ContractionOff"
190}
191}
192
193// -----
194
195// CHECK:      module {
196// CHECK-NEXT:   spv.module Logical GLSL450 {
197// CHECK-NEXT:     spv.func @foo
198// CHECK-NEXT:       spv.ReturnValue
199// CHECK-NEXT:     }
200
201// CHECK-NEXT:     spv.EntryPoint "GLCompute" @fo
202// CHECK-NEXT:     spv.ExecutionMode @foo "ContractionOff"
203
204// CHECK-NEXT:     spv.func @foo_1
205// CHECK-NEXT:       spv.ReturnValue
206// CHECK-NEXT:     }
207
208// CHECK-NEXT:     spv.EntryPoint "GLCompute" @foo_1
209// CHECK-NEXT:     spv.ExecutionMode @foo_1 "ContractionOff"
210// CHECK-NEXT:   }
211// CHECK-NEXT: }
212
213module {
214spv.module Logical GLSL450 {
215  spv.func @foo(%arg0 : i32) -> i32 "None" {
216    spv.ReturnValue %arg0 : i32
217  }
218
219  spv.EntryPoint "GLCompute" @foo
220  spv.ExecutionMode @foo "ContractionOff"
221}
222
223spv.module Logical GLSL450 {
224  spv.func @foo(%arg0 : f32) -> f32 "None" {
225    spv.ReturnValue %arg0 : f32
226  }
227
228  spv.EntryPoint "GLCompute" @foo
229  spv.ExecutionMode @foo "ContractionOff"
230}
231}
232
233// -----
234
235// Resolve conflicting funcOp and globalVariableOp.
236
237// CHECK:      module {
238// CHECK-NEXT:   spv.module Logical GLSL450 {
239// CHECK-NEXT:     spv.func @foo
240// CHECK-NEXT:       spv.ReturnValue
241// CHECK-NEXT:     }
242
243// CHECK-NEXT:     spv.globalVariable @foo_1
244// CHECK-NEXT: }
245
246module {
247spv.module Logical GLSL450 {
248  spv.func @foo(%arg0 : i32) -> i32 "None" {
249    spv.ReturnValue %arg0 : i32
250  }
251}
252
253spv.module Logical GLSL450 {
254  spv.globalVariable @foo bind(1, 0) : !spv.ptr<f32, Input>
255}
256}
257
258// -----
259
260// Resolve conflicting funcOp and globalVariableOp and update the global variable's
261// references.
262
263// CHECK:      module {
264// CHECK-NEXT:   spv.module Logical GLSL450 {
265// CHECK-NEXT:     spv.func @foo
266// CHECK-NEXT:       spv.ReturnValue
267// CHECK-NEXT:     }
268
269// CHECK-NEXT:     spv.globalVariable @foo_1
270// CHECK-NEXT:     spv.func @bar
271// CHECK-NEXT:       spv.mlir.addressof @foo_1
272// CHECK-NEXT:       spv.Load
273// CHECK-NEXT:       spv.ReturnValue
274// CHECK-NEXT:     }
275// CHECK-NEXT: }
276
277module {
278spv.module Logical GLSL450 {
279  spv.func @foo(%arg0 : i32) -> i32 "None" {
280    spv.ReturnValue %arg0 : i32
281  }
282}
283
284spv.module Logical GLSL450 {
285  spv.globalVariable @foo bind(1, 0) : !spv.ptr<f32, Input>
286
287  spv.func @bar() -> f32 "None" {
288    %0 = spv.mlir.addressof @foo : !spv.ptr<f32, Input>
289    %1 = spv.Load "Input" %0 : f32
290    spv.ReturnValue %1 : f32
291  }
292}
293}
294
295// -----
296
297// Resolve conflicting globalVariableOp and funcOp and update the global variable's
298// references.
299
300// CHECK:      module {
301// CHECK-NEXT:   spv.module Logical GLSL450 {
302// CHECK-NEXT:     spv.globalVariable @foo_1
303// CHECK-NEXT:     spv.func @bar
304// CHECK-NEXT:       spv.mlir.addressof @foo_1
305// CHECK-NEXT:       spv.Load
306// CHECK-NEXT:       spv.ReturnValue
307// CHECK-NEXT:     }
308
309// CHECK-NEXT:     spv.func @foo
310// CHECK-NEXT:       spv.ReturnValue
311// CHECK-NEXT:     }
312// CHECK-NEXT: }
313
314module {
315spv.module Logical GLSL450 {
316  spv.globalVariable @foo bind(1, 0) : !spv.ptr<f32, Input>
317
318  spv.func @bar() -> f32 "None" {
319    %0 = spv.mlir.addressof @foo : !spv.ptr<f32, Input>
320    %1 = spv.Load "Input" %0 : f32
321    spv.ReturnValue %1 : f32
322  }
323}
324
325spv.module Logical GLSL450 {
326  spv.func @foo(%arg0 : i32) -> i32 "None" {
327    spv.ReturnValue %arg0 : i32
328  }
329}
330}
331
332// -----
333
334// Resolve conflicting funcOp and specConstantOp.
335
336// CHECK:      module {
337// CHECK-NEXT:   spv.module Logical GLSL450 {
338// CHECK-NEXT:     spv.func @foo
339// CHECK-NEXT:       spv.ReturnValue
340// CHECK-NEXT:     }
341
342// CHECK-NEXT:     spv.specConstant @foo_1
343// CHECK-NEXT: }
344
345module {
346spv.module Logical GLSL450 {
347  spv.func @foo(%arg0 : i32) -> i32 "None" {
348    spv.ReturnValue %arg0 : i32
349  }
350}
351
352spv.module Logical GLSL450 {
353  spv.specConstant @foo = -5 : i32
354}
355}
356
357// -----
358
359// Resolve conflicting funcOp and specConstantOp and update the spec constant's
360// references.
361
362// CHECK:      module {
363// CHECK-NEXT:   spv.module Logical GLSL450 {
364// CHECK-NEXT:     spv.func @foo
365// CHECK-NEXT:       spv.ReturnValue
366// CHECK-NEXT:     }
367
368// CHECK-NEXT:     spv.specConstant @foo_1
369// CHECK-NEXT:     spv.func @bar
370// CHECK-NEXT:       spv.mlir.referenceof @foo_1
371// CHECK-NEXT:       spv.ReturnValue
372// CHECK-NEXT:     }
373// CHECK-NEXT: }
374
375module {
376spv.module Logical GLSL450 {
377  spv.func @foo(%arg0 : i32) -> i32 "None" {
378    spv.ReturnValue %arg0 : i32
379  }
380}
381
382spv.module Logical GLSL450 {
383  spv.specConstant @foo = -5 : i32
384
385  spv.func @bar() -> i32 "None" {
386    %0 = spv.mlir.referenceof @foo : i32
387    spv.ReturnValue %0 : i32
388  }
389}
390}
391
392// -----
393
394// Resolve conflicting specConstantOp and funcOp and update the spec constant's
395// references.
396
397// CHECK:      module {
398// CHECK-NEXT:   spv.module Logical GLSL450 {
399// CHECK-NEXT:     spv.specConstant @foo_1
400// CHECK-NEXT:     spv.func @bar
401// CHECK-NEXT:       spv.mlir.referenceof @foo_1
402// CHECK-NEXT:       spv.ReturnValue
403// CHECK-NEXT:     }
404
405// CHECK-NEXT:     spv.func @foo
406// CHECK-NEXT:       spv.ReturnValue
407// CHECK-NEXT:     }
408// CHECK-NEXT: }
409
410module {
411spv.module Logical GLSL450 {
412  spv.specConstant @foo = -5 : i32
413
414  spv.func @bar() -> i32 "None" {
415    %0 = spv.mlir.referenceof @foo : i32
416    spv.ReturnValue %0 : i32
417  }
418}
419
420spv.module Logical GLSL450 {
421  spv.func @foo(%arg0 : i32) -> i32 "None" {
422    spv.ReturnValue %arg0 : i32
423  }
424}
425}
426
427// -----
428
429// Resolve conflicting funcOp and specConstantCompositeOp.
430
431// CHECK:      module {
432// CHECK-NEXT:   spv.module Logical GLSL450 {
433// CHECK-NEXT:     spv.func @foo
434// CHECK-NEXT:       spv.ReturnValue
435// CHECK-NEXT:     }
436
437// CHECK-NEXT:     spv.specConstant @bar
438// CHECK-NEXT:     spv.specConstantComposite @foo_1 (@bar, @bar)
439// CHECK-NEXT: }
440
441module {
442spv.module Logical GLSL450 {
443  spv.func @foo(%arg0 : i32) -> i32 "None" {
444    spv.ReturnValue %arg0 : i32
445  }
446}
447
448spv.module Logical GLSL450 {
449  spv.specConstant @bar = -5 : i32
450  spv.specConstantComposite @foo (@bar, @bar) : !spv.array<2 x i32>
451}
452}
453
454// -----
455
456// Resolve conflicting funcOp and specConstantCompositeOp and update the spec
457// constant's references.
458
459// CHECK:      module {
460// CHECK-NEXT:   spv.module Logical GLSL450 {
461// CHECK-NEXT:     spv.func @foo
462// CHECK-NEXT:       spv.ReturnValue
463// CHECK-NEXT:     }
464
465// CHECK-NEXT:     spv.specConstant @bar
466// CHECK-NEXT:     spv.specConstantComposite @foo_1 (@bar, @bar)
467// CHECK-NEXT:     spv.func @baz
468// CHECK-NEXT:       spv.mlir.referenceof @foo_1
469// CHECK-NEXT:       spv.CompositeExtract
470// CHECK-NEXT:       spv.ReturnValue
471// CHECK-NEXT:     }
472// CHECK-NEXT: }
473
474module {
475spv.module Logical GLSL450 {
476  spv.func @foo(%arg0 : i32) -> i32 "None" {
477    spv.ReturnValue %arg0 : i32
478  }
479}
480
481spv.module Logical GLSL450 {
482  spv.specConstant @bar = -5 : i32
483  spv.specConstantComposite @foo (@bar, @bar) : !spv.array<2 x i32>
484
485  spv.func @baz() -> i32 "None" {
486    %0 = spv.mlir.referenceof @foo : !spv.array<2 x i32>
487    %1 = spv.CompositeExtract %0[0 : i32] : !spv.array<2 x i32>
488    spv.ReturnValue %1 : i32
489  }
490}
491}
492
493// -----
494
495// Resolve conflicting specConstantCompositeOp and funcOp and update the spec
496// constant's references.
497
498// CHECK:      module {
499// CHECK-NEXT:   spv.module Logical GLSL450 {
500// CHECK-NEXT:     spv.specConstant @bar
501// CHECK-NEXT:     spv.specConstantComposite @foo_1 (@bar, @bar)
502// CHECK-NEXT:     spv.func @baz
503// CHECK-NEXT:       spv.mlir.referenceof @foo_1
504// CHECK-NEXT:       spv.CompositeExtract
505// CHECK-NEXT:       spv.ReturnValue
506// CHECK-NEXT:     }
507
508// CHECK-NEXT:     spv.func @foo
509// CHECK-NEXT:       spv.ReturnValue
510// CHECK-NEXT:     }
511// CHECK-NEXT: }
512
513module {
514spv.module Logical GLSL450 {
515  spv.specConstant @bar = -5 : i32
516  spv.specConstantComposite @foo (@bar, @bar) : !spv.array<2 x i32>
517
518  spv.func @baz() -> i32 "None" {
519    %0 = spv.mlir.referenceof @foo : !spv.array<2 x i32>
520    %1 = spv.CompositeExtract %0[0 : i32] : !spv.array<2 x i32>
521    spv.ReturnValue %1 : i32
522  }
523}
524
525spv.module Logical GLSL450 {
526  spv.func @foo(%arg0 : i32) -> i32 "None" {
527    spv.ReturnValue %arg0 : i32
528  }
529}
530}
531
532// -----
533
534// Resolve conflicting spec constants and funcOps and update the spec constant's
535// references.
536
537// CHECK:      module {
538// CHECK-NEXT:   spv.module Logical GLSL450 {
539// CHECK-NEXT:     spv.specConstant @bar_1
540// CHECK-NEXT:     spv.specConstantComposite @foo_2 (@bar_1, @bar_1)
541// CHECK-NEXT:     spv.func @baz
542// CHECK-NEXT:       spv.mlir.referenceof @foo_2
543// CHECK-NEXT:       spv.CompositeExtract
544// CHECK-NEXT:       spv.ReturnValue
545// CHECK-NEXT:     }
546
547// CHECK-NEXT:     spv.func @foo
548// CHECK-NEXT:       spv.ReturnValue
549// CHECK-NEXT:     }
550
551// CHECK-NEXT:     spv.func @bar
552// CHECK-NEXT:       spv.ReturnValue
553// CHECK-NEXT:     }
554// CHECK-NEXT: }
555
556module {
557spv.module Logical GLSL450 {
558  spv.specConstant @bar = -5 : i32
559  spv.specConstantComposite @foo (@bar, @bar) : !spv.array<2 x i32>
560
561  spv.func @baz() -> i32 "None" {
562    %0 = spv.mlir.referenceof @foo : !spv.array<2 x i32>
563    %1 = spv.CompositeExtract %0[0 : i32] : !spv.array<2 x i32>
564    spv.ReturnValue %1 : i32
565  }
566}
567
568spv.module Logical GLSL450 {
569  spv.func @foo(%arg0 : i32) -> i32 "None" {
570    spv.ReturnValue %arg0 : i32
571  }
572
573  spv.func @bar(%arg0 : f32) -> f32 "None" {
574    spv.ReturnValue %arg0 : f32
575  }
576}
577}
578
579// -----
580
581// Resolve conflicting globalVariableOps.
582
583// CHECK:      module {
584// CHECK-NEXT:   spv.module Logical GLSL450 {
585// CHECK-NEXT:     spv.globalVariable @foo_1 bind(1, 0)
586
587// CHECK-NEXT:     spv.globalVariable @foo bind(2, 0)
588// CHECK-NEXT: }
589
590module {
591spv.module Logical GLSL450 {
592  spv.globalVariable @foo bind(1, 0) : !spv.ptr<f32, Input>
593}
594
595spv.module Logical GLSL450 {
596  spv.globalVariable @foo bind(2, 0) : !spv.ptr<f32, Input>
597}
598}
599
600// -----
601
602// CHECK:      module {
603// CHECK-NEXT:   spv.module Logical GLSL450 {
604// CHECK-NEXT:     spv.globalVariable @foo_1 built_in("GlobalInvocationId")
605
606// CHECK-NEXT:     spv.globalVariable @foo built_in("LocalInvocationId")
607// CHECK-NEXT: }
608
609module {
610spv.module Logical GLSL450 {
611  spv.globalVariable @foo built_in("GlobalInvocationId") : !spv.ptr<vector<3xi32>, Input>
612}
613
614spv.module Logical GLSL450 {
615  spv.globalVariable @foo built_in("LocalInvocationId") : !spv.ptr<vector<3xi32>, Input>
616}
617}
618
619// -----
620
621// Resolve conflicting globalVariableOp and specConstantOp.
622
623// CHECK:      module {
624// CHECK-NEXT:   spv.module Logical GLSL450 {
625// CHECK-NEXT:     spv.globalVariable @foo_1
626
627// CHECK-NEXT:     spv.specConstant @foo
628// CHECK-NEXT: }
629
630module {
631spv.module Logical GLSL450 {
632  spv.globalVariable @foo bind(1, 0) : !spv.ptr<f32, Input>
633}
634
635spv.module Logical GLSL450 {
636  spv.specConstant @foo = -5 : i32
637}
638}
639
640// -----
641
642// Resolve conflicting specConstantOp and globalVariableOp.
643
644// CHECK:      module {
645// CHECK-NEXT:   spv.module Logical GLSL450 {
646// CHECK-NEXT:     spv.specConstant @foo_1
647
648// CHECK-NEXT:     spv.globalVariable @foo
649// CHECK-NEXT: }
650
651module {
652spv.module Logical GLSL450 {
653  spv.specConstant @foo = -5 : i32
654}
655
656spv.module Logical GLSL450 {
657  spv.globalVariable @foo bind(1, 0) : !spv.ptr<f32, Input>
658}
659}
660
661// -----
662
663// Resolve conflicting globalVariableOp and specConstantCompositeOp.
664
665// CHECK:      module {
666// CHECK-NEXT:   spv.module Logical GLSL450 {
667// CHECK-NEXT:     spv.globalVariable @foo_1
668
669// CHECK-NEXT:     spv.specConstant @bar
670// CHECK-NEXT:     spv.specConstantComposite @foo (@bar, @bar)
671// CHECK-NEXT: }
672
673module {
674spv.module Logical GLSL450 {
675  spv.globalVariable @foo bind(1, 0) : !spv.ptr<f32, Input>
676}
677
678spv.module Logical GLSL450 {
679  spv.specConstant @bar = -5 : i32
680  spv.specConstantComposite @foo (@bar, @bar) : !spv.array<2 x i32>
681}
682}
683
684// -----
685
686// Resolve conflicting globalVariableOp and specConstantComposite.
687
688// CHECK:      module {
689// CHECK-NEXT:   spv.module Logical GLSL450 {
690// CHECK-NEXT:     spv.specConstant @bar
691// CHECK-NEXT:     spv.specConstantComposite @foo_1 (@bar, @bar)
692
693// CHECK-NEXT:     spv.globalVariable @foo
694// CHECK-NEXT: }
695
696module {
697spv.module Logical GLSL450 {
698  spv.specConstant @bar = -5 : i32
699  spv.specConstantComposite @foo (@bar, @bar) : !spv.array<2 x i32>
700}
701
702spv.module Logical GLSL450 {
703  spv.globalVariable @foo bind(1, 0) : !spv.ptr<f32, Input>
704}
705}
706