@@ -384,6 +384,121 @@ OpFunctionEnd
384384
385385 SinglePassRunAndCheck<SimplificationPass>(text, text, false );
386386}
387+
388+ TEST_F (SimplificationTest, CopyLogicalOfCompositeConstructMatchingTypes) {
389+ // OpCopyLogical fed by an OpCompositeConstruct whose constituents are
390+ // already typed exactly as the corresponding fields of the OpCopyLogical's
391+ // result type can be rewritten as an OpCompositeConstruct of the result
392+ // type.
393+ const std::string text = R"(
394+ ; CHECK: [[ptr:%\w+]] = OpVariable %_ptr_StorageBuffer_int StorageBuffer
395+ ; CHECK: [[ctor:%\w+]] = OpCompositeConstruct %ResHolder_fn [[ptr]]
396+ ; CHECK-NOT: OpCopyLogical
397+ ; CHECK: OpStore {{%\w+}} [[ctor]]
398+ OpCapability Shader
399+ OpMemoryModel Logical GLSL450
400+ OpEntryPoint GLCompute %main "main"
401+ OpExecutionMode %main LocalSize 1 1 1
402+ OpDecorate %ResHolder_block Block
403+ OpMemberDecorate %ResHolder_block 0 Offset 0
404+ OpDecorate %ssbo DescriptorSet 0
405+ OpDecorate %ssbo Binding 0
406+ %void = OpTypeVoid
407+ %void_fn = OpTypeFunction %void
408+ %int = OpTypeInt 32 1
409+ %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
410+ %ssbo = OpVariable %_ptr_StorageBuffer_int StorageBuffer
411+ %ResHolder_block = OpTypeStruct %int
412+ %ResHolder_fn = OpTypeStruct %_ptr_StorageBuffer_int
413+ %_ptr_Function_ResHolder_fn = OpTypePointer Function %ResHolder_fn
414+ %main = OpFunction %void None %void_fn
415+ %entry = OpLabel
416+ %h = OpVariable %_ptr_Function_ResHolder_fn Function
417+ %cc = OpCompositeConstruct %ResHolder_block %ssbo
418+ %cl = OpCopyLogical %ResHolder_fn %cc
419+ OpStore %h %cl
420+ OpReturn
421+ OpFunctionEnd
422+ )" ;
423+
424+ SinglePassRunAndMatch<SimplificationPass>(text, false );
425+ }
426+
427+ TEST_F (SimplificationTest, CopyLogicalOfCompositeConstructMixedTypes) {
428+ const std::string text = R"(
429+ ; CHECK: [[ptr:%\w+]] = OpVariable %_ptr_StorageBuffer_int StorageBuffer
430+ ; CHECK: [[u:%\w+]] = OpLoad %Uniforms_block
431+ ; CHECK: [[copy:%\w+]] = OpCopyLogical %Uniforms_fn [[u]]
432+ ; CHECK: [[ctor:%\w+]] = OpCompositeConstruct %Ctx_fn [[copy]] [[ptr]]
433+ ; CHECK-NOT: OpCopyLogical %Ctx_fn
434+ ; CHECK: OpStore {{%\w+}} [[ctor]]
435+ OpCapability Shader
436+ OpMemoryModel Logical GLSL450
437+ OpEntryPoint GLCompute %main "main"
438+ OpExecutionMode %main LocalSize 1 1 1
439+ OpDecorate %Uniforms_block Block
440+ OpMemberDecorate %Uniforms_block 0 Offset 0
441+ OpDecorate %ubo DescriptorSet 0
442+ OpDecorate %ubo Binding 0
443+ OpDecorate %ssbo DescriptorSet 0
444+ OpDecorate %ssbo Binding 1
445+ %void = OpTypeVoid
446+ %void_fn = OpTypeFunction %void
447+ %int = OpTypeInt 32 1
448+ %Uniforms_block = OpTypeStruct %int
449+ %Uniforms_fn = OpTypeStruct %int
450+ %_ptr_Uniform_Uniforms_block = OpTypePointer Uniform %Uniforms_block
451+ %ubo = OpVariable %_ptr_Uniform_Uniforms_block Uniform
452+ %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
453+ %ssbo = OpVariable %_ptr_StorageBuffer_int StorageBuffer
454+ %Ctx_block = OpTypeStruct %Uniforms_block %int
455+ %Ctx_fn = OpTypeStruct %Uniforms_fn %_ptr_StorageBuffer_int
456+ %_ptr_Function_Ctx_fn = OpTypePointer Function %Ctx_fn
457+ %main = OpFunction %void None %void_fn
458+ %entry = OpLabel
459+ %h = OpVariable %_ptr_Function_Ctx_fn Function
460+ %u = OpLoad %Uniforms_block %ubo
461+ %cc = OpCompositeConstruct %Ctx_block %u %ssbo
462+ %cl = OpCopyLogical %Ctx_fn %cc
463+ OpStore %h %cl
464+ OpReturn
465+ OpFunctionEnd
466+ )" ;
467+
468+ SinglePassRunAndMatch<SimplificationPass>(text, false );
469+ }
470+
471+ TEST_F (SimplificationTest,
472+ CopyLogicalOfCompositeConstructDoesNotFoldInvalidPointerMismatch) {
473+ // The fold must not insert an OpCopyLogical between non-layout-compatible
474+ // types.
475+ const std::string text = R"( OpCapability Shader
476+ OpMemoryModel Logical GLSL450
477+ OpEntryPoint GLCompute %main "main"
478+ OpExecutionMode %main LocalSize 1 1 1
479+ OpDecorate %Block Block
480+ OpMemberDecorate %Block 0 Offset 0
481+ OpDecorate %ssbo DescriptorSet 0
482+ OpDecorate %ssbo Binding 0
483+ %void = OpTypeVoid
484+ %void_fn = OpTypeFunction %void
485+ %int = OpTypeInt 32 1
486+ %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
487+ %ssbo = OpVariable %_ptr_StorageBuffer_int StorageBuffer
488+ %Block = OpTypeStruct %int
489+ %Ctx_value = OpTypeStruct %int
490+ %Ctx_ptr = OpTypeStruct %_ptr_StorageBuffer_int
491+ %main = OpFunction %void None %void_fn
492+ %entry = OpLabel
493+ %cc = OpCompositeConstruct %Ctx_ptr %ssbo
494+ %cl = OpCopyLogical %Ctx_value %cc
495+ OpReturn
496+ OpFunctionEnd
497+ )" ;
498+
499+ SinglePassRunAndCheck<SimplificationPass>(text, text, false );
500+ }
501+
387502} // namespace
388503} // namespace opt
389504} // namespace spvtools
0 commit comments