1 // Copyright (c) 2018 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <string> 16 17 #include "gmock/gmock.h" 18 #include "test/opt/assembly_builder.h" 19 #include "test/opt/pass_fixture.h" 20 #include "test/opt/pass_utils.h" 21 22 namespace spvtools { 23 namespace opt { 24 namespace { 25 26 using CombineAccessChainsTest = PassTest<::testing::Test>; 27 28 TEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainConstant) { 29 const std::string text = R"( 30 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 31 ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3 32 ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]] 33 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 34 ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int3]] 35 OpCapability Shader 36 OpCapability VariablePointers 37 OpExtension "SPV_KHR_variable_pointers" 38 OpMemoryModel Logical GLSL450 39 OpEntryPoint Fragment %main "main" 40 OpExecutionMode %main OriginUpperLeft 41 %void = OpTypeVoid 42 %uint = OpTypeInt 32 0 43 %uint_0 = OpConstant %uint 0 44 %uint_3 = OpConstant %uint 3 45 %uint_4 = OpConstant %uint 4 46 %uint_array_4 = OpTypeArray %uint %uint_4 47 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 48 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 49 %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup 50 %void_func = OpTypeFunction %void 51 %main = OpFunction %void None %void_func 52 %main_lab = OpLabel 53 %gep = OpAccessChain %ptr_Workgroup_uint %var %uint_0 54 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3 55 OpReturn 56 OpFunctionEnd 57 )"; 58 59 SinglePassRunAndMatch<CombineAccessChains>(text, true); 60 } 61 62 TEST_F(CombineAccessChainsTest, PtrAccessChainFromInBoundsAccessChainConstant) { 63 const std::string text = R"( 64 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 65 ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3 66 ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]] 67 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 68 ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int3]] 69 OpCapability Shader 70 OpCapability VariablePointers 71 OpExtension "SPV_KHR_variable_pointers" 72 OpMemoryModel Logical GLSL450 73 OpEntryPoint Fragment %main "main" 74 OpExecutionMode %main OriginUpperLeft 75 %void = OpTypeVoid 76 %uint = OpTypeInt 32 0 77 %uint_0 = OpConstant %uint 0 78 %uint_3 = OpConstant %uint 3 79 %uint_4 = OpConstant %uint 4 80 %uint_array_4 = OpTypeArray %uint %uint_4 81 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 82 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 83 %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup 84 %void_func = OpTypeFunction %void 85 %main = OpFunction %void None %void_func 86 %main_lab = OpLabel 87 %gep = OpInBoundsAccessChain %ptr_Workgroup_uint %var %uint_0 88 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3 89 OpReturn 90 OpFunctionEnd 91 )"; 92 93 SinglePassRunAndMatch<CombineAccessChains>(text, true); 94 } 95 96 TEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainCombineConstant) { 97 const std::string text = R"( 98 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 99 ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]] 100 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 101 ; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2 102 ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int2]] 103 OpCapability Shader 104 OpCapability VariablePointers 105 OpExtension "SPV_KHR_variable_pointers" 106 OpMemoryModel Logical GLSL450 107 OpEntryPoint Fragment %main "main" 108 OpExecutionMode %main OriginUpperLeft 109 %void = OpTypeVoid 110 %uint = OpTypeInt 32 0 111 %uint_0 = OpConstant %uint 0 112 %uint_1 = OpConstant %uint 1 113 %uint_4 = OpConstant %uint 4 114 %uint_array_4 = OpTypeArray %uint %uint_4 115 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 116 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 117 %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup 118 %void_func = OpTypeFunction %void 119 %main = OpFunction %void None %void_func 120 %main_lab = OpLabel 121 %gep = OpAccessChain %ptr_Workgroup_uint %var %uint_1 122 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_1 123 OpReturn 124 OpFunctionEnd 125 )"; 126 127 SinglePassRunAndMatch<CombineAccessChains>(text, true); 128 } 129 130 TEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainNonConstant) { 131 const std::string text = R"( 132 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 133 ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]] 134 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 135 ; CHECK: [[ld1:%\w+]] = OpLoad 136 ; CHECK: [[ld2:%\w+]] = OpLoad 137 ; CHECK: [[add:%\w+]] = OpIAdd [[int]] [[ld1]] [[ld2]] 138 ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[add]] 139 OpCapability Shader 140 OpCapability VariablePointers 141 OpExtension "SPV_KHR_variable_pointers" 142 OpMemoryModel Logical GLSL450 143 OpEntryPoint Fragment %main "main" 144 OpExecutionMode %main OriginUpperLeft 145 %void = OpTypeVoid 146 %uint = OpTypeInt 32 0 147 %uint_0 = OpConstant %uint 0 148 %uint_4 = OpConstant %uint 4 149 %uint_array_4 = OpTypeArray %uint %uint_4 150 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 151 %ptr_Function_uint = OpTypePointer Function %uint 152 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 153 %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup 154 %void_func = OpTypeFunction %void 155 %main = OpFunction %void None %void_func 156 %main_lab = OpLabel 157 %local_var = OpVariable %ptr_Function_uint Function 158 %ld1 = OpLoad %uint %local_var 159 %gep = OpAccessChain %ptr_Workgroup_uint %var %ld1 160 %ld2 = OpLoad %uint %local_var 161 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %ld2 162 OpReturn 163 OpFunctionEnd 164 )"; 165 166 SinglePassRunAndMatch<CombineAccessChains>(text, true); 167 } 168 169 TEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainExtraIndices) { 170 const std::string text = R"( 171 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 172 ; CHECK: [[int1:%\w+]] = OpConstant [[int]] 1 173 ; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2 174 ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3 175 ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]] 176 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 177 ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int1]] [[int2]] [[int3]] 178 OpCapability Shader 179 OpCapability VariablePointers 180 OpExtension "SPV_KHR_variable_pointers" 181 OpMemoryModel Logical GLSL450 182 OpEntryPoint Fragment %main "main" 183 OpExecutionMode %main OriginUpperLeft 184 %void = OpTypeVoid 185 %uint = OpTypeInt 32 0 186 %uint_0 = OpConstant %uint 0 187 %uint_1 = OpConstant %uint 1 188 %uint_2 = OpConstant %uint 2 189 %uint_3 = OpConstant %uint 3 190 %uint_4 = OpConstant %uint 4 191 %uint_array_4 = OpTypeArray %uint %uint_4 192 %uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4 193 %uint_array_4_array_4_array_4 = OpTypeArray %uint_array_4_array_4 %uint_4 194 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 195 %ptr_Function_uint = OpTypePointer Function %uint 196 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 197 %ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4 198 %ptr_Workgroup_uint_array_4_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4_array_4 199 %var = OpVariable %ptr_Workgroup_uint_array_4_array_4_array_4 Workgroup 200 %void_func = OpTypeFunction %void 201 %main = OpFunction %void None %void_func 202 %main_lab = OpLabel 203 %gep = OpAccessChain %ptr_Workgroup_uint_array_4 %var %uint_1 %uint_0 204 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_2 %uint_3 205 OpReturn 206 OpFunctionEnd 207 )"; 208 209 SinglePassRunAndMatch<CombineAccessChains>(text, true); 210 } 211 212 TEST_F(CombineAccessChainsTest, 213 PtrAccessChainFromPtrAccessChainCombineElementOperand) { 214 const std::string text = R"( 215 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 216 ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3 217 ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]] 218 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 219 ; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6 220 ; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int6]] [[int3]] 221 OpCapability Shader 222 OpCapability VariablePointers 223 OpExtension "SPV_KHR_variable_pointers" 224 OpMemoryModel Logical GLSL450 225 OpEntryPoint Fragment %main "main" 226 OpExecutionMode %main OriginUpperLeft 227 %void = OpTypeVoid 228 %uint = OpTypeInt 32 0 229 %uint_0 = OpConstant %uint 0 230 %uint_3 = OpConstant %uint 3 231 %uint_4 = OpConstant %uint 4 232 %uint_array_4 = OpTypeArray %uint %uint_4 233 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 234 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 235 %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup 236 %void_func = OpTypeFunction %void 237 %main = OpFunction %void None %void_func 238 %main_lab = OpLabel 239 %gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3 240 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3 %uint_3 241 OpReturn 242 OpFunctionEnd 243 )"; 244 245 SinglePassRunAndMatch<CombineAccessChains>(text, true); 246 } 247 248 TEST_F(CombineAccessChainsTest, 249 PtrAccessChainFromPtrAccessChainOnlyElementOperand) { 250 const std::string text = R"( 251 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 252 ; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4 253 ; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]] 254 ; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]] 255 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 256 ; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6 257 ; CHECK: OpPtrAccessChain [[ptr_array]] [[var]] [[int6]] 258 OpCapability Shader 259 OpCapability VariablePointers 260 OpExtension "SPV_KHR_variable_pointers" 261 OpMemoryModel Logical GLSL450 262 OpEntryPoint Fragment %main "main" 263 OpExecutionMode %main OriginUpperLeft 264 %void = OpTypeVoid 265 %uint = OpTypeInt 32 0 266 %uint_0 = OpConstant %uint 0 267 %uint_3 = OpConstant %uint 3 268 %uint_4 = OpConstant %uint 4 269 %uint_array_4 = OpTypeArray %uint %uint_4 270 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 271 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 272 %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup 273 %void_func = OpTypeFunction %void 274 %main = OpFunction %void None %void_func 275 %main_lab = OpLabel 276 %gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3 277 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3 278 OpReturn 279 OpFunctionEnd 280 )"; 281 282 SinglePassRunAndMatch<CombineAccessChains>(text, true); 283 } 284 285 TEST_F(CombineAccessChainsTest, 286 PtrAccessChainFromPtrAccessCombineNonElementIndex) { 287 const std::string text = R"( 288 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 289 ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3 290 ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]] 291 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 292 ; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int3]] [[int3]] [[int3]] 293 OpCapability Shader 294 OpCapability VariablePointers 295 OpExtension "SPV_KHR_variable_pointers" 296 OpMemoryModel Logical GLSL450 297 OpEntryPoint Fragment %main "main" 298 OpExecutionMode %main OriginUpperLeft 299 %void = OpTypeVoid 300 %uint = OpTypeInt 32 0 301 %uint_0 = OpConstant %uint 0 302 %uint_3 = OpConstant %uint 3 303 %uint_4 = OpConstant %uint 4 304 %uint_array_4 = OpTypeArray %uint %uint_4 305 %uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4 306 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 307 %ptr_Function_uint = OpTypePointer Function %uint 308 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 309 %ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4 310 %var = OpVariable %ptr_Workgroup_uint_array_4_array_4 Workgroup 311 %void_func = OpTypeFunction %void 312 %main = OpFunction %void None %void_func 313 %main_lab = OpLabel 314 %gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3 %uint_0 315 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3 %uint_3 316 OpReturn 317 OpFunctionEnd 318 )"; 319 320 SinglePassRunAndMatch<CombineAccessChains>(text, true); 321 } 322 323 TEST_F(CombineAccessChainsTest, 324 AccessChainFromPtrAccessChainOnlyElementOperand) { 325 const std::string text = R"( 326 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 327 ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3 328 ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]] 329 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 330 ; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int3]] [[int3]] 331 OpCapability Shader 332 OpCapability VariablePointers 333 OpExtension "SPV_KHR_variable_pointers" 334 OpMemoryModel Logical GLSL450 335 OpEntryPoint Fragment %main "main" 336 OpExecutionMode %main OriginUpperLeft 337 %void = OpTypeVoid 338 %uint = OpTypeInt 32 0 339 %uint_0 = OpConstant %uint 0 340 %uint_3 = OpConstant %uint 3 341 %uint_4 = OpConstant %uint 4 342 %uint_array_4 = OpTypeArray %uint %uint_4 343 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 344 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 345 %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup 346 %void_func = OpTypeFunction %void 347 %main = OpFunction %void None %void_func 348 %main_lab = OpLabel 349 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3 350 %gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_3 351 OpReturn 352 OpFunctionEnd 353 )"; 354 355 SinglePassRunAndMatch<CombineAccessChains>(text, true); 356 } 357 358 TEST_F(CombineAccessChainsTest, AccessChainFromPtrAccessChainAppend) { 359 const std::string text = R"( 360 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 361 ; CHECK: [[int1:%\w+]] = OpConstant [[int]] 1 362 ; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2 363 ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3 364 ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]] 365 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 366 ; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int1]] [[int2]] [[int3]] 367 OpCapability Shader 368 OpCapability VariablePointers 369 OpExtension "SPV_KHR_variable_pointers" 370 OpMemoryModel Logical GLSL450 371 OpEntryPoint Fragment %main "main" 372 OpExecutionMode %main OriginUpperLeft 373 %void = OpTypeVoid 374 %uint = OpTypeInt 32 0 375 %uint_0 = OpConstant %uint 0 376 %uint_1 = OpConstant %uint 1 377 %uint_2 = OpConstant %uint 2 378 %uint_3 = OpConstant %uint 3 379 %uint_4 = OpConstant %uint 4 380 %uint_array_4 = OpTypeArray %uint %uint_4 381 %uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4 382 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 383 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 384 %ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4 385 %var = OpVariable %ptr_Workgroup_uint_array_4_array_4 Workgroup 386 %void_func = OpTypeFunction %void 387 %main = OpFunction %void None %void_func 388 %main_lab = OpLabel 389 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_1 %uint_2 390 %gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_3 391 OpReturn 392 OpFunctionEnd 393 )"; 394 395 SinglePassRunAndMatch<CombineAccessChains>(text, true); 396 } 397 398 TEST_F(CombineAccessChainsTest, AccessChainFromAccessChainAppend) { 399 const std::string text = R"( 400 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 401 ; CHECK: [[int1:%\w+]] = OpConstant [[int]] 1 402 ; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2 403 ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]] 404 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 405 ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int1]] [[int2]] 406 OpCapability Shader 407 OpCapability VariablePointers 408 OpExtension "SPV_KHR_variable_pointers" 409 OpMemoryModel Logical GLSL450 410 OpEntryPoint Fragment %main "main" 411 OpExecutionMode %main OriginUpperLeft 412 %void = OpTypeVoid 413 %uint = OpTypeInt 32 0 414 %uint_0 = OpConstant %uint 0 415 %uint_1 = OpConstant %uint 1 416 %uint_2 = OpConstant %uint 2 417 %uint_3 = OpConstant %uint 3 418 %uint_4 = OpConstant %uint 4 419 %uint_array_4 = OpTypeArray %uint %uint_4 420 %uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4 421 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 422 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 423 %ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4 424 %var = OpVariable %ptr_Workgroup_uint_array_4_array_4 Workgroup 425 %void_func = OpTypeFunction %void 426 %main = OpFunction %void None %void_func 427 %main_lab = OpLabel 428 %ptr_gep = OpAccessChain %ptr_Workgroup_uint_array_4 %var %uint_1 429 %gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_2 430 OpReturn 431 OpFunctionEnd 432 )"; 433 434 SinglePassRunAndMatch<CombineAccessChains>(text, true); 435 } 436 437 TEST_F(CombineAccessChainsTest, NonConstantStructSlide) { 438 const std::string text = R"( 439 ; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0 440 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 441 ; CHECK: [[ld:%\w+]] = OpLoad 442 ; CHECK: OpPtrAccessChain {{%\w+}} [[var]] [[ld]] [[int0]] 443 OpCapability Shader 444 OpCapability VariablePointers 445 OpExtension "SPV_KHR_variable_pointers" 446 OpMemoryModel Logical GLSL450 447 OpEntryPoint Fragment %main "main" 448 OpExecutionMode %main OriginUpperLeft 449 %void = OpTypeVoid 450 %uint = OpTypeInt 32 0 451 %uint_0 = OpConstant %uint 0 452 %struct = OpTypeStruct %uint %uint 453 %ptr_Workgroup_struct = OpTypePointer Workgroup %struct 454 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 455 %ptr_Function_uint = OpTypePointer Function %uint 456 %wg_var = OpVariable %ptr_Workgroup_struct Workgroup 457 %void_func = OpTypeFunction %void 458 %main = OpFunction %void None %void_func 459 %1 = OpLabel 460 %func_var = OpVariable %ptr_Function_uint Function 461 %ld = OpLoad %uint %func_var 462 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_struct %wg_var %ld 463 %gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_0 464 OpReturn 465 OpFunctionEnd 466 )"; 467 468 SinglePassRunAndMatch<CombineAccessChains>(text, true); 469 } 470 471 TEST_F(CombineAccessChainsTest, DontCombineNonConstantStructSlide) { 472 const std::string text = R"( 473 ; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0 474 ; CHECK: [[ld:%\w+]] = OpLoad 475 ; CHECK: [[gep:%\w+]] = OpAccessChain 476 ; CHECK: OpPtrAccessChain {{%\w+}} [[gep]] [[ld]] [[int0]] 477 OpCapability Shader 478 OpCapability VariablePointers 479 OpExtension "SPV_KHR_variable_pointers" 480 OpMemoryModel Logical GLSL450 481 OpEntryPoint Fragment %main "main" 482 OpExecutionMode %main OriginUpperLeft 483 %void = OpTypeVoid 484 %uint = OpTypeInt 32 0 485 %uint_0 = OpConstant %uint 0 486 %uint_4 = OpConstant %uint 4 487 %struct = OpTypeStruct %uint %uint 488 %struct_array_4 = OpTypeArray %struct %uint_4 489 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 490 %ptr_Function_uint = OpTypePointer Function %uint 491 %ptr_Workgroup_struct = OpTypePointer Workgroup %struct 492 %ptr_Workgroup_struct_array_4 = OpTypePointer Workgroup %struct_array_4 493 %wg_var = OpVariable %ptr_Workgroup_struct_array_4 Workgroup 494 %void_func = OpTypeFunction %void 495 %main = OpFunction %void None %void_func 496 %1 = OpLabel 497 %func_var = OpVariable %ptr_Function_uint Function 498 %ld = OpLoad %uint %func_var 499 %gep = OpAccessChain %ptr_Workgroup_struct %wg_var %uint_0 500 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %ld %uint_0 501 OpReturn 502 OpFunctionEnd 503 )"; 504 505 SinglePassRunAndMatch<CombineAccessChains>(text, true); 506 } 507 508 TEST_F(CombineAccessChainsTest, CombineNonConstantStructSlideElement) { 509 const std::string text = R"( 510 ; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0 511 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 512 ; CHECK: [[ld:%\w+]] = OpLoad 513 ; CHECK: [[add:%\w+]] = OpIAdd {{%\w+}} [[ld]] [[ld]] 514 ; CHECK: OpPtrAccessChain {{%\w+}} [[var]] [[add]] [[int0]] 515 OpCapability Shader 516 OpCapability VariablePointers 517 OpExtension "SPV_KHR_variable_pointers" 518 OpMemoryModel Logical GLSL450 519 OpEntryPoint Fragment %main "main" 520 OpExecutionMode %main OriginUpperLeft 521 %void = OpTypeVoid 522 %uint = OpTypeInt 32 0 523 %uint_0 = OpConstant %uint 0 524 %uint_4 = OpConstant %uint 4 525 %struct = OpTypeStruct %uint %uint 526 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 527 %ptr_Function_uint = OpTypePointer Function %uint 528 %ptr_Workgroup_struct = OpTypePointer Workgroup %struct 529 %wg_var = OpVariable %ptr_Workgroup_struct Workgroup 530 %void_func = OpTypeFunction %void 531 %main = OpFunction %void None %void_func 532 %1 = OpLabel 533 %func_var = OpVariable %ptr_Function_uint Function 534 %ld = OpLoad %uint %func_var 535 %gep = OpPtrAccessChain %ptr_Workgroup_struct %wg_var %ld 536 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %ld %uint_0 537 OpReturn 538 OpFunctionEnd 539 )"; 540 541 SinglePassRunAndMatch<CombineAccessChains>(text, true); 542 } 543 544 TEST_F(CombineAccessChainsTest, PtrAccessChainFromInBoundsPtrAccessChain) { 545 const std::string text = R"( 546 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 547 ; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4 548 ; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]] 549 ; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]] 550 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 551 ; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6 552 ; CHECK: OpPtrAccessChain [[ptr_array]] [[var]] [[int6]] 553 OpCapability Shader 554 OpCapability VariablePointers 555 OpCapability Addresses 556 OpExtension "SPV_KHR_variable_pointers" 557 OpMemoryModel Logical GLSL450 558 OpEntryPoint Fragment %main "main" 559 OpExecutionMode %main OriginUpperLeft 560 %void = OpTypeVoid 561 %uint = OpTypeInt 32 0 562 %uint_0 = OpConstant %uint 0 563 %uint_3 = OpConstant %uint 3 564 %uint_4 = OpConstant %uint 4 565 %uint_array_4 = OpTypeArray %uint %uint_4 566 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 567 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 568 %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup 569 %void_func = OpTypeFunction %void 570 %main = OpFunction %void None %void_func 571 %main_lab = OpLabel 572 %gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3 573 %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3 574 OpReturn 575 OpFunctionEnd 576 )"; 577 578 SinglePassRunAndMatch<CombineAccessChains>(text, true); 579 } 580 581 TEST_F(CombineAccessChainsTest, InBoundsPtrAccessChainFromPtrAccessChain) { 582 const std::string text = R"( 583 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 584 ; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4 585 ; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]] 586 ; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]] 587 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 588 ; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6 589 ; CHECK: OpPtrAccessChain [[ptr_array]] [[var]] [[int6]] 590 OpCapability Shader 591 OpCapability VariablePointers 592 OpCapability Addresses 593 OpExtension "SPV_KHR_variable_pointers" 594 OpMemoryModel Logical GLSL450 595 OpEntryPoint Fragment %main "main" 596 OpExecutionMode %main OriginUpperLeft 597 %void = OpTypeVoid 598 %uint = OpTypeInt 32 0 599 %uint_0 = OpConstant %uint 0 600 %uint_3 = OpConstant %uint 3 601 %uint_4 = OpConstant %uint 4 602 %uint_array_4 = OpTypeArray %uint %uint_4 603 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 604 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 605 %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup 606 %void_func = OpTypeFunction %void 607 %main = OpFunction %void None %void_func 608 %main_lab = OpLabel 609 %gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3 610 %ptr_gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3 611 OpReturn 612 OpFunctionEnd 613 )"; 614 615 SinglePassRunAndMatch<CombineAccessChains>(text, true); 616 } 617 618 TEST_F(CombineAccessChainsTest, 619 InBoundsPtrAccessChainFromInBoundsPtrAccessChain) { 620 const std::string text = R"( 621 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0 622 ; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4 623 ; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]] 624 ; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]] 625 ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup 626 ; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6 627 ; CHECK: OpInBoundsPtrAccessChain [[ptr_array]] [[var]] [[int6]] 628 OpCapability Shader 629 OpCapability VariablePointers 630 OpCapability Addresses 631 OpExtension "SPV_KHR_variable_pointers" 632 OpMemoryModel Logical GLSL450 633 OpEntryPoint Fragment %main "main" 634 OpExecutionMode %main OriginUpperLeft 635 %void = OpTypeVoid 636 %uint = OpTypeInt 32 0 637 %uint_0 = OpConstant %uint 0 638 %uint_3 = OpConstant %uint 3 639 %uint_4 = OpConstant %uint 4 640 %uint_array_4 = OpTypeArray %uint %uint_4 641 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 642 %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4 643 %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup 644 %void_func = OpTypeFunction %void 645 %main = OpFunction %void None %void_func 646 %main_lab = OpLabel 647 %gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3 648 %ptr_gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3 649 OpReturn 650 OpFunctionEnd 651 )"; 652 653 SinglePassRunAndMatch<CombineAccessChains>(text, true); 654 } 655 656 TEST_F(CombineAccessChainsTest, NoIndexAccessChains) { 657 const std::string text = R"( 658 ; CHECK: [[var:%\w+]] = OpVariable 659 ; CHECK-NOT: OpConstant 660 ; CHECK: [[gep:%\w+]] = OpAccessChain {{%\w+}} [[var]] 661 ; CHECK: OpAccessChain {{%\w+}} [[var]] 662 OpCapability Shader 663 OpMemoryModel Logical GLSL450 664 OpEntryPoint Fragment %func "func" 665 OpExecutionMode %func OriginUpperLeft 666 %void = OpTypeVoid 667 %uint = OpTypeInt 32 0 668 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 669 %var = OpVariable %ptr_Workgroup_uint Workgroup 670 %void_func = OpTypeFunction %void 671 %func = OpFunction %void None %void_func 672 %1 = OpLabel 673 %gep1 = OpAccessChain %ptr_Workgroup_uint %var 674 %gep2 = OpAccessChain %ptr_Workgroup_uint %gep1 675 OpReturn 676 OpFunctionEnd 677 )"; 678 679 SinglePassRunAndMatch<CombineAccessChains>(text, true); 680 } 681 682 TEST_F(CombineAccessChainsTest, NoIndexPtrAccessChains) { 683 const std::string text = R"( 684 ; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0 685 ; CHECK: [[var:%\w+]] = OpVariable 686 ; CHECK: [[gep:%\w+]] = OpPtrAccessChain {{%\w+}} [[var]] [[int0]] 687 ; CHECK: OpCopyObject {{%\w+}} [[gep]] 688 OpCapability Shader 689 OpCapability VariablePointers 690 OpExtension "SPV_KHR_variable_pointers" 691 OpMemoryModel Logical GLSL450 692 OpEntryPoint Fragment %func "func" 693 OpExecutionMode %func OriginUpperLeft 694 %void = OpTypeVoid 695 %uint = OpTypeInt 32 0 696 %uint_0 = OpConstant %uint 0 697 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 698 %var = OpVariable %ptr_Workgroup_uint Workgroup 699 %void_func = OpTypeFunction %void 700 %func = OpFunction %void None %void_func 701 %1 = OpLabel 702 %gep1 = OpPtrAccessChain %ptr_Workgroup_uint %var %uint_0 703 %gep2 = OpAccessChain %ptr_Workgroup_uint %gep1 704 OpReturn 705 OpFunctionEnd 706 )"; 707 708 SinglePassRunAndMatch<CombineAccessChains>(text, true); 709 } 710 711 TEST_F(CombineAccessChainsTest, NoIndexPtrAccessChains2) { 712 const std::string text = R"( 713 ; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0 714 ; CHECK: [[var:%\w+]] = OpVariable 715 ; CHECK: OpPtrAccessChain {{%\w+}} [[var]] [[int0]] 716 OpCapability Shader 717 OpCapability VariablePointers 718 OpExtension "SPV_KHR_variable_pointers" 719 OpMemoryModel Logical GLSL450 720 OpEntryPoint Fragment %func "func" 721 OpExecutionMode %func OriginUpperLeft 722 %void = OpTypeVoid 723 %uint = OpTypeInt 32 0 724 %uint_0 = OpConstant %uint 0 725 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 726 %var = OpVariable %ptr_Workgroup_uint Workgroup 727 %void_func = OpTypeFunction %void 728 %func = OpFunction %void None %void_func 729 %1 = OpLabel 730 %gep1 = OpAccessChain %ptr_Workgroup_uint %var 731 %gep2 = OpPtrAccessChain %ptr_Workgroup_uint %gep1 %uint_0 732 OpReturn 733 OpFunctionEnd 734 )"; 735 736 SinglePassRunAndMatch<CombineAccessChains>(text, true); 737 } 738 739 TEST_F(CombineAccessChainsTest, CombineMixedSign) { 740 const std::string text = R"( 741 ; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 742 ; CHECK: [[var:%\w+]] = OpVariable 743 ; CHECK: [[uint2:%\w+]] = OpConstant [[uint]] 2 744 ; CHECK: OpInBoundsPtrAccessChain {{%\w+}} [[var]] [[uint2]] 745 OpCapability Shader 746 OpCapability VariablePointers 747 OpCapability Addresses 748 OpExtension "SPV_KHR_variable_pointers" 749 OpMemoryModel Logical GLSL450 750 OpEntryPoint Fragment %func "func" 751 OpExecutionMode %func OriginUpperLeft 752 %void = OpTypeVoid 753 %uint = OpTypeInt 32 0 754 %int = OpTypeInt 32 1 755 %uint_1 = OpConstant %uint 1 756 %int_1 = OpConstant %int 1 757 %ptr_Workgroup_uint = OpTypePointer Workgroup %uint 758 %var = OpVariable %ptr_Workgroup_uint Workgroup 759 %void_func = OpTypeFunction %void 760 %func = OpFunction %void None %void_func 761 %1 = OpLabel 762 %gep1 = OpInBoundsPtrAccessChain %ptr_Workgroup_uint %var %uint_1 763 %gep2 = OpInBoundsPtrAccessChain %ptr_Workgroup_uint %gep1 %int_1 764 OpReturn 765 OpFunctionEnd 766 )"; 767 768 SinglePassRunAndMatch<CombineAccessChains>(text, true); 769 } 770 771 } // namespace 772 } // namespace opt 773 } // namespace spvtools 774