@@ -384,6 +384,135 @@ 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+ SetTargetEnv (SPV_ENV_UNIVERSAL_1_4 );
394+ const std::string text = R"(
395+ ; CHECK: [[ptr:%\w+]] = OpVariable %_ptr_StorageBuffer_int StorageBuffer
396+ ; CHECK: [[ctor:%\w+]] = OpCompositeConstruct {{%\w+}} [[ptr]]
397+ ; CHECK-NOT: OpCopyLogical
398+ ; CHECK: [[ctor2:%\w+]] = OpCompositeConstruct {{%\w+}} [[ptr]]
399+ ; CHECK: OpStore {{%\w+}} [[ctor2]]
400+ OpCapability Shader
401+ OpMemoryModel Logical GLSL450
402+ OpEntryPoint GLCompute %main "main"
403+ OpExecutionMode %main LocalSize 1 1 1
404+ OpDecorate %ResHolder_block Block
405+ OpMemberDecorate %ResHolder_block 0 Offset 0
406+ OpDecorate %ssbo DescriptorSet 0
407+ OpDecorate %ssbo Binding 0
408+ %void = OpTypeVoid
409+ %void_fn = OpTypeFunction %void
410+ %int = OpTypeInt 32 1
411+ %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
412+ %ssbo = OpVariable %_ptr_StorageBuffer_int StorageBuffer
413+ %ResHolder_block = OpTypeStruct %int
414+ %ResHolder_fn = OpTypeStruct %_ptr_StorageBuffer_int
415+ %_ptr_Function_ResHolder_fn = OpTypePointer Function %ResHolder_fn
416+ %main = OpFunction %void None %void_fn
417+ %entry = OpLabel
418+ %h = OpVariable %_ptr_Function_ResHolder_fn Function
419+ %cc = OpCompositeConstruct %ResHolder_block %ssbo
420+ %cl = OpCopyLogical %ResHolder_fn %cc
421+ OpStore %h %cl
422+ OpReturn
423+ OpFunctionEnd
424+ )" ;
425+
426+ SinglePassRunAndMatch<SimplificationPass>(text, false );
427+ }
428+
429+ TEST_F (SimplificationTest, CopyLogicalOfCompositeConstructMixedTypes) {
430+ SetTargetEnv (SPV_ENV_UNIVERSAL_1_4 );
431+ const std::string text = R"(
432+ ; CHECK: [[ptr:%\w+]] = OpVariable %_ptr_StorageBuffer_int StorageBuffer
433+ ; CHECK: [[u:%\w+]] = OpLoad {{%\w+}}
434+ ; CHECK: [[copy:%\w+]] = OpCopyLogical {{%\w+}} [[u]]
435+ ; CHECK: [[ctor:%\w+]] = OpCompositeConstruct {{%\w+}} [[copy]] [[ptr]]
436+ ; CHECK-NOT: OpCopyLogical {{%\w+}} {{%\w+}} {{%\w+}}
437+ ; CHECK: OpStore {{%\w+}} [[ctor]]
438+ OpCapability Shader
439+ OpMemoryModel Logical GLSL450
440+ OpEntryPoint GLCompute %main "main"
441+ OpExecutionMode %main LocalSize 1 1 1
442+ OpDecorate %Uniforms_block Block
443+ OpMemberDecorate %Uniforms_block 0 Offset 0
444+ OpDecorate %ubo DescriptorSet 0
445+ OpDecorate %ubo Binding 0
446+ OpDecorate %ssbo DescriptorSet 0
447+ OpDecorate %ssbo Binding 1
448+ %void = OpTypeVoid
449+ %void_fn = OpTypeFunction %void
450+ %int = OpTypeInt 32 1
451+ %Uniforms_block = OpTypeStruct %int
452+ %Uniforms_fn = OpTypeStruct %int
453+ %_ptr_Uniform_Uniforms_block = OpTypePointer Uniform %Uniforms_block
454+ %ubo = OpVariable %_ptr_Uniform_Uniforms_block Uniform
455+ %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
456+ %ssbo = OpVariable %_ptr_StorageBuffer_int StorageBuffer
457+ %Ctx_block = OpTypeStruct %Uniforms_block %int
458+ %Ctx_fn = OpTypeStruct %Uniforms_fn %_ptr_StorageBuffer_int
459+ %_ptr_Function_Ctx_fn = OpTypePointer Function %Ctx_fn
460+ %main = OpFunction %void None %void_fn
461+ %entry = OpLabel
462+ %h = OpVariable %_ptr_Function_Ctx_fn Function
463+ %u = OpLoad %Uniforms_block %ubo
464+ %cc = OpCompositeConstruct %Ctx_block %u %ssbo
465+ %cl = OpCopyLogical %Ctx_fn %cc
466+ OpStore %h %cl
467+ OpReturn
468+ OpFunctionEnd
469+ )" ;
470+
471+ SinglePassRunAndMatch<SimplificationPass>(text, false );
472+ }
473+
474+ TEST_F (SimplificationTest,
475+ CopyLogicalOfCompositeConstructPhysicalStorageBufferPointerField) {
476+ SetTargetEnv (SPV_ENV_UNIVERSAL_1_4 );
477+ const std::string text = R"(
478+ ; CHECK: [[cc:%\w+]] = OpCompositeConstruct {{%\w+}} {{%\w+}}
479+ ; CHECK: OpCopyLogical {{%\w+}} [[cc]]
480+ OpCapability Shader
481+ OpCapability PhysicalStorageBufferAddresses
482+ OpExtension "SPV_KHR_physical_storage_buffer"
483+ OpMemoryModel PhysicalStorageBuffer64 GLSL450
484+ OpEntryPoint GLCompute %main "main"
485+ OpExecutionMode %main LocalSize 1 1 1
486+ OpDecorate %Payload_a Block
487+ OpMemberDecorate %Payload_a 0 Offset 0
488+ OpDecorate %Payload_b Block
489+ OpMemberDecorate %Payload_b 0 Offset 0
490+ %void = OpTypeVoid
491+ %void_fn = OpTypeFunction %void
492+ %int = OpTypeInt 32 1
493+ %Payload_a = OpTypeStruct %int
494+ %Payload_b = OpTypeStruct %int
495+ %_ptr_PSB_Payload_a = OpTypePointer PhysicalStorageBuffer %Payload_a
496+ %_ptr_PSB_Payload_b = OpTypePointer PhysicalStorageBuffer %Payload_b
497+ %Holder_src = OpTypeStruct %_ptr_PSB_Payload_a
498+ %Holder_dst = OpTypeStruct %_ptr_PSB_Payload_b
499+ %_ptr_Function_Holder_dst = OpTypePointer Function %Holder_dst
500+ %_ptr_Function_ptr_PSB_a = OpTypePointer Function %_ptr_PSB_Payload_a
501+ %main = OpFunction %void None %void_fn
502+ %entry = OpLabel
503+ %h = OpVariable %_ptr_Function_Holder_dst Function
504+ %pvar = OpVariable %_ptr_Function_ptr_PSB_a Function
505+ %p = OpLoad %_ptr_PSB_Payload_a %pvar
506+ %cc = OpCompositeConstruct %Holder_src %p
507+ %cl = OpCopyLogical %Holder_dst %cc
508+ OpStore %h %cl
509+ OpReturn
510+ OpFunctionEnd
511+ )" ;
512+
513+ SinglePassRunAndMatch<SimplificationPass>(text, false );
514+ }
515+
387516} // namespace
388517} // namespace opt
389518} // namespace spvtools
0 commit comments