// Copyright (c) 2022 Advanced Micro Devices, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "gmock/gmock.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" namespace spvtools { namespace opt { namespace { using FixFuncCallArgumentsTest = PassTest<::testing::Test>; TEST_F(FixFuncCallArgumentsTest, Simple) { const std::string text = R"( ; ; CHECK: [[v0:%\w+]] = OpVariable %_ptr_Function_float Function ; CHECK: [[v1:%\w+]] = OpVariable %_ptr_Function_float Function ; CHECK: [[v2:%\w+]] = OpVariable %_ptr_Function_T Function ; CHECK: [[ac0:%\w+]] = OpAccessChain %_ptr_Function_float %t %int_0 ; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform_float %r1 %int_0 %uint_0 ; CHECK: [[ld0:%\w+]] = OpLoad %float [[ac0]] ; CHECK: OpStore [[v1]] [[ld0]] ; CHECK: [[ld1:%\w+]] = OpLoad %float [[ac1]] ; CHECK: OpStore [[v0]] [[ld1]] ; CHECK: [[func:%\w+]] = OpFunctionCall %void %fn [[v1]] [[v0]] ; CHECK: [[ld2:%\w+]] = OpLoad %float [[v0]] ; CHECK: OpStore [[ac1]] [[ld2]] ; CHECK: [[ld3:%\w+]] = OpLoad %float [[v1]] ; CHECK: OpStore [[ac0]] [[ld3]] ; OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpSource HLSL 630 OpName %type_RWStructuredBuffer_float "type.RWStructuredBuffer.float" OpName %r1 "r1" OpName %type_ACSBuffer_counter "type.ACSBuffer.counter" OpMemberName %type_ACSBuffer_counter 0 "counter" OpName %counter_var_r1 "counter.var.r1" OpName %main "main" OpName %bb_entry "bb.entry" OpName %T "T" OpMemberName %T 0 "t0" OpName %t "t" OpName %fn "fn" OpName %p0 "p0" OpName %p2 "p2" OpName %bb_entry_0 "bb.entry" OpDecorate %main LinkageAttributes "main" Export OpDecorate %r1 DescriptorSet 0 OpDecorate %r1 Binding 0 OpDecorate %counter_var_r1 DescriptorSet 0 OpDecorate %counter_var_r1 Binding 1 OpDecorate %_runtimearr_float ArrayStride 4 OpMemberDecorate %type_RWStructuredBuffer_float 0 Offset 0 OpDecorate %type_RWStructuredBuffer_float BufferBlock OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0 OpDecorate %type_ACSBuffer_counter BufferBlock %int = OpTypeInt 32 1 %int_0 = OpConstant %int 0 %uint = OpTypeInt 32 0 %uint_0 = OpConstant %uint 0 %int_1 = OpConstant %int 1 %float = OpTypeFloat 32 %_runtimearr_float = OpTypeRuntimeArray %float %type_RWStructuredBuffer_float = OpTypeStruct %_runtimearr_float %_ptr_Uniform_type_RWStructuredBuffer_float = OpTypePointer Uniform %type_RWStructuredBuffer_float %type_ACSBuffer_counter = OpTypeStruct %int %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter %15 = OpTypeFunction %int %T = OpTypeStruct %float %_ptr_Function_T = OpTypePointer Function %T %_ptr_Function_float = OpTypePointer Function %float %_ptr_Uniform_float = OpTypePointer Uniform %float %void = OpTypeVoid %27 = OpTypeFunction %void %_ptr_Function_float %_ptr_Function_float %r1 = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_float Uniform %counter_var_r1 = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform %main = OpFunction %int None %15 %bb_entry = OpLabel %t = OpVariable %_ptr_Function_T Function %21 = OpAccessChain %_ptr_Function_float %t %int_0 %23 = OpAccessChain %_ptr_Uniform_float %r1 %int_0 %uint_0 %25 = OpFunctionCall %void %fn %21 %23 OpReturnValue %int_1 OpFunctionEnd %fn = OpFunction %void DontInline %27 %p0 = OpFunctionParameter %_ptr_Function_float %p2 = OpFunctionParameter %_ptr_Function_float %bb_entry_0 = OpLabel OpReturn OpFunctionEnd )"; SinglePassRunAndMatch(text, true); } TEST_F(FixFuncCallArgumentsTest, NotAccessChainInput) { const std::string text = R"( ; ; CHECK: [[o:%\w+]] = OpCopyObject %_ptr_Function_float %t ; CHECK: [[func:%\w+]] = OpFunctionCall %void %fn [[o]] ; OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpSource HLSL 630 OpName %main "main" OpName %bb_entry "bb.entry" OpName %t "t" OpName %fn "fn" OpName %p0 "p0" OpName %bb_entry_0 "bb.entry" OpDecorate %main LinkageAttributes "main" Export %int = OpTypeInt 32 1 %int_1 = OpConstant %int 1 %4 = OpTypeFunction %int %float = OpTypeFloat 32 %_ptr_Function_float = OpTypePointer Function %float %void = OpTypeVoid %12 = OpTypeFunction %void %_ptr_Function_float %main = OpFunction %int None %4 %bb_entry = OpLabel %t = OpVariable %_ptr_Function_float Function %t1 = OpCopyObject %_ptr_Function_float %t %10 = OpFunctionCall %void %fn %t1 OpReturnValue %int_1 OpFunctionEnd %fn = OpFunction %void DontInline %12 %p0 = OpFunctionParameter %_ptr_Function_float %bb_entry_0 = OpLabel OpReturn OpFunctionEnd )"; SinglePassRunAndMatch(text, false); } } // namespace } // namespace opt } // namespace spvtools