1 // RUN: mlir-opt -test-spirv-module-combiner -split-input-file -verify-diagnostics %s | FileCheck %s
3 // Deduplicate 2 global variables with the same descriptor set and binding.
6 // CHECK-NEXT: spirv.module Logical GLSL450 {
7 // CHECK-NEXT: spirv.GlobalVariable @foo
9 // CHECK-NEXT: spirv.func @use_foo
10 // CHECK-NEXT: spirv.mlir.addressof @foo
11 // CHECK-NEXT: spirv.Load
12 // CHECK-NEXT: spirv.ReturnValue
15 // CHECK-NEXT: spirv.func @use_bar
16 // CHECK-NEXT: spirv.mlir.addressof @foo
17 // CHECK-NEXT: spirv.Load
18 // CHECK-NEXT: spirv.FAdd
19 // CHECK-NEXT: spirv.ReturnValue
24 spirv.module Logical GLSL450 {
25 spirv.GlobalVariable @foo bind(1, 0) : !spirv.ptr<f32, Input>
27 spirv.func @use_foo() -> f32 "None" {
28 %0 = spirv.mlir.addressof @foo : !spirv.ptr<f32, Input>
29 %1 = spirv.Load "Input" %0 : f32
30 spirv.ReturnValue %1 : f32
34 spirv.module Logical GLSL450 {
35 spirv.GlobalVariable @bar bind(1, 0) : !spirv.ptr<f32, Input>
37 spirv.func @use_bar() -> f32 "None" {
38 %0 = spirv.mlir.addressof @bar : !spirv.ptr<f32, Input>
39 %1 = spirv.Load "Input" %0 : f32
40 %2 = spirv.FAdd %1, %1 : f32
41 spirv.ReturnValue %2 : f32
47 // Deduplicate 2 global variables with the same descriptor set and binding but different types.
50 // CHECK-NEXT: spirv.module Logical GLSL450 {
51 // CHECK-NEXT: spirv.GlobalVariable @foo bind(1, 0)
53 // CHECK-NEXT: spirv.GlobalVariable @bar bind(1, 0)
55 // CHECK-NEXT: spirv.func @use_bar
56 // CHECK-NEXT: spirv.mlir.addressof @bar
57 // CHECK-NEXT: spirv.Load
58 // CHECK-NEXT: spirv.ReturnValue
63 spirv.module Logical GLSL450 {
64 spirv.GlobalVariable @foo bind(1, 0) : !spirv.ptr<i32, Input>
67 spirv.module Logical GLSL450 {
68 spirv.GlobalVariable @bar bind(1, 0) : !spirv.ptr<f32, Input>
70 spirv.func @use_bar() -> f32 "None" {
71 %0 = spirv.mlir.addressof @bar : !spirv.ptr<f32, Input>
72 %1 = spirv.Load "Input" %0 : f32
73 spirv.ReturnValue %1 : f32
79 // Deduplicate 2 global variables with the same built-in attribute.
82 // CHECK-NEXT: spirv.module Logical GLSL450 {
83 // CHECK-NEXT: spirv.GlobalVariable @foo built_in("GlobalInvocationId")
84 // CHECK-NEXT: spirv.func @use_bar
85 // CHECK-NEXT: spirv.mlir.addressof @foo
86 // CHECK-NEXT: spirv.Load
87 // CHECK-NEXT: spirv.ReturnValue
92 spirv.module Logical GLSL450 {
93 spirv.GlobalVariable @foo built_in("GlobalInvocationId") : !spirv.ptr<vector<3xi32>, Input>
96 spirv.module Logical GLSL450 {
97 spirv.GlobalVariable @bar built_in("GlobalInvocationId") : !spirv.ptr<vector<3xi32>, Input>
99 spirv.func @use_bar() -> vector<3xi32> "None" {
100 %0 = spirv.mlir.addressof @bar : !spirv.ptr<vector<3xi32>, Input>
101 %1 = spirv.Load "Input" %0 : vector<3xi32>
102 spirv.ReturnValue %1 : vector<3xi32>
108 // Deduplicate 2 spec constants with the same spec ID.
111 // CHECK-NEXT: spirv.module Logical GLSL450 {
112 // CHECK-NEXT: spirv.SpecConstant @foo spec_id(5)
114 // CHECK-NEXT: spirv.func @use_foo()
115 // CHECK-NEXT: %0 = spirv.mlir.referenceof @foo
116 // CHECK-NEXT: spirv.ReturnValue
119 // CHECK-NEXT: spirv.func @use_bar()
120 // CHECK-NEXT: %0 = spirv.mlir.referenceof @foo
121 // CHECK-NEXT: spirv.FAdd
122 // CHECK-NEXT: spirv.ReturnValue
127 spirv.module Logical GLSL450 {
128 spirv.SpecConstant @foo spec_id(5) = 1. : f32
130 spirv.func @use_foo() -> (f32) "None" {
131 %0 = spirv.mlir.referenceof @foo : f32
132 spirv.ReturnValue %0 : f32
136 spirv.module Logical GLSL450 {
137 spirv.SpecConstant @bar spec_id(5) = 1. : f32
139 spirv.func @use_bar() -> (f32) "None" {
140 %0 = spirv.mlir.referenceof @bar : f32
141 %1 = spirv.FAdd %0, %0 : f32
142 spirv.ReturnValue %1 : f32
148 // Don't deduplicate functions with similar ops but different operands.
150 // CHECK: spirv.module Logical GLSL450 {
151 // CHECK-NEXT: spirv.func @foo(%[[ARG0:.+]]: f32, %[[ARG1:.+]]: f32, %[[ARG2:.+]]: f32)
152 // CHECK-NEXT: %[[ADD:.+]] = spirv.FAdd %[[ARG0]], %[[ARG1]] : f32
153 // CHECK-NEXT: %[[MUL:.+]] = spirv.FMul %[[ADD]], %[[ARG2]] : f32
154 // CHECK-NEXT: spirv.ReturnValue %[[MUL]] : f32
156 // CHECK-NEXT: spirv.func @foo_1(%[[ARG0:.+]]: f32, %[[ARG1:.+]]: f32, %[[ARG2:.+]]: f32)
157 // CHECK-NEXT: %[[ADD:.+]] = spirv.FAdd %[[ARG0]], %[[ARG2]] : f32
158 // CHECK-NEXT: %[[MUL:.+]] = spirv.FMul %[[ADD]], %[[ARG1]] : f32
159 // CHECK-NEXT: spirv.ReturnValue %[[MUL]] : f32
163 spirv.module Logical GLSL450 {
164 spirv.func @foo(%a: f32, %b: f32, %c: f32) -> f32 "None" {
165 %add = spirv.FAdd %a, %b: f32
166 %mul = spirv.FMul %add, %c: f32
167 spirv.ReturnValue %mul: f32
171 spirv.module Logical GLSL450 {
172 spirv.func @foo(%a: f32, %b: f32, %c: f32) -> f32 "None" {
173 %add = spirv.FAdd %a, %c: f32
174 %mul = spirv.FMul %add, %b: f32
175 spirv.ReturnValue %mul: f32
181 // TODO: re-enable this test once we have better function deduplication.
184 // XXXXX-NEXT: spirv.module Logical GLSL450 {
185 // XXXXX-NEXT: spirv.SpecConstant @bar spec_id(5)
187 // XXXXX-NEXT: spirv.func @foo(%arg0: f32)
188 // XXXXX-NEXT: spirv.ReturnValue
191 // XXXXX-NEXT: spirv.func @foo_different_body(%arg0: f32)
192 // XXXXX-NEXT: spirv.mlir.referenceof
193 // XXXXX-NEXT: spirv.ReturnValue
196 // XXXXX-NEXT: spirv.func @baz(%arg0: i32)
197 // XXXXX-NEXT: spirv.ReturnValue
200 // XXXXX-NEXT: spirv.func @baz_no_return(%arg0: i32)
201 // XXXXX-NEXT: spirv.Return
204 // XXXXX-NEXT: spirv.func @baz_no_return_different_control
205 // XXXXX-NEXT: spirv.Return
208 // XXXXX-NEXT: spirv.func @baz_no_return_another_control
209 // XXXXX-NEXT: spirv.Return
212 // XXXXX-NEXT: spirv.func @kernel
213 // XXXXX-NEXT: spirv.Return
216 // XXXXX-NEXT: spirv.func @kernel_different_attr
217 // XXXXX-NEXT: spirv.Return
223 spirv.module Logical GLSL450 {
224 spirv.SpecConstant @bar spec_id(5) = 1. : f32
226 spirv.func @foo(%arg0: f32) -> (f32) "None" {
227 spirv.ReturnValue %arg0 : f32
230 spirv.func @foo_duplicate(%arg0: f32) -> (f32) "None" {
231 spirv.ReturnValue %arg0 : f32
234 spirv.func @foo_different_body(%arg0: f32) -> (f32) "None" {
235 %0 = spirv.mlir.referenceof @bar : f32
236 spirv.ReturnValue %arg0 : f32
239 spirv.func @baz(%arg0: i32) -> (i32) "None" {
240 spirv.ReturnValue %arg0 : i32
243 spirv.func @baz_no_return(%arg0: i32) "None" {
247 spirv.func @baz_no_return_duplicate(%arg0: i32) -> () "None" {
251 spirv.func @baz_no_return_different_control(%arg0: i32) -> () "Inline" {
255 spirv.func @baz_no_return_another_control(%arg0: i32) -> () "Inline|Pure" {
261 %arg1: !spirv.ptr<!spirv.struct<(!spirv.array<12 x f32>)>, CrossWorkgroup>) "None"
262 attributes {spirv.entry_point_abi = #spirv.entry_point_abi<workgroup_size = [32, 1, 1]>} {
266 spirv.func @kernel_different_attr(
268 %arg1: !spirv.ptr<!spirv.struct<(!spirv.array<12 x f32>)>, CrossWorkgroup>) "None"
269 attributes {spirv.entry_point_abi = #spirv.entry_point_abi<workgroup_size = [64, 1, 1]>} {