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 "test/opt/pass_fixture.h" 18 #include "test/opt/pass_utils.h" 19 20 namespace spvtools { 21 namespace opt { 22 namespace { 23 24 using VectorDCETest = PassTest<::testing::Test>; 25 26 TEST_F(VectorDCETest, InsertAfterInsertElim) { 27 // With two insertions to the same offset, the first is dead. 28 // 29 // Note: The SPIR-V assembly has had store/load elimination 30 // performed to allow the inserts and extracts to directly 31 // reference each other. 32 // 33 // #version 450 34 // 35 // layout (location=0) in float In0; 36 // layout (location=1) in float In1; 37 // layout (location=2) in vec2 In2; 38 // layout (location=0) out vec4 OutColor; 39 // 40 // void main() 41 // { 42 // vec2 v = In2; 43 // v.x = In0 + In1; // dead 44 // v.x = 0.0; 45 // OutColor = v.xyxy; 46 // } 47 48 const std::string before_predefs = 49 R"(OpCapability Shader 50 %1 = OpExtInstImport "GLSL.std.450" 51 OpMemoryModel Logical GLSL450 52 OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor 53 OpExecutionMode %main OriginUpperLeft 54 OpSource GLSL 450 55 OpName %main "main" 56 OpName %In2 "In2" 57 OpName %In0 "In0" 58 OpName %In1 "In1" 59 OpName %OutColor "OutColor" 60 OpName %_Globals_ "_Globals_" 61 OpMemberName %_Globals_ 0 "g_b" 62 OpMemberName %_Globals_ 1 "g_n" 63 OpName %_ "" 64 OpDecorate %In2 Location 2 65 OpDecorate %In0 Location 0 66 OpDecorate %In1 Location 1 67 OpDecorate %OutColor Location 0 68 OpMemberDecorate %_Globals_ 0 Offset 0 69 OpMemberDecorate %_Globals_ 1 Offset 4 70 OpDecorate %_Globals_ Block 71 OpDecorate %_ DescriptorSet 0 72 OpDecorate %_ Binding 0 73 %void = OpTypeVoid 74 %11 = OpTypeFunction %void 75 %float = OpTypeFloat 32 76 %v2float = OpTypeVector %float 2 77 %_ptr_Function_v2float = OpTypePointer Function %v2float 78 %_ptr_Input_v2float = OpTypePointer Input %v2float 79 %In2 = OpVariable %_ptr_Input_v2float Input 80 %_ptr_Input_float = OpTypePointer Input %float 81 %In0 = OpVariable %_ptr_Input_float Input 82 %In1 = OpVariable %_ptr_Input_float Input 83 %uint = OpTypeInt 32 0 84 %_ptr_Function_float = OpTypePointer Function %float 85 %float_0 = OpConstant %float 0 86 %v4float = OpTypeVector %float 4 87 %_ptr_Output_v4float = OpTypePointer Output %v4float 88 %OutColor = OpVariable %_ptr_Output_v4float Output 89 %int = OpTypeInt 32 1 90 %_Globals_ = OpTypeStruct %uint %int 91 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_ 92 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform 93 )"; 94 95 const std::string after_predefs = 96 R"(OpCapability Shader 97 %1 = OpExtInstImport "GLSL.std.450" 98 OpMemoryModel Logical GLSL450 99 OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor 100 OpExecutionMode %main OriginUpperLeft 101 OpSource GLSL 450 102 OpName %main "main" 103 OpName %In2 "In2" 104 OpName %In0 "In0" 105 OpName %In1 "In1" 106 OpName %OutColor "OutColor" 107 OpName %_Globals_ "_Globals_" 108 OpMemberName %_Globals_ 0 "g_b" 109 OpMemberName %_Globals_ 1 "g_n" 110 OpName %_ "" 111 OpDecorate %In2 Location 2 112 OpDecorate %In0 Location 0 113 OpDecorate %In1 Location 1 114 OpDecorate %OutColor Location 0 115 OpMemberDecorate %_Globals_ 0 Offset 0 116 OpMemberDecorate %_Globals_ 1 Offset 4 117 OpDecorate %_Globals_ Block 118 OpDecorate %_ DescriptorSet 0 119 OpDecorate %_ Binding 0 120 %void = OpTypeVoid 121 %10 = OpTypeFunction %void 122 %float = OpTypeFloat 32 123 %v2float = OpTypeVector %float 2 124 %_ptr_Function_v2float = OpTypePointer Function %v2float 125 %_ptr_Input_v2float = OpTypePointer Input %v2float 126 %In2 = OpVariable %_ptr_Input_v2float Input 127 %_ptr_Input_float = OpTypePointer Input %float 128 %In0 = OpVariable %_ptr_Input_float Input 129 %In1 = OpVariable %_ptr_Input_float Input 130 %uint = OpTypeInt 32 0 131 %_ptr_Function_float = OpTypePointer Function %float 132 %float_0 = OpConstant %float 0 133 %v4float = OpTypeVector %float 4 134 %_ptr_Output_v4float = OpTypePointer Output %v4float 135 %OutColor = OpVariable %_ptr_Output_v4float Output 136 %int = OpTypeInt 32 1 137 %_Globals_ = OpTypeStruct %uint %int 138 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_ 139 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform 140 )"; 141 142 const std::string before = 143 R"(%main = OpFunction %void None %11 144 %25 = OpLabel 145 %26 = OpLoad %v2float %In2 146 %27 = OpLoad %float %In0 147 %28 = OpLoad %float %In1 148 %29 = OpFAdd %float %27 %28 149 %35 = OpCompositeInsert %v2float %29 %26 0 150 %37 = OpCompositeInsert %v2float %float_0 %35 0 151 %33 = OpVectorShuffle %v4float %37 %37 0 1 0 1 152 OpStore %OutColor %33 153 OpReturn 154 OpFunctionEnd 155 )"; 156 157 const std::string after = 158 R"(%main = OpFunction %void None %10 159 %23 = OpLabel 160 %24 = OpLoad %v2float %In2 161 %25 = OpLoad %float %In0 162 %26 = OpLoad %float %In1 163 %27 = OpFAdd %float %25 %26 164 %28 = OpCompositeInsert %v2float %27 %24 0 165 %29 = OpCompositeInsert %v2float %float_0 %24 0 166 %30 = OpVectorShuffle %v4float %29 %29 0 1 0 1 167 OpStore %OutColor %30 168 OpReturn 169 OpFunctionEnd 170 )"; 171 172 SinglePassRunAndCheck<VectorDCE>(before_predefs + before, 173 after_predefs + after, true, true); 174 } 175 176 TEST_F(VectorDCETest, DeadInsertInChainWithPhi) { 177 // Dead insert eliminated with phi in insertion chain. 178 // 179 // Note: The SPIR-V assembly has had store/load elimination 180 // performed to allow the inserts and extracts to directly 181 // reference each other. 182 // 183 // #version 450 184 // 185 // layout (location=0) in vec4 In0; 186 // layout (location=1) in float In1; 187 // layout (location=2) in float In2; 188 // layout (location=0) out vec4 OutColor; 189 // 190 // layout(std140, binding = 0 ) uniform _Globals_ 191 // { 192 // bool g_b; 193 // }; 194 // 195 // void main() 196 // { 197 // vec4 v = In0; 198 // v.z = In1 + In2; 199 // if (g_b) v.w = 1.0; 200 // OutColor = vec4(v.x,v.y,0.0,v.w); 201 // } 202 203 const std::string before_predefs = 204 R"(OpCapability Shader 205 %1 = OpExtInstImport "GLSL.std.450" 206 OpMemoryModel Logical GLSL450 207 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor 208 OpExecutionMode %main OriginUpperLeft 209 OpSource GLSL 450 210 OpName %main "main" 211 OpName %In0 "In0" 212 OpName %In1 "In1" 213 OpName %In2 "In2" 214 OpName %_Globals_ "_Globals_" 215 OpMemberName %_Globals_ 0 "g_b" 216 OpName %_ "" 217 OpName %OutColor "OutColor" 218 OpDecorate %In0 Location 0 219 OpDecorate %In1 Location 1 220 OpDecorate %In2 Location 2 221 OpMemberDecorate %_Globals_ 0 Offset 0 222 OpDecorate %_Globals_ Block 223 OpDecorate %_ DescriptorSet 0 224 OpDecorate %_ Binding 0 225 OpDecorate %OutColor Location 0 226 %void = OpTypeVoid 227 %11 = OpTypeFunction %void 228 %float = OpTypeFloat 32 229 %v4float = OpTypeVector %float 4 230 %_ptr_Function_v4float = OpTypePointer Function %v4float 231 %_ptr_Input_v4float = OpTypePointer Input %v4float 232 %In0 = OpVariable %_ptr_Input_v4float Input 233 %_ptr_Input_float = OpTypePointer Input %float 234 %In1 = OpVariable %_ptr_Input_float Input 235 %In2 = OpVariable %_ptr_Input_float Input 236 %uint = OpTypeInt 32 0 237 %_ptr_Function_float = OpTypePointer Function %float 238 %_Globals_ = OpTypeStruct %uint 239 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_ 240 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform 241 %int = OpTypeInt 32 1 242 %int_0 = OpConstant %int 0 243 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 244 %bool = OpTypeBool 245 %uint_0 = OpConstant %uint 0 246 %float_1 = OpConstant %float 1 247 %_ptr_Output_v4float = OpTypePointer Output %v4float 248 %OutColor = OpVariable %_ptr_Output_v4float Output 249 %float_0 = OpConstant %float 0 250 )"; 251 252 const std::string after_predefs = 253 R"(OpCapability Shader 254 %1 = OpExtInstImport "GLSL.std.450" 255 OpMemoryModel Logical GLSL450 256 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor 257 OpExecutionMode %main OriginUpperLeft 258 OpSource GLSL 450 259 OpName %main "main" 260 OpName %In0 "In0" 261 OpName %In1 "In1" 262 OpName %In2 "In2" 263 OpName %_Globals_ "_Globals_" 264 OpMemberName %_Globals_ 0 "g_b" 265 OpName %_ "" 266 OpName %OutColor "OutColor" 267 OpDecorate %In0 Location 0 268 OpDecorate %In1 Location 1 269 OpDecorate %In2 Location 2 270 OpMemberDecorate %_Globals_ 0 Offset 0 271 OpDecorate %_Globals_ Block 272 OpDecorate %_ DescriptorSet 0 273 OpDecorate %_ Binding 0 274 OpDecorate %OutColor Location 0 275 %void = OpTypeVoid 276 %10 = OpTypeFunction %void 277 %float = OpTypeFloat 32 278 %v4float = OpTypeVector %float 4 279 %_ptr_Function_v4float = OpTypePointer Function %v4float 280 %_ptr_Input_v4float = OpTypePointer Input %v4float 281 %In0 = OpVariable %_ptr_Input_v4float Input 282 %_ptr_Input_float = OpTypePointer Input %float 283 %In1 = OpVariable %_ptr_Input_float Input 284 %In2 = OpVariable %_ptr_Input_float Input 285 %uint = OpTypeInt 32 0 286 %_ptr_Function_float = OpTypePointer Function %float 287 %_Globals_ = OpTypeStruct %uint 288 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_ 289 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform 290 %int = OpTypeInt 32 1 291 %int_0 = OpConstant %int 0 292 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 293 %bool = OpTypeBool 294 %uint_0 = OpConstant %uint 0 295 %float_1 = OpConstant %float 1 296 %_ptr_Output_v4float = OpTypePointer Output %v4float 297 %OutColor = OpVariable %_ptr_Output_v4float Output 298 %float_0 = OpConstant %float 0 299 )"; 300 301 const std::string before = 302 R"(%main = OpFunction %void None %11 303 %31 = OpLabel 304 %32 = OpLoad %v4float %In0 305 %33 = OpLoad %float %In1 306 %34 = OpLoad %float %In2 307 %35 = OpFAdd %float %33 %34 308 %51 = OpCompositeInsert %v4float %35 %32 2 309 %37 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 310 %38 = OpLoad %uint %37 311 %39 = OpINotEqual %bool %38 %uint_0 312 OpSelectionMerge %40 None 313 OpBranchConditional %39 %41 %40 314 %41 = OpLabel 315 %53 = OpCompositeInsert %v4float %float_1 %51 3 316 OpBranch %40 317 %40 = OpLabel 318 %60 = OpPhi %v4float %51 %31 %53 %41 319 %55 = OpCompositeExtract %float %60 0 320 %57 = OpCompositeExtract %float %60 1 321 %59 = OpCompositeExtract %float %60 3 322 %49 = OpCompositeConstruct %v4float %55 %57 %float_0 %59 323 OpStore %OutColor %49 324 OpReturn 325 OpFunctionEnd 326 )"; 327 328 const std::string after = 329 R"(%main = OpFunction %void None %10 330 %27 = OpLabel 331 %28 = OpLoad %v4float %In0 332 %29 = OpLoad %float %In1 333 %30 = OpLoad %float %In2 334 %31 = OpFAdd %float %29 %30 335 %32 = OpCompositeInsert %v4float %31 %28 2 336 %33 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 337 %34 = OpLoad %uint %33 338 %35 = OpINotEqual %bool %34 %uint_0 339 OpSelectionMerge %36 None 340 OpBranchConditional %35 %37 %36 341 %37 = OpLabel 342 %38 = OpCompositeInsert %v4float %float_1 %28 3 343 OpBranch %36 344 %36 = OpLabel 345 %39 = OpPhi %v4float %28 %27 %38 %37 346 %40 = OpCompositeExtract %float %39 0 347 %41 = OpCompositeExtract %float %39 1 348 %42 = OpCompositeExtract %float %39 3 349 %43 = OpCompositeConstruct %v4float %40 %41 %float_0 %42 350 OpStore %OutColor %43 351 OpReturn 352 OpFunctionEnd 353 )"; 354 355 SinglePassRunAndCheck<VectorDCE>(before_predefs + before, 356 after_predefs + after, true, true); 357 } 358 359 TEST_F(VectorDCETest, DeadInsertWithScalars) { 360 // Dead insert which requires two passes to eliminate 361 // 362 // Note: The SPIR-V assembly has had store/load elimination 363 // performed to allow the inserts and extracts to directly 364 // reference each other. 365 // 366 // #version 450 367 // 368 // layout (location=0) in vec4 In0; 369 // layout (location=1) in float In1; 370 // layout (location=2) in float In2; 371 // layout (location=0) out vec4 OutColor; 372 // 373 // layout(std140, binding = 0 ) uniform _Globals_ 374 // { 375 // bool g_b; 376 // bool g_b2; 377 // }; 378 // 379 // void main() 380 // { 381 // vec4 v1, v2; 382 // v1 = In0; 383 // v1.y = In1 + In2; // dead, second pass 384 // if (g_b) v1.x = 1.0; 385 // v2.x = v1.x; 386 // v2.y = v1.y; // dead, first pass 387 // if (g_b2) v2.x = 0.0; 388 // OutColor = vec4(v2.x,v2.x,0.0,1.0); 389 // } 390 391 const std::string before_predefs = 392 R"(OpCapability Shader 393 %1 = OpExtInstImport "GLSL.std.450" 394 OpMemoryModel Logical GLSL450 395 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor 396 OpExecutionMode %main OriginUpperLeft 397 OpSource GLSL 450 398 OpName %main "main" 399 OpName %In0 "In0" 400 OpName %In1 "In1" 401 OpName %In2 "In2" 402 OpName %_Globals_ "_Globals_" 403 OpMemberName %_Globals_ 0 "g_b" 404 OpMemberName %_Globals_ 1 "g_b2" 405 OpName %_ "" 406 OpName %OutColor "OutColor" 407 OpDecorate %In0 Location 0 408 OpDecorate %In1 Location 1 409 OpDecorate %In2 Location 2 410 OpMemberDecorate %_Globals_ 0 Offset 0 411 OpMemberDecorate %_Globals_ 1 Offset 4 412 OpDecorate %_Globals_ Block 413 OpDecorate %_ DescriptorSet 0 414 OpDecorate %_ Binding 0 415 OpDecorate %OutColor Location 0 416 %void = OpTypeVoid 417 %10 = OpTypeFunction %void 418 %float = OpTypeFloat 32 419 %v4float = OpTypeVector %float 4 420 %_ptr_Function_v4float = OpTypePointer Function %v4float 421 %_ptr_Input_v4float = OpTypePointer Input %v4float 422 %In0 = OpVariable %_ptr_Input_v4float Input 423 %_ptr_Input_float = OpTypePointer Input %float 424 %In1 = OpVariable %_ptr_Input_float Input 425 %In2 = OpVariable %_ptr_Input_float Input 426 %uint = OpTypeInt 32 0 427 %_Globals_ = OpTypeStruct %uint %uint 428 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_ 429 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform 430 %int = OpTypeInt 32 1 431 %int_0 = OpConstant %int 0 432 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 433 %bool = OpTypeBool 434 %uint_0 = OpConstant %uint 0 435 %float_1 = OpConstant %float 1 436 %int_1 = OpConstant %int 1 437 %float_0 = OpConstant %float 0 438 %_ptr_Output_v4float = OpTypePointer Output %v4float 439 %OutColor = OpVariable %_ptr_Output_v4float Output 440 %27 = OpUndef %v4float 441 )"; 442 443 const std::string after_predefs = 444 R"(OpCapability Shader 445 %1 = OpExtInstImport "GLSL.std.450" 446 OpMemoryModel Logical GLSL450 447 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor 448 OpExecutionMode %main OriginUpperLeft 449 OpSource GLSL 450 450 OpName %main "main" 451 OpName %In0 "In0" 452 OpName %In1 "In1" 453 OpName %In2 "In2" 454 OpName %_Globals_ "_Globals_" 455 OpMemberName %_Globals_ 0 "g_b" 456 OpMemberName %_Globals_ 1 "g_b2" 457 OpName %_ "" 458 OpName %OutColor "OutColor" 459 OpDecorate %In0 Location 0 460 OpDecorate %In1 Location 1 461 OpDecorate %In2 Location 2 462 OpMemberDecorate %_Globals_ 0 Offset 0 463 OpMemberDecorate %_Globals_ 1 Offset 4 464 OpDecorate %_Globals_ Block 465 OpDecorate %_ DescriptorSet 0 466 OpDecorate %_ Binding 0 467 OpDecorate %OutColor Location 0 468 %void = OpTypeVoid 469 %10 = OpTypeFunction %void 470 %float = OpTypeFloat 32 471 %v4float = OpTypeVector %float 4 472 %_ptr_Function_v4float = OpTypePointer Function %v4float 473 %_ptr_Input_v4float = OpTypePointer Input %v4float 474 %In0 = OpVariable %_ptr_Input_v4float Input 475 %_ptr_Input_float = OpTypePointer Input %float 476 %In1 = OpVariable %_ptr_Input_float Input 477 %In2 = OpVariable %_ptr_Input_float Input 478 %uint = OpTypeInt 32 0 479 %_Globals_ = OpTypeStruct %uint %uint 480 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_ 481 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform 482 %int = OpTypeInt 32 1 483 %int_0 = OpConstant %int 0 484 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 485 %bool = OpTypeBool 486 %uint_0 = OpConstant %uint 0 487 %float_1 = OpConstant %float 1 488 %int_1 = OpConstant %int 1 489 %float_0 = OpConstant %float 0 490 %_ptr_Output_v4float = OpTypePointer Output %v4float 491 %OutColor = OpVariable %_ptr_Output_v4float Output 492 %27 = OpUndef %v4float 493 )"; 494 495 const std::string before = 496 R"(%main = OpFunction %void None %10 497 %28 = OpLabel 498 %29 = OpLoad %v4float %In0 499 %30 = OpLoad %float %In1 500 %31 = OpLoad %float %In2 501 %32 = OpFAdd %float %30 %31 502 %33 = OpCompositeInsert %v4float %32 %29 1 503 %34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 504 %35 = OpLoad %uint %34 505 %36 = OpINotEqual %bool %35 %uint_0 506 OpSelectionMerge %37 None 507 OpBranchConditional %36 %38 %37 508 %38 = OpLabel 509 %39 = OpCompositeInsert %v4float %float_1 %33 0 510 OpBranch %37 511 %37 = OpLabel 512 %40 = OpPhi %v4float %33 %28 %39 %38 513 %41 = OpCompositeExtract %float %40 0 514 %42 = OpCompositeInsert %v4float %41 %27 0 515 %43 = OpCompositeExtract %float %40 1 516 %44 = OpCompositeInsert %v4float %43 %42 1 517 %45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1 518 %46 = OpLoad %uint %45 519 %47 = OpINotEqual %bool %46 %uint_0 520 OpSelectionMerge %48 None 521 OpBranchConditional %47 %49 %48 522 %49 = OpLabel 523 %50 = OpCompositeInsert %v4float %float_0 %44 0 524 OpBranch %48 525 %48 = OpLabel 526 %51 = OpPhi %v4float %44 %37 %50 %49 527 %52 = OpCompositeExtract %float %51 0 528 %53 = OpCompositeExtract %float %51 0 529 %54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1 530 OpStore %OutColor %54 531 OpReturn 532 OpFunctionEnd 533 )"; 534 535 const std::string after = 536 R"(%main = OpFunction %void None %10 537 %28 = OpLabel 538 %29 = OpLoad %v4float %In0 539 %34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 540 %35 = OpLoad %uint %34 541 %36 = OpINotEqual %bool %35 %uint_0 542 OpSelectionMerge %37 None 543 OpBranchConditional %36 %38 %37 544 %38 = OpLabel 545 %39 = OpCompositeInsert %v4float %float_1 %29 0 546 OpBranch %37 547 %37 = OpLabel 548 %40 = OpPhi %v4float %29 %28 %39 %38 549 %41 = OpCompositeExtract %float %40 0 550 %42 = OpCompositeInsert %v4float %41 %27 0 551 %45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1 552 %46 = OpLoad %uint %45 553 %47 = OpINotEqual %bool %46 %uint_0 554 OpSelectionMerge %48 None 555 OpBranchConditional %47 %49 %48 556 %49 = OpLabel 557 %50 = OpCompositeInsert %v4float %float_0 %42 0 558 OpBranch %48 559 %48 = OpLabel 560 %51 = OpPhi %v4float %42 %37 %50 %49 561 %52 = OpCompositeExtract %float %51 0 562 %53 = OpCompositeExtract %float %51 0 563 %54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1 564 OpStore %OutColor %54 565 OpReturn 566 OpFunctionEnd 567 )"; 568 569 SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before, 570 after_predefs + after, true, true); 571 } 572 573 TEST_F(VectorDCETest, InsertObjectLive) { 574 // Make sure that the object being inserted in an OpCompositeInsert 575 // is not removed when it is uses later on. 576 const std::string before = 577 R"(OpCapability Shader 578 %1 = OpExtInstImport "GLSL.std.450" 579 OpMemoryModel Logical GLSL450 580 OpEntryPoint Fragment %main "main" %In0 %In1 %OutColor 581 OpExecutionMode %main OriginUpperLeft 582 OpSource GLSL 450 583 OpName %main "main" 584 OpName %In0 "In0" 585 OpName %In1 "In1" 586 OpName %OutColor "OutColor" 587 OpDecorate %In0 Location 0 588 OpDecorate %In1 Location 1 589 OpDecorate %OutColor Location 0 590 %void = OpTypeVoid 591 %10 = OpTypeFunction %void 592 %float = OpTypeFloat 32 593 %v4float = OpTypeVector %float 4 594 %_ptr_Input_v4float = OpTypePointer Input %v4float 595 %In0 = OpVariable %_ptr_Input_v4float Input 596 %_ptr_Input_float = OpTypePointer Input %float 597 %In1 = OpVariable %_ptr_Input_float Input 598 %_ptr_Output_v4float = OpTypePointer Output %v4float 599 %OutColor = OpVariable %_ptr_Output_v4float Output 600 %main = OpFunction %void None %10 601 %28 = OpLabel 602 %29 = OpLoad %v4float %In0 603 %30 = OpLoad %float %In1 604 %33 = OpCompositeInsert %v4float %30 %29 1 605 OpStore %OutColor %33 606 OpReturn 607 OpFunctionEnd 608 )"; 609 610 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 611 SinglePassRunAndCheck<DeadInsertElimPass>(before, before, true, true); 612 } 613 614 TEST_F(VectorDCETest, DeadInsertInCycle) { 615 // Dead insert in chain with cycle. Demonstrates analysis can handle 616 // cycles in chains going through scalars intermediate values. 617 // 618 // Note: The SPIR-V assembly has had store/load elimination 619 // performed to allow the inserts and extracts to directly 620 // reference each other. 621 // 622 // #version 450 623 // 624 // layout (location=0) in vec4 In0; 625 // layout (location=1) in float In1; 626 // layout (location=2) in float In2; 627 // layout (location=0) out vec4 OutColor; 628 // 629 // layout(std140, binding = 0 ) uniform _Globals_ 630 // { 631 // int g_n ; 632 // }; 633 // 634 // void main() 635 // { 636 // vec2 v = vec2(0.0, 1.0); 637 // for (int i = 0; i < g_n; i++) { 638 // v.x = v.x + 1; 639 // v.y = v.y * 0.9; // dead 640 // } 641 // OutColor = vec4(v.x); 642 // } 643 644 const std::string assembly = 645 R"( 646 ; CHECK: [[init_val:%\w+]] = OpConstantComposite %v2float %float_0 %float_1 647 ; CHECK: [[undef:%\w+]] = OpUndef %v2float 648 ; CHECK: OpFunction 649 ; CHECK: [[entry_lab:%\w+]] = OpLabel 650 ; CHECK: [[loop_header:%\w+]] = OpLabel 651 ; CHECK: OpPhi %v2float [[init_val]] [[entry_lab]] [[x_insert:%\w+]] {{%\w+}} 652 ; CHECK: [[x_insert:%\w+]] = OpCompositeInsert %v2float %43 [[undef]] 0 653 OpCapability Shader 654 %1 = OpExtInstImport "GLSL.std.450" 655 OpMemoryModel Logical GLSL450 656 OpEntryPoint Fragment %main "main" %OutColor %In0 %In1 %In2 657 OpExecutionMode %main OriginUpperLeft 658 OpSource GLSL 450 659 OpName %main "main" 660 OpName %_Globals_ "_Globals_" 661 OpMemberName %_Globals_ 0 "g_n" 662 OpName %_ "" 663 OpName %OutColor "OutColor" 664 OpName %In0 "In0" 665 OpName %In1 "In1" 666 OpName %In2 "In2" 667 OpMemberDecorate %_Globals_ 0 Offset 0 668 OpDecorate %_Globals_ Block 669 OpDecorate %_ DescriptorSet 0 670 OpDecorate %_ Binding 0 671 OpDecorate %OutColor Location 0 672 OpDecorate %In0 Location 0 673 OpDecorate %In1 Location 1 674 OpDecorate %In2 Location 2 675 %void = OpTypeVoid 676 %10 = OpTypeFunction %void 677 %float = OpTypeFloat 32 678 %v2float = OpTypeVector %float 2 679 %_ptr_Function_v2float = OpTypePointer Function %v2float 680 %float_0 = OpConstant %float 0 681 %float_1 = OpConstant %float 1 682 %16 = OpConstantComposite %v2float %float_0 %float_1 683 %int = OpTypeInt 32 1 684 %_ptr_Function_int = OpTypePointer Function %int 685 %int_0 = OpConstant %int 0 686 %_Globals_ = OpTypeStruct %int 687 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_ 688 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform 689 %_ptr_Uniform_int = OpTypePointer Uniform %int 690 %bool = OpTypeBool 691 %float_0_75 = OpConstant %float 0.75 692 %int_1 = OpConstant %int 1 693 %v4float = OpTypeVector %float 4 694 %_ptr_Output_v4float = OpTypePointer Output %v4float 695 %OutColor = OpVariable %_ptr_Output_v4float Output 696 %_ptr_Input_v4float = OpTypePointer Input %v4float 697 %In0 = OpVariable %_ptr_Input_v4float Input 698 %_ptr_Input_float = OpTypePointer Input %float 699 %In1 = OpVariable %_ptr_Input_float Input 700 %In2 = OpVariable %_ptr_Input_float Input 701 %main = OpFunction %void None %10 702 %29 = OpLabel 703 OpBranch %30 704 %30 = OpLabel 705 %31 = OpPhi %v2float %16 %29 %32 %33 706 %34 = OpPhi %int %int_0 %29 %35 %33 707 OpLoopMerge %36 %33 None 708 OpBranch %37 709 %37 = OpLabel 710 %38 = OpAccessChain %_ptr_Uniform_int %_ %int_0 711 %39 = OpLoad %int %38 712 %40 = OpSLessThan %bool %34 %39 713 OpBranchConditional %40 %41 %36 714 %41 = OpLabel 715 %42 = OpCompositeExtract %float %31 0 716 %43 = OpFAdd %float %42 %float_1 717 %44 = OpCompositeInsert %v2float %43 %31 0 718 %45 = OpCompositeExtract %float %44 1 719 %46 = OpFMul %float %45 %float_0_75 720 %32 = OpCompositeInsert %v2float %46 %44 1 721 OpBranch %33 722 %33 = OpLabel 723 %35 = OpIAdd %int %34 %int_1 724 OpBranch %30 725 %36 = OpLabel 726 %47 = OpCompositeExtract %float %31 0 727 %48 = OpCompositeConstruct %v4float %47 %47 %47 %47 728 OpStore %OutColor %48 729 OpReturn 730 OpFunctionEnd 731 )"; 732 733 SinglePassRunAndMatch<VectorDCE>(assembly, true); 734 } 735 736 TEST_F(VectorDCETest, DeadLoadFeedingCompositeConstruct) { 737 // Detach the loads feeding the CompositeConstruct for the unused elements. 738 // TODO: Implement the rewrite for CompositeConstruct. 739 740 const std::string assembly = 741 R"( 742 ; CHECK: [[undef:%\w+]] = OpUndef %float 743 ; CHECK: [[ac:%\w+]] = OpAccessChain %_ptr_Input_float %In0 %uint_2 744 ; CHECK: [[load:%\w+]] = OpLoad %float [[ac]] 745 ; CHECK: OpCompositeConstruct %v3float [[load]] [[undef]] [[undef]] 746 OpCapability Shader 747 %1 = OpExtInstImport "GLSL.std.450" 748 OpMemoryModel Logical GLSL450 749 OpEntryPoint Fragment %main "main" %In0 %OutColor 750 OpExecutionMode %main OriginUpperLeft 751 OpSource GLSL 450 752 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 753 OpSourceExtension "GL_GOOGLE_include_directive" 754 OpName %main "main" 755 OpName %In0 "In0" 756 OpName %OutColor "OutColor" 757 OpDecorate %In0 Location 0 758 OpDecorate %OutColor Location 0 759 %void = OpTypeVoid 760 %6 = OpTypeFunction %void 761 %float = OpTypeFloat 32 762 %v4float = OpTypeVector %float 4 763 %_ptr_Input_v4float = OpTypePointer Input %v4float 764 %In0 = OpVariable %_ptr_Input_v4float Input 765 %uint = OpTypeInt 32 0 766 %uint_0 = OpConstant %uint 0 767 %_ptr_Input_float = OpTypePointer Input %float 768 %uint_1 = OpConstant %uint 1 769 %uint_2 = OpConstant %uint 2 770 %v3float = OpTypeVector %float 3 771 %int = OpTypeInt 32 1 772 %int_0 = OpConstant %int 0 773 %int_20 = OpConstant %int 20 774 %bool = OpTypeBool 775 %float_1 = OpConstant %float 1 776 %int_1 = OpConstant %int 1 777 %_ptr_Output_v4float = OpTypePointer Output %v4float 778 %OutColor = OpVariable %_ptr_Output_v4float Output 779 %23 = OpUndef %v3float 780 %main = OpFunction %void None %6 781 %24 = OpLabel 782 %25 = OpAccessChain %_ptr_Input_float %In0 %uint_0 783 %26 = OpLoad %float %25 784 %27 = OpAccessChain %_ptr_Input_float %In0 %uint_1 785 %28 = OpLoad %float %27 786 %29 = OpAccessChain %_ptr_Input_float %In0 %uint_2 787 %30 = OpLoad %float %29 788 %31 = OpCompositeConstruct %v3float %30 %28 %26 789 OpBranch %32 790 %32 = OpLabel 791 %33 = OpPhi %v3float %31 %24 %34 %35 792 %36 = OpPhi %int %int_0 %24 %37 %35 793 OpLoopMerge %38 %35 None 794 OpBranch %39 795 %39 = OpLabel 796 %40 = OpSLessThan %bool %36 %int_20 797 OpBranchConditional %40 %41 %38 798 %41 = OpLabel 799 %42 = OpCompositeExtract %float %33 0 800 %43 = OpFAdd %float %42 %float_1 801 %34 = OpCompositeInsert %v3float %43 %33 0 802 OpBranch %35 803 %35 = OpLabel 804 %37 = OpIAdd %int %36 %int_1 805 OpBranch %32 806 %38 = OpLabel 807 %44 = OpCompositeExtract %float %33 0 808 %45 = OpCompositeConstruct %v4float %44 %44 %44 %44 809 OpStore %OutColor %45 810 OpReturn 811 OpFunctionEnd 812 )"; 813 814 SinglePassRunAndMatch<VectorDCE>(assembly, true); 815 } 816 817 TEST_F(VectorDCETest, DeadLoadFeedingVectorShuffle) { 818 // Detach the loads feeding the CompositeConstruct for the unused elements. 819 // TODO: Implement the rewrite for CompositeConstruct. 820 821 const std::string assembly = 822 R"( 823 ; MemPass Type2Undef does not reuse and already existing undef. 824 ; CHECK: {{%\w+}} = OpUndef %v3float 825 ; CHECK: [[undef:%\w+]] = OpUndef %v3float 826 ; CHECK: OpFunction 827 ; CHECK: OpVectorShuffle %v3float {{%\w+}} [[undef]] 0 4 5 828 OpCapability Shader 829 %1 = OpExtInstImport "GLSL.std.450" 830 OpMemoryModel Logical GLSL450 831 OpEntryPoint Fragment %main "main" %In0 %OutColor 832 OpExecutionMode %main OriginUpperLeft 833 OpSource GLSL 450 834 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 835 OpSourceExtension "GL_GOOGLE_include_directive" 836 OpName %main "main" 837 OpName %In0 "In0" 838 OpName %OutColor "OutColor" 839 OpDecorate %In0 Location 0 840 OpDecorate %OutColor Location 0 841 %void = OpTypeVoid 842 %6 = OpTypeFunction %void 843 %float = OpTypeFloat 32 844 %v4float = OpTypeVector %float 4 845 %_ptr_Input_v4float = OpTypePointer Input %v4float 846 %In0 = OpVariable %_ptr_Input_v4float Input 847 %uint = OpTypeInt 32 0 848 %uint_0 = OpConstant %uint 0 849 %_ptr_Input_float = OpTypePointer Input %float 850 %uint_1 = OpConstant %uint 1 851 %uint_2 = OpConstant %uint 2 852 %v3float = OpTypeVector %float 3 853 %int = OpTypeInt 32 1 854 %int_0 = OpConstant %int 0 855 %int_20 = OpConstant %int 20 856 %bool = OpTypeBool 857 %float_1 = OpConstant %float 1 858 %vec_const = OpConstantComposite %v3float %float_1 %float_1 %float_1 859 %int_1 = OpConstant %int 1 860 %_ptr_Output_v4float = OpTypePointer Output %v4float 861 %OutColor = OpVariable %_ptr_Output_v4float Output 862 %23 = OpUndef %v3float 863 %main = OpFunction %void None %6 864 %24 = OpLabel 865 %25 = OpAccessChain %_ptr_Input_float %In0 %uint_0 866 %26 = OpLoad %float %25 867 %27 = OpAccessChain %_ptr_Input_float %In0 %uint_1 868 %28 = OpLoad %float %27 869 %29 = OpAccessChain %_ptr_Input_float %In0 %uint_2 870 %30 = OpLoad %float %29 871 %31 = OpCompositeConstruct %v3float %30 %28 %26 872 %sh = OpVectorShuffle %v3float %vec_const %31 0 4 5 873 OpBranch %32 874 %32 = OpLabel 875 %33 = OpPhi %v3float %sh %24 %34 %35 876 %36 = OpPhi %int %int_0 %24 %37 %35 877 OpLoopMerge %38 %35 None 878 OpBranch %39 879 %39 = OpLabel 880 %40 = OpSLessThan %bool %36 %int_20 881 OpBranchConditional %40 %41 %38 882 %41 = OpLabel 883 %42 = OpCompositeExtract %float %33 0 884 %43 = OpFAdd %float %42 %float_1 885 %34 = OpCompositeInsert %v3float %43 %33 0 886 OpBranch %35 887 %35 = OpLabel 888 %37 = OpIAdd %int %36 %int_1 889 OpBranch %32 890 %38 = OpLabel 891 %44 = OpCompositeExtract %float %33 0 892 %45 = OpCompositeConstruct %v4float %44 %44 %44 %44 893 OpStore %OutColor %45 894 OpReturn 895 OpFunctionEnd 896 )"; 897 898 SinglePassRunAndMatch<VectorDCE>(assembly, true); 899 } 900 901 TEST_F(VectorDCETest, DeadInstThroughShuffle) { 902 // Dead insert in chain with cycle. Demonstrates analysis can handle 903 // cycles in chains. 904 // 905 // Note: The SPIR-V assembly has had store/load elimination 906 // performed to allow the inserts and extracts to directly 907 // reference each other. 908 // 909 // #version 450 910 // 911 // layout (location=0) out vec4 OutColor; 912 // 913 // void main() 914 // { 915 // vec2 v; 916 // v.x = 0.0; 917 // v.y = 0.1; // dead 918 // for (int i = 0; i < 20; i++) { 919 // v.x = v.x + 1; 920 // v = v * 0.9; 921 // } 922 // OutColor = vec4(v.x); 923 // } 924 925 const std::string assembly = 926 R"( 927 ; CHECK: OpFunction 928 ; CHECK-NOT: OpCompositeInsert %v2float {{%\w+}} 1 929 ; CHECK: OpFunctionEnd 930 OpCapability Shader 931 %1 = OpExtInstImport "GLSL.std.450" 932 OpMemoryModel Logical GLSL450 933 OpEntryPoint Fragment %main "main" %OutColor 934 OpExecutionMode %main OriginUpperLeft 935 OpSource GLSL 450 936 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 937 OpSourceExtension "GL_GOOGLE_include_directive" 938 OpName %main "main" 939 OpName %OutColor "OutColor" 940 OpDecorate %OutColor Location 0 941 %void = OpTypeVoid 942 %3 = OpTypeFunction %void 943 %float = OpTypeFloat 32 944 %v2float = OpTypeVector %float 2 945 %float_0 = OpConstant %float 0 946 %float_0_100000001 = OpConstant %float 0.100000001 947 %int = OpTypeInt 32 1 948 %int_0 = OpConstant %int 0 949 %int_20 = OpConstant %int 20 950 %bool = OpTypeBool 951 %float_1 = OpConstant %float 1 952 %float_0_899999976 = OpConstant %float 0.899999976 953 %int_1 = OpConstant %int 1 954 %v4float = OpTypeVector %float 4 955 %_ptr_Output_v4float = OpTypePointer Output %v4float 956 %OutColor = OpVariable %_ptr_Output_v4float Output 957 %58 = OpUndef %v2float 958 %main = OpFunction %void None %3 959 %5 = OpLabel 960 %49 = OpCompositeInsert %v2float %float_0 %58 0 961 %51 = OpCompositeInsert %v2float %float_0_100000001 %49 1 962 OpBranch %22 963 %22 = OpLabel 964 %60 = OpPhi %v2float %51 %5 %38 %25 965 %59 = OpPhi %int %int_0 %5 %41 %25 966 OpLoopMerge %24 %25 None 967 OpBranch %26 968 %26 = OpLabel 969 %30 = OpSLessThan %bool %59 %int_20 970 OpBranchConditional %30 %23 %24 971 %23 = OpLabel 972 %53 = OpCompositeExtract %float %60 0 973 %34 = OpFAdd %float %53 %float_1 974 %55 = OpCompositeInsert %v2float %34 %60 0 975 %38 = OpVectorTimesScalar %v2float %55 %float_0_899999976 976 OpBranch %25 977 %25 = OpLabel 978 %41 = OpIAdd %int %59 %int_1 979 OpBranch %22 980 %24 = OpLabel 981 %57 = OpCompositeExtract %float %60 0 982 %47 = OpCompositeConstruct %v4float %57 %57 %57 %57 983 OpStore %OutColor %47 984 OpReturn 985 OpFunctionEnd 986 )"; 987 988 SinglePassRunAndMatch<VectorDCE>(assembly, true); 989 } 990 991 TEST_F(VectorDCETest, DeadInsertThroughOtherInst) { 992 // Dead insert in chain with cycle. Demonstrates analysis can handle 993 // cycles in chains. 994 // 995 // Note: The SPIR-V assembly has had store/load elimination 996 // performed to allow the inserts and extracts to directly 997 // reference each other. 998 // 999 // #version 450 1000 // 1001 // layout (location=0) out vec4 OutColor; 1002 // 1003 // void main() 1004 // { 1005 // vec2 v; 1006 // v.x = 0.0; 1007 // v.y = 0.1; // dead 1008 // for (int i = 0; i < 20; i++) { 1009 // v.x = v.x + 1; 1010 // v = v * 0.9; 1011 // } 1012 // OutColor = vec4(v.x); 1013 // } 1014 1015 const std::string assembly = 1016 R"( 1017 ; CHECK: OpFunction 1018 ; CHECK-NOT: OpCompositeInsert %v2float {{%\w+}} 1 1019 ; CHECK: OpFunctionEnd 1020 OpCapability Shader 1021 %1 = OpExtInstImport "GLSL.std.450" 1022 OpMemoryModel Logical GLSL450 1023 OpEntryPoint Fragment %main "main" %OutColor 1024 OpExecutionMode %main OriginUpperLeft 1025 OpSource GLSL 450 1026 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 1027 OpSourceExtension "GL_GOOGLE_include_directive" 1028 OpName %main "main" 1029 OpName %OutColor "OutColor" 1030 OpDecorate %OutColor Location 0 1031 %void = OpTypeVoid 1032 %3 = OpTypeFunction %void 1033 %float = OpTypeFloat 32 1034 %v2float = OpTypeVector %float 2 1035 %float_0 = OpConstant %float 0 1036 %float_0_100000001 = OpConstant %float 0.100000001 1037 %int = OpTypeInt 32 1 1038 %int_0 = OpConstant %int 0 1039 %int_20 = OpConstant %int 20 1040 %bool = OpTypeBool 1041 %float_1 = OpConstant %float 1 1042 %float_0_899999976 = OpConstant %float 0.899999976 1043 %int_1 = OpConstant %int 1 1044 %v4float = OpTypeVector %float 4 1045 %_ptr_Output_v4float = OpTypePointer Output %v4float 1046 %OutColor = OpVariable %_ptr_Output_v4float Output 1047 %58 = OpUndef %v2float 1048 %main = OpFunction %void None %3 1049 %5 = OpLabel 1050 %49 = OpCompositeInsert %v2float %float_0 %58 0 1051 %51 = OpCompositeInsert %v2float %float_0_100000001 %49 1 1052 OpBranch %22 1053 %22 = OpLabel 1054 %60 = OpPhi %v2float %51 %5 %38 %25 1055 %59 = OpPhi %int %int_0 %5 %41 %25 1056 OpLoopMerge %24 %25 None 1057 OpBranch %26 1058 %26 = OpLabel 1059 %30 = OpSLessThan %bool %59 %int_20 1060 OpBranchConditional %30 %23 %24 1061 %23 = OpLabel 1062 %53 = OpCompositeExtract %float %60 0 1063 %34 = OpFAdd %float %53 %float_1 1064 %55 = OpCompositeInsert %v2float %34 %60 0 1065 %38 = OpVectorTimesScalar %v2float %55 %float_0_899999976 1066 OpBranch %25 1067 %25 = OpLabel 1068 %41 = OpIAdd %int %59 %int_1 1069 OpBranch %22 1070 %24 = OpLabel 1071 %57 = OpCompositeExtract %float %60 0 1072 %47 = OpCompositeConstruct %v4float %57 %57 %57 %57 1073 OpStore %OutColor %47 1074 OpReturn 1075 OpFunctionEnd 1076 )"; 1077 1078 SinglePassRunAndMatch<VectorDCE>(assembly, true); 1079 } 1080 1081 TEST_F(VectorDCETest, VectorIntoCompositeConstruct) { 1082 const std::string text = R"(OpCapability Linkage 1083 OpCapability Shader 1084 OpMemoryModel Logical GLSL450 1085 OpEntryPoint Fragment %1 "EntryPoint_Main" %2 %3 1086 OpExecutionMode %1 OriginUpperLeft 1087 OpDecorate %2 Location 0 1088 OpDecorate %_struct_4 Block 1089 OpDecorate %3 Location 0 1090 %float = OpTypeFloat 32 1091 %v2float = OpTypeVector %float 2 1092 %_ptr_Function_v2float = OpTypePointer Function %v2float 1093 %v4float = OpTypeVector %float 4 1094 %_ptr_Function_v4float = OpTypePointer Function %v4float 1095 %mat4v4float = OpTypeMatrix %v4float 4 1096 %_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float 1097 %v3float = OpTypeVector %float 3 1098 %_ptr_Function_v3float = OpTypePointer Function %v3float 1099 %_struct_14 = OpTypeStruct %v2float %mat4v4float %v3float %v2float %v4float 1100 %_ptr_Function__struct_14 = OpTypePointer Function %_struct_14 1101 %void = OpTypeVoid 1102 %int = OpTypeInt 32 1 1103 %int_2 = OpConstant %int 2 1104 %int_1 = OpConstant %int 1 1105 %int_4 = OpConstant %int 4 1106 %int_0 = OpConstant %int 0 1107 %int_3 = OpConstant %int 3 1108 %float_0 = OpConstant %float 0 1109 %float_1 = OpConstant %float 1 1110 %_ptr_Input_v2float = OpTypePointer Input %v2float 1111 %2 = OpVariable %_ptr_Input_v2float Input 1112 %_ptr_Output_v2float = OpTypePointer Output %v2float 1113 %_struct_4 = OpTypeStruct %v2float 1114 %_ptr_Output__struct_4 = OpTypePointer Output %_struct_4 1115 %3 = OpVariable %_ptr_Output__struct_4 Output 1116 %28 = OpTypeFunction %void 1117 %29 = OpConstantComposite %v2float %float_0 %float_0 1118 %30 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 1119 %31 = OpConstantComposite %mat4v4float %30 %30 %30 %30 1120 %32 = OpConstantComposite %v3float %float_0 %float_0 %float_0 1121 %1 = OpFunction %void None %28 1122 %33 = OpLabel 1123 %34 = OpVariable %_ptr_Function_v4float Function 1124 %35 = OpVariable %_ptr_Function__struct_14 Function 1125 %36 = OpAccessChain %_ptr_Function_v2float %35 %int_0 1126 OpStore %36 %29 1127 %37 = OpAccessChain %_ptr_Function_mat4v4float %35 %int_1 1128 OpStore %37 %31 1129 %38 = OpAccessChain %_ptr_Function_v3float %35 %int_2 1130 OpStore %38 %32 1131 %39 = OpAccessChain %_ptr_Function_v2float %35 %int_3 1132 OpStore %39 %29 1133 %40 = OpAccessChain %_ptr_Function_v4float %35 %int_4 1134 OpStore %40 %30 1135 %41 = OpLoad %v2float %2 1136 OpStore %36 %41 1137 %42 = OpLoad %v3float %38 1138 %43 = OpCompositeConstruct %v4float %42 %float_1 1139 %44 = OpLoad %mat4v4float %37 1140 %45 = OpVectorTimesMatrix %v4float %43 %44 1141 OpStore %34 %45 1142 OpCopyMemory %40 %34 1143 OpCopyMemory %36 %39 1144 %46 = OpAccessChain %_ptr_Output_v2float %3 %int_0 1145 %47 = OpLoad %v2float %36 1146 OpStore %46 %47 1147 OpReturn 1148 OpFunctionEnd 1149 )"; 1150 1151 SinglePassRunAndCheck<DeadInsertElimPass>(text, text, true, true); 1152 } 1153 1154 } // namespace 1155 } // namespace opt 1156 } // namespace spvtools 1157