1fd4e5da5Sopenharmony_ci// Copyright (c) 2017-2022 Valve Corporation 2fd4e5da5Sopenharmony_ci// Copyright (c) 2017-2022 LunarG Inc. 3fd4e5da5Sopenharmony_ci// 4fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 5fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 6fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 7fd4e5da5Sopenharmony_ci// 8fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 9fd4e5da5Sopenharmony_ci// 10fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 11fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 12fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 14fd4e5da5Sopenharmony_ci// limitations under the License. 15fd4e5da5Sopenharmony_ci 16fd4e5da5Sopenharmony_ci#include <memory> 17fd4e5da5Sopenharmony_ci#include <string> 18fd4e5da5Sopenharmony_ci#include <vector> 19fd4e5da5Sopenharmony_ci 20fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 21fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_cinamespace spvtools { 24fd4e5da5Sopenharmony_cinamespace opt { 25fd4e5da5Sopenharmony_cinamespace { 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciusing InlineTest = PassTest<::testing::Test>; 28fd4e5da5Sopenharmony_ci 29fd4e5da5Sopenharmony_ciTEST_F(InlineTest, Simple) { 30fd4e5da5Sopenharmony_ci // #version 140 31fd4e5da5Sopenharmony_ci // 32fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 33fd4e5da5Sopenharmony_ci // 34fd4e5da5Sopenharmony_ci // float foo(vec4 bar) 35fd4e5da5Sopenharmony_ci // { 36fd4e5da5Sopenharmony_ci // return bar.x + bar.y; 37fd4e5da5Sopenharmony_ci // } 38fd4e5da5Sopenharmony_ci // 39fd4e5da5Sopenharmony_ci // void main() 40fd4e5da5Sopenharmony_ci // { 41fd4e5da5Sopenharmony_ci // vec4 color = vec4(foo(BaseColor)); 42fd4e5da5Sopenharmony_ci // gl_FragColor = color; 43fd4e5da5Sopenharmony_ci // } 44fd4e5da5Sopenharmony_ci const std::vector<const char*> predefs = { 45fd4e5da5Sopenharmony_ci // clang-format off 46fd4e5da5Sopenharmony_ci "OpCapability Shader", 47fd4e5da5Sopenharmony_ci "%1 = OpExtInstImport \"GLSL.std.450\"", 48fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 49fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\" %BaseColor %gl_FragColor", 50fd4e5da5Sopenharmony_ci "OpExecutionMode %main OriginUpperLeft", 51fd4e5da5Sopenharmony_ci "OpSource GLSL 140", 52fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 53fd4e5da5Sopenharmony_ci "OpName %foo_vf4_ \"foo(vf4;\"", 54fd4e5da5Sopenharmony_ci "OpName %bar \"bar\"", 55fd4e5da5Sopenharmony_ci "OpName %color \"color\"", 56fd4e5da5Sopenharmony_ci "OpName %BaseColor \"BaseColor\"", 57fd4e5da5Sopenharmony_ci "OpName %param \"param\"", 58fd4e5da5Sopenharmony_ci "OpName %gl_FragColor \"gl_FragColor\"", 59fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 60fd4e5da5Sopenharmony_ci "%10 = OpTypeFunction %void", 61fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 62fd4e5da5Sopenharmony_ci "%v4float = OpTypeVector %float 4", 63fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float", 64fd4e5da5Sopenharmony_ci "%14 = OpTypeFunction %float %_ptr_Function_v4float", 65fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 66fd4e5da5Sopenharmony_ci "%uint_0 = OpConstant %uint 0", 67fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float", 68fd4e5da5Sopenharmony_ci "%uint_1 = OpConstant %uint 1", 69fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float", 70fd4e5da5Sopenharmony_ci "%BaseColor = OpVariable %_ptr_Input_v4float Input", 71fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float", 72fd4e5da5Sopenharmony_ci"%gl_FragColor = OpVariable %_ptr_Output_v4float Output", 73fd4e5da5Sopenharmony_ci // clang-format on 74fd4e5da5Sopenharmony_ci }; 75fd4e5da5Sopenharmony_ci 76fd4e5da5Sopenharmony_ci const std::vector<const char*> nonEntryFuncs = { 77fd4e5da5Sopenharmony_ci // clang-format off 78fd4e5da5Sopenharmony_ci "%foo_vf4_ = OpFunction %float None %14", 79fd4e5da5Sopenharmony_ci "%bar = OpFunctionParameter %_ptr_Function_v4float", 80fd4e5da5Sopenharmony_ci "%26 = OpLabel", 81fd4e5da5Sopenharmony_ci "%27 = OpAccessChain %_ptr_Function_float %bar %uint_0", 82fd4e5da5Sopenharmony_ci "%28 = OpLoad %float %27", 83fd4e5da5Sopenharmony_ci "%29 = OpAccessChain %_ptr_Function_float %bar %uint_1", 84fd4e5da5Sopenharmony_ci "%30 = OpLoad %float %29", 85fd4e5da5Sopenharmony_ci "%31 = OpFAdd %float %28 %30", 86fd4e5da5Sopenharmony_ci "OpReturnValue %31", 87fd4e5da5Sopenharmony_ci "OpFunctionEnd", 88fd4e5da5Sopenharmony_ci // clang-format on 89fd4e5da5Sopenharmony_ci }; 90fd4e5da5Sopenharmony_ci 91fd4e5da5Sopenharmony_ci const std::vector<const char*> before = { 92fd4e5da5Sopenharmony_ci // clang-format off 93fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %10", 94fd4e5da5Sopenharmony_ci "%21 = OpLabel", 95fd4e5da5Sopenharmony_ci "%color = OpVariable %_ptr_Function_v4float Function", 96fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 97fd4e5da5Sopenharmony_ci "%22 = OpLoad %v4float %BaseColor", 98fd4e5da5Sopenharmony_ci "OpStore %param %22", 99fd4e5da5Sopenharmony_ci "%23 = OpFunctionCall %float %foo_vf4_ %param", 100fd4e5da5Sopenharmony_ci "%24 = OpCompositeConstruct %v4float %23 %23 %23 %23", 101fd4e5da5Sopenharmony_ci "OpStore %color %24", 102fd4e5da5Sopenharmony_ci "%25 = OpLoad %v4float %color", 103fd4e5da5Sopenharmony_ci "OpStore %gl_FragColor %25", 104fd4e5da5Sopenharmony_ci "OpReturn", 105fd4e5da5Sopenharmony_ci "OpFunctionEnd", 106fd4e5da5Sopenharmony_ci // clang-format on 107fd4e5da5Sopenharmony_ci }; 108fd4e5da5Sopenharmony_ci 109fd4e5da5Sopenharmony_ci const std::vector<const char*> after = { 110fd4e5da5Sopenharmony_ci // clang-format off 111fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %10", 112fd4e5da5Sopenharmony_ci "%21 = OpLabel", 113fd4e5da5Sopenharmony_ci "%32 = OpVariable %_ptr_Function_float Function", 114fd4e5da5Sopenharmony_ci "%color = OpVariable %_ptr_Function_v4float Function", 115fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 116fd4e5da5Sopenharmony_ci "%22 = OpLoad %v4float %BaseColor", 117fd4e5da5Sopenharmony_ci "OpStore %param %22", 118fd4e5da5Sopenharmony_ci "%34 = OpAccessChain %_ptr_Function_float %param %uint_0", 119fd4e5da5Sopenharmony_ci "%35 = OpLoad %float %34", 120fd4e5da5Sopenharmony_ci "%36 = OpAccessChain %_ptr_Function_float %param %uint_1", 121fd4e5da5Sopenharmony_ci "%37 = OpLoad %float %36", 122fd4e5da5Sopenharmony_ci "%38 = OpFAdd %float %35 %37", 123fd4e5da5Sopenharmony_ci "OpStore %32 %38", 124fd4e5da5Sopenharmony_ci "%23 = OpLoad %float %32", 125fd4e5da5Sopenharmony_ci "%24 = OpCompositeConstruct %v4float %23 %23 %23 %23", 126fd4e5da5Sopenharmony_ci "OpStore %color %24", 127fd4e5da5Sopenharmony_ci "%25 = OpLoad %v4float %color", 128fd4e5da5Sopenharmony_ci "OpStore %gl_FragColor %25", 129fd4e5da5Sopenharmony_ci "OpReturn", 130fd4e5da5Sopenharmony_ci "OpFunctionEnd", 131fd4e5da5Sopenharmony_ci // clang-format on 132fd4e5da5Sopenharmony_ci }; 133fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>( 134fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)), 135fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)), 136fd4e5da5Sopenharmony_ci /* skip_nop = */ false, /* do_validate = */ true); 137fd4e5da5Sopenharmony_ci} 138fd4e5da5Sopenharmony_ci 139fd4e5da5Sopenharmony_ciTEST_F(InlineTest, Nested) { 140fd4e5da5Sopenharmony_ci // #version 140 141fd4e5da5Sopenharmony_ci // 142fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 143fd4e5da5Sopenharmony_ci // 144fd4e5da5Sopenharmony_ci // float foo2(float f, float f2) 145fd4e5da5Sopenharmony_ci // { 146fd4e5da5Sopenharmony_ci // return f * f2; 147fd4e5da5Sopenharmony_ci // } 148fd4e5da5Sopenharmony_ci // 149fd4e5da5Sopenharmony_ci // float foo(vec4 bar) 150fd4e5da5Sopenharmony_ci // { 151fd4e5da5Sopenharmony_ci // return foo2(bar.x + bar.y, bar.z); 152fd4e5da5Sopenharmony_ci // } 153fd4e5da5Sopenharmony_ci // 154fd4e5da5Sopenharmony_ci // void main() 155fd4e5da5Sopenharmony_ci // { 156fd4e5da5Sopenharmony_ci // vec4 color = vec4(foo(BaseColor)); 157fd4e5da5Sopenharmony_ci // gl_FragColor = color; 158fd4e5da5Sopenharmony_ci // } 159fd4e5da5Sopenharmony_ci const std::vector<const char*> predefs = { 160fd4e5da5Sopenharmony_ci // clang-format off 161fd4e5da5Sopenharmony_ci "OpCapability Shader", 162fd4e5da5Sopenharmony_ci "%1 = OpExtInstImport \"GLSL.std.450\"", 163fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 164fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\" %BaseColor %gl_FragColor", 165fd4e5da5Sopenharmony_ci "OpExecutionMode %main OriginUpperLeft", 166fd4e5da5Sopenharmony_ci "OpSource GLSL 140", 167fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 168fd4e5da5Sopenharmony_ci "OpName %foo2_f1_f1_ \"foo2(f1;f1;\"", 169fd4e5da5Sopenharmony_ci "OpName %f \"f\"", 170fd4e5da5Sopenharmony_ci "OpName %f2 \"f2\"", 171fd4e5da5Sopenharmony_ci "OpName %foo_vf4_ \"foo(vf4;\"", 172fd4e5da5Sopenharmony_ci "OpName %bar \"bar\"", 173fd4e5da5Sopenharmony_ci "OpName %param \"param\"", 174fd4e5da5Sopenharmony_ci "OpName %param_0 \"param\"", 175fd4e5da5Sopenharmony_ci "OpName %color \"color\"", 176fd4e5da5Sopenharmony_ci "OpName %BaseColor \"BaseColor\"", 177fd4e5da5Sopenharmony_ci "OpName %param_1 \"param\"", 178fd4e5da5Sopenharmony_ci "OpName %gl_FragColor \"gl_FragColor\"", 179fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 180fd4e5da5Sopenharmony_ci "%15 = OpTypeFunction %void", 181fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 182fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float", 183fd4e5da5Sopenharmony_ci "%18 = OpTypeFunction %float %_ptr_Function_float %_ptr_Function_float", 184fd4e5da5Sopenharmony_ci "%v4float = OpTypeVector %float 4", 185fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float", 186fd4e5da5Sopenharmony_ci "%21 = OpTypeFunction %float %_ptr_Function_v4float", 187fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 188fd4e5da5Sopenharmony_ci "%uint_0 = OpConstant %uint 0", 189fd4e5da5Sopenharmony_ci "%uint_1 = OpConstant %uint 1", 190fd4e5da5Sopenharmony_ci "%uint_2 = OpConstant %uint 2", 191fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float", 192fd4e5da5Sopenharmony_ci "%BaseColor = OpVariable %_ptr_Input_v4float Input", 193fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float", 194fd4e5da5Sopenharmony_ci"%gl_FragColor = OpVariable %_ptr_Output_v4float Output", 195fd4e5da5Sopenharmony_ci // clang-format on 196fd4e5da5Sopenharmony_ci }; 197fd4e5da5Sopenharmony_ci 198fd4e5da5Sopenharmony_ci const std::vector<const char*> nonEntryFuncs = { 199fd4e5da5Sopenharmony_ci // clang-format off 200fd4e5da5Sopenharmony_ci"%foo2_f1_f1_ = OpFunction %float None %18", 201fd4e5da5Sopenharmony_ci "%f = OpFunctionParameter %_ptr_Function_float", 202fd4e5da5Sopenharmony_ci "%f2 = OpFunctionParameter %_ptr_Function_float", 203fd4e5da5Sopenharmony_ci "%33 = OpLabel", 204fd4e5da5Sopenharmony_ci "%34 = OpLoad %float %f", 205fd4e5da5Sopenharmony_ci "%35 = OpLoad %float %f2", 206fd4e5da5Sopenharmony_ci "%36 = OpFMul %float %34 %35", 207fd4e5da5Sopenharmony_ci "OpReturnValue %36", 208fd4e5da5Sopenharmony_ci "OpFunctionEnd", 209fd4e5da5Sopenharmony_ci "%foo_vf4_ = OpFunction %float None %21", 210fd4e5da5Sopenharmony_ci "%bar = OpFunctionParameter %_ptr_Function_v4float", 211fd4e5da5Sopenharmony_ci "%37 = OpLabel", 212fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_float Function", 213fd4e5da5Sopenharmony_ci "%param_0 = OpVariable %_ptr_Function_float Function", 214fd4e5da5Sopenharmony_ci "%38 = OpAccessChain %_ptr_Function_float %bar %uint_0", 215fd4e5da5Sopenharmony_ci "%39 = OpLoad %float %38", 216fd4e5da5Sopenharmony_ci "%40 = OpAccessChain %_ptr_Function_float %bar %uint_1", 217fd4e5da5Sopenharmony_ci "%41 = OpLoad %float %40", 218fd4e5da5Sopenharmony_ci "%42 = OpFAdd %float %39 %41", 219fd4e5da5Sopenharmony_ci "OpStore %param %42", 220fd4e5da5Sopenharmony_ci "%43 = OpAccessChain %_ptr_Function_float %bar %uint_2", 221fd4e5da5Sopenharmony_ci "%44 = OpLoad %float %43", 222fd4e5da5Sopenharmony_ci "OpStore %param_0 %44", 223fd4e5da5Sopenharmony_ci "%45 = OpFunctionCall %float %foo2_f1_f1_ %param %param_0", 224fd4e5da5Sopenharmony_ci "OpReturnValue %45", 225fd4e5da5Sopenharmony_ci "OpFunctionEnd", 226fd4e5da5Sopenharmony_ci // clang-format on 227fd4e5da5Sopenharmony_ci }; 228fd4e5da5Sopenharmony_ci 229fd4e5da5Sopenharmony_ci const std::vector<const char*> before = { 230fd4e5da5Sopenharmony_ci // clang-format off 231fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %15", 232fd4e5da5Sopenharmony_ci "%28 = OpLabel", 233fd4e5da5Sopenharmony_ci "%color = OpVariable %_ptr_Function_v4float Function", 234fd4e5da5Sopenharmony_ci "%param_1 = OpVariable %_ptr_Function_v4float Function", 235fd4e5da5Sopenharmony_ci "%29 = OpLoad %v4float %BaseColor", 236fd4e5da5Sopenharmony_ci "OpStore %param_1 %29", 237fd4e5da5Sopenharmony_ci "%30 = OpFunctionCall %float %foo_vf4_ %param_1", 238fd4e5da5Sopenharmony_ci "%31 = OpCompositeConstruct %v4float %30 %30 %30 %30", 239fd4e5da5Sopenharmony_ci "OpStore %color %31", 240fd4e5da5Sopenharmony_ci "%32 = OpLoad %v4float %color", 241fd4e5da5Sopenharmony_ci "OpStore %gl_FragColor %32", 242fd4e5da5Sopenharmony_ci "OpReturn", 243fd4e5da5Sopenharmony_ci "OpFunctionEnd", 244fd4e5da5Sopenharmony_ci // clang-format on 245fd4e5da5Sopenharmony_ci }; 246fd4e5da5Sopenharmony_ci 247fd4e5da5Sopenharmony_ci const std::vector<const char*> after = { 248fd4e5da5Sopenharmony_ci // clang-format off 249fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %15", 250fd4e5da5Sopenharmony_ci "%28 = OpLabel", 251fd4e5da5Sopenharmony_ci "%58 = OpVariable %_ptr_Function_float Function", 252fd4e5da5Sopenharmony_ci "%46 = OpVariable %_ptr_Function_float Function", 253fd4e5da5Sopenharmony_ci "%47 = OpVariable %_ptr_Function_float Function", 254fd4e5da5Sopenharmony_ci "%48 = OpVariable %_ptr_Function_float Function", 255fd4e5da5Sopenharmony_ci "%color = OpVariable %_ptr_Function_v4float Function", 256fd4e5da5Sopenharmony_ci "%param_1 = OpVariable %_ptr_Function_v4float Function", 257fd4e5da5Sopenharmony_ci "%29 = OpLoad %v4float %BaseColor", 258fd4e5da5Sopenharmony_ci "OpStore %param_1 %29", 259fd4e5da5Sopenharmony_ci "%50 = OpAccessChain %_ptr_Function_float %param_1 %uint_0", 260fd4e5da5Sopenharmony_ci "%51 = OpLoad %float %50", 261fd4e5da5Sopenharmony_ci "%52 = OpAccessChain %_ptr_Function_float %param_1 %uint_1", 262fd4e5da5Sopenharmony_ci "%53 = OpLoad %float %52", 263fd4e5da5Sopenharmony_ci "%54 = OpFAdd %float %51 %53", 264fd4e5da5Sopenharmony_ci "OpStore %46 %54", 265fd4e5da5Sopenharmony_ci "%55 = OpAccessChain %_ptr_Function_float %param_1 %uint_2", 266fd4e5da5Sopenharmony_ci "%56 = OpLoad %float %55", 267fd4e5da5Sopenharmony_ci "OpStore %47 %56", 268fd4e5da5Sopenharmony_ci "%60 = OpLoad %float %46", 269fd4e5da5Sopenharmony_ci "%61 = OpLoad %float %47", 270fd4e5da5Sopenharmony_ci "%62 = OpFMul %float %60 %61", 271fd4e5da5Sopenharmony_ci "OpStore %58 %62", 272fd4e5da5Sopenharmony_ci "%57 = OpLoad %float %58", 273fd4e5da5Sopenharmony_ci "OpStore %48 %57", 274fd4e5da5Sopenharmony_ci "%30 = OpLoad %float %48", 275fd4e5da5Sopenharmony_ci "%31 = OpCompositeConstruct %v4float %30 %30 %30 %30", 276fd4e5da5Sopenharmony_ci "OpStore %color %31", 277fd4e5da5Sopenharmony_ci "%32 = OpLoad %v4float %color", 278fd4e5da5Sopenharmony_ci "OpStore %gl_FragColor %32", 279fd4e5da5Sopenharmony_ci "OpReturn", 280fd4e5da5Sopenharmony_ci "OpFunctionEnd", 281fd4e5da5Sopenharmony_ci // clang-format on 282fd4e5da5Sopenharmony_ci }; 283fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>( 284fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)), 285fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)), 286fd4e5da5Sopenharmony_ci /* skip_nop = */ false, /* do_validate = */ true); 287fd4e5da5Sopenharmony_ci} 288fd4e5da5Sopenharmony_ci 289fd4e5da5Sopenharmony_ciTEST_F(InlineTest, InOutParameter) { 290fd4e5da5Sopenharmony_ci // #version 400 291fd4e5da5Sopenharmony_ci // 292fd4e5da5Sopenharmony_ci // in vec4 Basecolor; 293fd4e5da5Sopenharmony_ci // 294fd4e5da5Sopenharmony_ci // void foo(inout vec4 bar) 295fd4e5da5Sopenharmony_ci // { 296fd4e5da5Sopenharmony_ci // bar.z = bar.x + bar.y; 297fd4e5da5Sopenharmony_ci // } 298fd4e5da5Sopenharmony_ci // 299fd4e5da5Sopenharmony_ci // void main() 300fd4e5da5Sopenharmony_ci // { 301fd4e5da5Sopenharmony_ci // vec4 b = Basecolor; 302fd4e5da5Sopenharmony_ci // foo(b); 303fd4e5da5Sopenharmony_ci // vec4 color = vec4(b.z); 304fd4e5da5Sopenharmony_ci // gl_FragColor = color; 305fd4e5da5Sopenharmony_ci // } 306fd4e5da5Sopenharmony_ci const std::vector<const char*> predefs = { 307fd4e5da5Sopenharmony_ci // clang-format off 308fd4e5da5Sopenharmony_ci "OpCapability Shader", 309fd4e5da5Sopenharmony_ci "%1 = OpExtInstImport \"GLSL.std.450\"", 310fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 311fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\" %Basecolor %gl_FragColor", 312fd4e5da5Sopenharmony_ci "OpExecutionMode %main OriginUpperLeft", 313fd4e5da5Sopenharmony_ci "OpSource GLSL 400", 314fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 315fd4e5da5Sopenharmony_ci "OpName %foo_vf4_ \"foo(vf4;\"", 316fd4e5da5Sopenharmony_ci "OpName %bar \"bar\"", 317fd4e5da5Sopenharmony_ci "OpName %b \"b\"", 318fd4e5da5Sopenharmony_ci "OpName %Basecolor \"Basecolor\"", 319fd4e5da5Sopenharmony_ci "OpName %param \"param\"", 320fd4e5da5Sopenharmony_ci "OpName %color \"color\"", 321fd4e5da5Sopenharmony_ci "OpName %gl_FragColor \"gl_FragColor\"", 322fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 323fd4e5da5Sopenharmony_ci "%11 = OpTypeFunction %void", 324fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 325fd4e5da5Sopenharmony_ci "%v4float = OpTypeVector %float 4", 326fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float", 327fd4e5da5Sopenharmony_ci "%15 = OpTypeFunction %void %_ptr_Function_v4float", 328fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 329fd4e5da5Sopenharmony_ci "%uint_0 = OpConstant %uint 0", 330fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float", 331fd4e5da5Sopenharmony_ci "%uint_1 = OpConstant %uint 1", 332fd4e5da5Sopenharmony_ci "%uint_2 = OpConstant %uint 2", 333fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float", 334fd4e5da5Sopenharmony_ci "%Basecolor = OpVariable %_ptr_Input_v4float Input", 335fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float", 336fd4e5da5Sopenharmony_ci"%gl_FragColor = OpVariable %_ptr_Output_v4float Output", 337fd4e5da5Sopenharmony_ci // clang-format on 338fd4e5da5Sopenharmony_ci }; 339fd4e5da5Sopenharmony_ci 340fd4e5da5Sopenharmony_ci const std::vector<const char*> nonEntryFuncs = { 341fd4e5da5Sopenharmony_ci // clang-format off 342fd4e5da5Sopenharmony_ci "%foo_vf4_ = OpFunction %void None %15", 343fd4e5da5Sopenharmony_ci "%bar = OpFunctionParameter %_ptr_Function_v4float", 344fd4e5da5Sopenharmony_ci "%32 = OpLabel", 345fd4e5da5Sopenharmony_ci "%33 = OpAccessChain %_ptr_Function_float %bar %uint_0", 346fd4e5da5Sopenharmony_ci "%34 = OpLoad %float %33", 347fd4e5da5Sopenharmony_ci "%35 = OpAccessChain %_ptr_Function_float %bar %uint_1", 348fd4e5da5Sopenharmony_ci "%36 = OpLoad %float %35", 349fd4e5da5Sopenharmony_ci "%37 = OpFAdd %float %34 %36", 350fd4e5da5Sopenharmony_ci "%38 = OpAccessChain %_ptr_Function_float %bar %uint_2", 351fd4e5da5Sopenharmony_ci "OpStore %38 %37", 352fd4e5da5Sopenharmony_ci "OpReturn", 353fd4e5da5Sopenharmony_ci "OpFunctionEnd", 354fd4e5da5Sopenharmony_ci // clang-format on 355fd4e5da5Sopenharmony_ci }; 356fd4e5da5Sopenharmony_ci 357fd4e5da5Sopenharmony_ci const std::vector<const char*> before = { 358fd4e5da5Sopenharmony_ci // clang-format off 359fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %11", 360fd4e5da5Sopenharmony_ci "%23 = OpLabel", 361fd4e5da5Sopenharmony_ci "%b = OpVariable %_ptr_Function_v4float Function", 362fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 363fd4e5da5Sopenharmony_ci "%color = OpVariable %_ptr_Function_v4float Function", 364fd4e5da5Sopenharmony_ci "%24 = OpLoad %v4float %Basecolor", 365fd4e5da5Sopenharmony_ci "OpStore %b %24", 366fd4e5da5Sopenharmony_ci "%25 = OpLoad %v4float %b", 367fd4e5da5Sopenharmony_ci "OpStore %param %25", 368fd4e5da5Sopenharmony_ci "%26 = OpFunctionCall %void %foo_vf4_ %param", 369fd4e5da5Sopenharmony_ci "%27 = OpLoad %v4float %param", 370fd4e5da5Sopenharmony_ci "OpStore %b %27", 371fd4e5da5Sopenharmony_ci "%28 = OpAccessChain %_ptr_Function_float %b %uint_2", 372fd4e5da5Sopenharmony_ci "%29 = OpLoad %float %28", 373fd4e5da5Sopenharmony_ci "%30 = OpCompositeConstruct %v4float %29 %29 %29 %29", 374fd4e5da5Sopenharmony_ci "OpStore %color %30", 375fd4e5da5Sopenharmony_ci "%31 = OpLoad %v4float %color", 376fd4e5da5Sopenharmony_ci "OpStore %gl_FragColor %31", 377fd4e5da5Sopenharmony_ci "OpReturn", 378fd4e5da5Sopenharmony_ci "OpFunctionEnd", 379fd4e5da5Sopenharmony_ci // clang-format on 380fd4e5da5Sopenharmony_ci }; 381fd4e5da5Sopenharmony_ci 382fd4e5da5Sopenharmony_ci const std::vector<const char*> after = { 383fd4e5da5Sopenharmony_ci // clang-format off 384fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %11", 385fd4e5da5Sopenharmony_ci "%23 = OpLabel", 386fd4e5da5Sopenharmony_ci "%b = OpVariable %_ptr_Function_v4float Function", 387fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 388fd4e5da5Sopenharmony_ci "%color = OpVariable %_ptr_Function_v4float Function", 389fd4e5da5Sopenharmony_ci "%24 = OpLoad %v4float %Basecolor", 390fd4e5da5Sopenharmony_ci "OpStore %b %24", 391fd4e5da5Sopenharmony_ci "%25 = OpLoad %v4float %b", 392fd4e5da5Sopenharmony_ci "OpStore %param %25", 393fd4e5da5Sopenharmony_ci "%40 = OpAccessChain %_ptr_Function_float %param %uint_0", 394fd4e5da5Sopenharmony_ci "%41 = OpLoad %float %40", 395fd4e5da5Sopenharmony_ci "%42 = OpAccessChain %_ptr_Function_float %param %uint_1", 396fd4e5da5Sopenharmony_ci "%43 = OpLoad %float %42", 397fd4e5da5Sopenharmony_ci "%44 = OpFAdd %float %41 %43", 398fd4e5da5Sopenharmony_ci "%45 = OpAccessChain %_ptr_Function_float %param %uint_2", 399fd4e5da5Sopenharmony_ci "OpStore %45 %44", 400fd4e5da5Sopenharmony_ci "%27 = OpLoad %v4float %param", 401fd4e5da5Sopenharmony_ci "OpStore %b %27", 402fd4e5da5Sopenharmony_ci "%28 = OpAccessChain %_ptr_Function_float %b %uint_2", 403fd4e5da5Sopenharmony_ci "%29 = OpLoad %float %28", 404fd4e5da5Sopenharmony_ci "%30 = OpCompositeConstruct %v4float %29 %29 %29 %29", 405fd4e5da5Sopenharmony_ci "OpStore %color %30", 406fd4e5da5Sopenharmony_ci "%31 = OpLoad %v4float %color", 407fd4e5da5Sopenharmony_ci "OpStore %gl_FragColor %31", 408fd4e5da5Sopenharmony_ci "OpReturn", 409fd4e5da5Sopenharmony_ci "OpFunctionEnd", 410fd4e5da5Sopenharmony_ci // clang-format on 411fd4e5da5Sopenharmony_ci }; 412fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>( 413fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)), 414fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)), 415fd4e5da5Sopenharmony_ci /* skip_nop = */ false, /* do_validate = */ true); 416fd4e5da5Sopenharmony_ci} 417fd4e5da5Sopenharmony_ci 418fd4e5da5Sopenharmony_ciTEST_F(InlineTest, BranchInCallee) { 419fd4e5da5Sopenharmony_ci // #version 140 420fd4e5da5Sopenharmony_ci // 421fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 422fd4e5da5Sopenharmony_ci // 423fd4e5da5Sopenharmony_ci // float foo(vec4 bar) 424fd4e5da5Sopenharmony_ci // { 425fd4e5da5Sopenharmony_ci // float r = bar.x; 426fd4e5da5Sopenharmony_ci // if (r < 0.0) 427fd4e5da5Sopenharmony_ci // r = -r; 428fd4e5da5Sopenharmony_ci // return r; 429fd4e5da5Sopenharmony_ci // } 430fd4e5da5Sopenharmony_ci // 431fd4e5da5Sopenharmony_ci // void main() 432fd4e5da5Sopenharmony_ci // { 433fd4e5da5Sopenharmony_ci // vec4 color = vec4(foo(BaseColor)); 434fd4e5da5Sopenharmony_ci // 435fd4e5da5Sopenharmony_ci // gl_FragColor = color; 436fd4e5da5Sopenharmony_ci // } 437fd4e5da5Sopenharmony_ci const std::vector<const char*> predefs = { 438fd4e5da5Sopenharmony_ci // clang-format off 439fd4e5da5Sopenharmony_ci "OpCapability Shader", 440fd4e5da5Sopenharmony_ci "%1 = OpExtInstImport \"GLSL.std.450\"", 441fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 442fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\" %BaseColor %gl_FragColor", 443fd4e5da5Sopenharmony_ci "OpExecutionMode %main OriginUpperLeft", 444fd4e5da5Sopenharmony_ci "OpSource GLSL 140", 445fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 446fd4e5da5Sopenharmony_ci "OpName %foo_vf4_ \"foo(vf4;\"", 447fd4e5da5Sopenharmony_ci "OpName %bar \"bar\"", 448fd4e5da5Sopenharmony_ci "OpName %r \"r\"", 449fd4e5da5Sopenharmony_ci "OpName %color \"color\"", 450fd4e5da5Sopenharmony_ci "OpName %BaseColor \"BaseColor\"", 451fd4e5da5Sopenharmony_ci "OpName %param \"param\"", 452fd4e5da5Sopenharmony_ci "OpName %gl_FragColor \"gl_FragColor\"", 453fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 454fd4e5da5Sopenharmony_ci "%11 = OpTypeFunction %void", 455fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 456fd4e5da5Sopenharmony_ci "%v4float = OpTypeVector %float 4", 457fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float", 458fd4e5da5Sopenharmony_ci "%15 = OpTypeFunction %float %_ptr_Function_v4float", 459fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float", 460fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 461fd4e5da5Sopenharmony_ci "%uint_0 = OpConstant %uint 0", 462fd4e5da5Sopenharmony_ci "%float_0 = OpConstant %float 0", 463fd4e5da5Sopenharmony_ci "%bool = OpTypeBool", 464fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float", 465fd4e5da5Sopenharmony_ci "%BaseColor = OpVariable %_ptr_Input_v4float Input", 466fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float", 467fd4e5da5Sopenharmony_ci"%gl_FragColor = OpVariable %_ptr_Output_v4float Output", 468fd4e5da5Sopenharmony_ci // clang-format on 469fd4e5da5Sopenharmony_ci }; 470fd4e5da5Sopenharmony_ci 471fd4e5da5Sopenharmony_ci const std::vector<const char*> nonEntryFuncs = { 472fd4e5da5Sopenharmony_ci // clang-format off 473fd4e5da5Sopenharmony_ci "%foo_vf4_ = OpFunction %float None %15", 474fd4e5da5Sopenharmony_ci "%bar = OpFunctionParameter %_ptr_Function_v4float", 475fd4e5da5Sopenharmony_ci "%28 = OpLabel", 476fd4e5da5Sopenharmony_ci "%r = OpVariable %_ptr_Function_float Function", 477fd4e5da5Sopenharmony_ci "%29 = OpAccessChain %_ptr_Function_float %bar %uint_0", 478fd4e5da5Sopenharmony_ci "%30 = OpLoad %float %29", 479fd4e5da5Sopenharmony_ci "OpStore %r %30", 480fd4e5da5Sopenharmony_ci "%31 = OpLoad %float %r", 481fd4e5da5Sopenharmony_ci "%32 = OpFOrdLessThan %bool %31 %float_0", 482fd4e5da5Sopenharmony_ci "OpSelectionMerge %33 None", 483fd4e5da5Sopenharmony_ci "OpBranchConditional %32 %34 %33", 484fd4e5da5Sopenharmony_ci "%34 = OpLabel", 485fd4e5da5Sopenharmony_ci "%35 = OpLoad %float %r", 486fd4e5da5Sopenharmony_ci "%36 = OpFNegate %float %35", 487fd4e5da5Sopenharmony_ci "OpStore %r %36", 488fd4e5da5Sopenharmony_ci "OpBranch %33", 489fd4e5da5Sopenharmony_ci "%33 = OpLabel", 490fd4e5da5Sopenharmony_ci "%37 = OpLoad %float %r", 491fd4e5da5Sopenharmony_ci "OpReturnValue %37", 492fd4e5da5Sopenharmony_ci "OpFunctionEnd", 493fd4e5da5Sopenharmony_ci // clang-format on 494fd4e5da5Sopenharmony_ci }; 495fd4e5da5Sopenharmony_ci 496fd4e5da5Sopenharmony_ci const std::vector<const char*> before = { 497fd4e5da5Sopenharmony_ci // clang-format off 498fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %11", 499fd4e5da5Sopenharmony_ci "%23 = OpLabel", 500fd4e5da5Sopenharmony_ci "%color = OpVariable %_ptr_Function_v4float Function", 501fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 502fd4e5da5Sopenharmony_ci "%24 = OpLoad %v4float %BaseColor", 503fd4e5da5Sopenharmony_ci "OpStore %param %24", 504fd4e5da5Sopenharmony_ci "%25 = OpFunctionCall %float %foo_vf4_ %param", 505fd4e5da5Sopenharmony_ci "%26 = OpCompositeConstruct %v4float %25 %25 %25 %25", 506fd4e5da5Sopenharmony_ci "OpStore %color %26", 507fd4e5da5Sopenharmony_ci "%27 = OpLoad %v4float %color", 508fd4e5da5Sopenharmony_ci "OpStore %gl_FragColor %27", 509fd4e5da5Sopenharmony_ci "OpReturn", 510fd4e5da5Sopenharmony_ci "OpFunctionEnd", 511fd4e5da5Sopenharmony_ci // clang-format on 512fd4e5da5Sopenharmony_ci }; 513fd4e5da5Sopenharmony_ci 514fd4e5da5Sopenharmony_ci const std::vector<const char*> after = { 515fd4e5da5Sopenharmony_ci // clang-format off 516fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %11", 517fd4e5da5Sopenharmony_ci "%23 = OpLabel", 518fd4e5da5Sopenharmony_ci "%38 = OpVariable %_ptr_Function_float Function", 519fd4e5da5Sopenharmony_ci "%39 = OpVariable %_ptr_Function_float Function", 520fd4e5da5Sopenharmony_ci "%color = OpVariable %_ptr_Function_v4float Function", 521fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 522fd4e5da5Sopenharmony_ci "%24 = OpLoad %v4float %BaseColor", 523fd4e5da5Sopenharmony_ci "OpStore %param %24", 524fd4e5da5Sopenharmony_ci "%41 = OpAccessChain %_ptr_Function_float %param %uint_0", 525fd4e5da5Sopenharmony_ci "%42 = OpLoad %float %41", 526fd4e5da5Sopenharmony_ci "OpStore %38 %42", 527fd4e5da5Sopenharmony_ci "%43 = OpLoad %float %38", 528fd4e5da5Sopenharmony_ci "%44 = OpFOrdLessThan %bool %43 %float_0", 529fd4e5da5Sopenharmony_ci "OpSelectionMerge %48 None", 530fd4e5da5Sopenharmony_ci "OpBranchConditional %44 %45 %48", 531fd4e5da5Sopenharmony_ci "%45 = OpLabel", 532fd4e5da5Sopenharmony_ci "%46 = OpLoad %float %38", 533fd4e5da5Sopenharmony_ci "%47 = OpFNegate %float %46", 534fd4e5da5Sopenharmony_ci "OpStore %38 %47", 535fd4e5da5Sopenharmony_ci "OpBranch %48", 536fd4e5da5Sopenharmony_ci "%48 = OpLabel", 537fd4e5da5Sopenharmony_ci "%49 = OpLoad %float %38", 538fd4e5da5Sopenharmony_ci "OpStore %39 %49", 539fd4e5da5Sopenharmony_ci "%25 = OpLoad %float %39", 540fd4e5da5Sopenharmony_ci "%26 = OpCompositeConstruct %v4float %25 %25 %25 %25", 541fd4e5da5Sopenharmony_ci "OpStore %color %26", 542fd4e5da5Sopenharmony_ci "%27 = OpLoad %v4float %color", 543fd4e5da5Sopenharmony_ci "OpStore %gl_FragColor %27", 544fd4e5da5Sopenharmony_ci "OpReturn", 545fd4e5da5Sopenharmony_ci "OpFunctionEnd", 546fd4e5da5Sopenharmony_ci // clang-format on 547fd4e5da5Sopenharmony_ci }; 548fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>( 549fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)), 550fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)), 551fd4e5da5Sopenharmony_ci /* skip_nop = */ false, /* do_validate = */ true); 552fd4e5da5Sopenharmony_ci} 553fd4e5da5Sopenharmony_ci 554fd4e5da5Sopenharmony_ciTEST_F(InlineTest, PhiAfterCall) { 555fd4e5da5Sopenharmony_ci // #version 140 556fd4e5da5Sopenharmony_ci // 557fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 558fd4e5da5Sopenharmony_ci // 559fd4e5da5Sopenharmony_ci // float foo(float bar) 560fd4e5da5Sopenharmony_ci // { 561fd4e5da5Sopenharmony_ci // float r = bar; 562fd4e5da5Sopenharmony_ci // if (r < 0.0) 563fd4e5da5Sopenharmony_ci // r = -r; 564fd4e5da5Sopenharmony_ci // return r; 565fd4e5da5Sopenharmony_ci // } 566fd4e5da5Sopenharmony_ci // 567fd4e5da5Sopenharmony_ci // void main() 568fd4e5da5Sopenharmony_ci // { 569fd4e5da5Sopenharmony_ci // vec4 color = BaseColor; 570fd4e5da5Sopenharmony_ci // if (foo(color.x) > 2.0 && foo(color.y) > 2.0) 571fd4e5da5Sopenharmony_ci // color = vec4(0.0); 572fd4e5da5Sopenharmony_ci // gl_FragColor = color; 573fd4e5da5Sopenharmony_ci // } 574fd4e5da5Sopenharmony_ci const std::vector<const char*> predefs = { 575fd4e5da5Sopenharmony_ci // clang-format off 576fd4e5da5Sopenharmony_ci "OpCapability Shader", 577fd4e5da5Sopenharmony_ci "%1 = OpExtInstImport \"GLSL.std.450\"", 578fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 579fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\" %BaseColor %gl_FragColor", 580fd4e5da5Sopenharmony_ci "OpExecutionMode %main OriginUpperLeft", 581fd4e5da5Sopenharmony_ci "OpSource GLSL 140", 582fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 583fd4e5da5Sopenharmony_ci "OpName %foo_f1_ \"foo(f1;\"", 584fd4e5da5Sopenharmony_ci "OpName %bar \"bar\"", 585fd4e5da5Sopenharmony_ci "OpName %r \"r\"", 586fd4e5da5Sopenharmony_ci "OpName %color \"color\"", 587fd4e5da5Sopenharmony_ci "OpName %BaseColor \"BaseColor\"", 588fd4e5da5Sopenharmony_ci "OpName %param \"param\"", 589fd4e5da5Sopenharmony_ci "OpName %param_0 \"param\"", 590fd4e5da5Sopenharmony_ci "OpName %gl_FragColor \"gl_FragColor\"", 591fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 592fd4e5da5Sopenharmony_ci "%12 = OpTypeFunction %void", 593fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 594fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float", 595fd4e5da5Sopenharmony_ci "%15 = OpTypeFunction %float %_ptr_Function_float", 596fd4e5da5Sopenharmony_ci "%float_0 = OpConstant %float 0", 597fd4e5da5Sopenharmony_ci "%bool = OpTypeBool", 598fd4e5da5Sopenharmony_ci "%v4float = OpTypeVector %float 4", 599fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float", 600fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float", 601fd4e5da5Sopenharmony_ci "%BaseColor = OpVariable %_ptr_Input_v4float Input", 602fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 603fd4e5da5Sopenharmony_ci "%uint_0 = OpConstant %uint 0", 604fd4e5da5Sopenharmony_ci "%float_2 = OpConstant %float 2", 605fd4e5da5Sopenharmony_ci "%uint_1 = OpConstant %uint 1", 606fd4e5da5Sopenharmony_ci "%25 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0", 607fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float", 608fd4e5da5Sopenharmony_ci"%gl_FragColor = OpVariable %_ptr_Output_v4float Output", 609fd4e5da5Sopenharmony_ci // clang-format on 610fd4e5da5Sopenharmony_ci }; 611fd4e5da5Sopenharmony_ci 612fd4e5da5Sopenharmony_ci const std::vector<const char*> nonEntryFuncs = { 613fd4e5da5Sopenharmony_ci // clang-format off 614fd4e5da5Sopenharmony_ci "%foo_f1_ = OpFunction %float None %15", 615fd4e5da5Sopenharmony_ci "%bar = OpFunctionParameter %_ptr_Function_float", 616fd4e5da5Sopenharmony_ci "%43 = OpLabel", 617fd4e5da5Sopenharmony_ci "%r = OpVariable %_ptr_Function_float Function", 618fd4e5da5Sopenharmony_ci "%44 = OpLoad %float %bar", 619fd4e5da5Sopenharmony_ci "OpStore %r %44", 620fd4e5da5Sopenharmony_ci "%45 = OpLoad %float %r", 621fd4e5da5Sopenharmony_ci "%46 = OpFOrdLessThan %bool %45 %float_0", 622fd4e5da5Sopenharmony_ci "OpSelectionMerge %47 None", 623fd4e5da5Sopenharmony_ci "OpBranchConditional %46 %48 %47", 624fd4e5da5Sopenharmony_ci "%48 = OpLabel", 625fd4e5da5Sopenharmony_ci "%49 = OpLoad %float %r", 626fd4e5da5Sopenharmony_ci "%50 = OpFNegate %float %49", 627fd4e5da5Sopenharmony_ci "OpStore %r %50", 628fd4e5da5Sopenharmony_ci "OpBranch %47", 629fd4e5da5Sopenharmony_ci "%47 = OpLabel", 630fd4e5da5Sopenharmony_ci "%51 = OpLoad %float %r", 631fd4e5da5Sopenharmony_ci "OpReturnValue %51", 632fd4e5da5Sopenharmony_ci "OpFunctionEnd", 633fd4e5da5Sopenharmony_ci // clang-format on 634fd4e5da5Sopenharmony_ci }; 635fd4e5da5Sopenharmony_ci 636fd4e5da5Sopenharmony_ci const std::vector<const char*> before = { 637fd4e5da5Sopenharmony_ci // clang-format off 638fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %12", 639fd4e5da5Sopenharmony_ci "%27 = OpLabel", 640fd4e5da5Sopenharmony_ci "%color = OpVariable %_ptr_Function_v4float Function", 641fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_float Function", 642fd4e5da5Sopenharmony_ci "%param_0 = OpVariable %_ptr_Function_float Function", 643fd4e5da5Sopenharmony_ci "%28 = OpLoad %v4float %BaseColor", 644fd4e5da5Sopenharmony_ci "OpStore %color %28", 645fd4e5da5Sopenharmony_ci "%29 = OpAccessChain %_ptr_Function_float %color %uint_0", 646fd4e5da5Sopenharmony_ci "%30 = OpLoad %float %29", 647fd4e5da5Sopenharmony_ci "OpStore %param %30", 648fd4e5da5Sopenharmony_ci "%31 = OpFunctionCall %float %foo_f1_ %param", 649fd4e5da5Sopenharmony_ci "%32 = OpFOrdGreaterThan %bool %31 %float_2", 650fd4e5da5Sopenharmony_ci "OpSelectionMerge %33 None", 651fd4e5da5Sopenharmony_ci "OpBranchConditional %32 %34 %33", 652fd4e5da5Sopenharmony_ci "%34 = OpLabel", 653fd4e5da5Sopenharmony_ci "%35 = OpAccessChain %_ptr_Function_float %color %uint_1", 654fd4e5da5Sopenharmony_ci "%36 = OpLoad %float %35", 655fd4e5da5Sopenharmony_ci "OpStore %param_0 %36", 656fd4e5da5Sopenharmony_ci "%37 = OpFunctionCall %float %foo_f1_ %param_0", 657fd4e5da5Sopenharmony_ci "%38 = OpFOrdGreaterThan %bool %37 %float_2", 658fd4e5da5Sopenharmony_ci "OpBranch %33", 659fd4e5da5Sopenharmony_ci "%33 = OpLabel", 660fd4e5da5Sopenharmony_ci "%39 = OpPhi %bool %32 %27 %38 %34", 661fd4e5da5Sopenharmony_ci "OpSelectionMerge %40 None", 662fd4e5da5Sopenharmony_ci "OpBranchConditional %39 %41 %40", 663fd4e5da5Sopenharmony_ci "%41 = OpLabel", 664fd4e5da5Sopenharmony_ci "OpStore %color %25", 665fd4e5da5Sopenharmony_ci "OpBranch %40", 666fd4e5da5Sopenharmony_ci "%40 = OpLabel", 667fd4e5da5Sopenharmony_ci "%42 = OpLoad %v4float %color", 668fd4e5da5Sopenharmony_ci "OpStore %gl_FragColor %42", 669fd4e5da5Sopenharmony_ci "OpReturn", 670fd4e5da5Sopenharmony_ci "OpFunctionEnd", 671fd4e5da5Sopenharmony_ci // clang-format on 672fd4e5da5Sopenharmony_ci }; 673fd4e5da5Sopenharmony_ci 674fd4e5da5Sopenharmony_ci const std::vector<const char*> after = { 675fd4e5da5Sopenharmony_ci // clang-format off 676fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %12", 677fd4e5da5Sopenharmony_ci "%27 = OpLabel", 678fd4e5da5Sopenharmony_ci "%63 = OpVariable %_ptr_Function_float Function", 679fd4e5da5Sopenharmony_ci "%64 = OpVariable %_ptr_Function_float Function", 680fd4e5da5Sopenharmony_ci "%52 = OpVariable %_ptr_Function_float Function", 681fd4e5da5Sopenharmony_ci "%53 = OpVariable %_ptr_Function_float Function", 682fd4e5da5Sopenharmony_ci "%color = OpVariable %_ptr_Function_v4float Function", 683fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_float Function", 684fd4e5da5Sopenharmony_ci "%param_0 = OpVariable %_ptr_Function_float Function", 685fd4e5da5Sopenharmony_ci "%28 = OpLoad %v4float %BaseColor", 686fd4e5da5Sopenharmony_ci "OpStore %color %28", 687fd4e5da5Sopenharmony_ci "%29 = OpAccessChain %_ptr_Function_float %color %uint_0", 688fd4e5da5Sopenharmony_ci "%30 = OpLoad %float %29", 689fd4e5da5Sopenharmony_ci "OpStore %param %30", 690fd4e5da5Sopenharmony_ci "%55 = OpLoad %float %param", 691fd4e5da5Sopenharmony_ci "OpStore %52 %55", 692fd4e5da5Sopenharmony_ci "%56 = OpLoad %float %52", 693fd4e5da5Sopenharmony_ci "%57 = OpFOrdLessThan %bool %56 %float_0", 694fd4e5da5Sopenharmony_ci "OpSelectionMerge %61 None", 695fd4e5da5Sopenharmony_ci "OpBranchConditional %57 %58 %61", 696fd4e5da5Sopenharmony_ci "%58 = OpLabel", 697fd4e5da5Sopenharmony_ci "%59 = OpLoad %float %52", 698fd4e5da5Sopenharmony_ci "%60 = OpFNegate %float %59", 699fd4e5da5Sopenharmony_ci "OpStore %52 %60", 700fd4e5da5Sopenharmony_ci "OpBranch %61", 701fd4e5da5Sopenharmony_ci "%61 = OpLabel", 702fd4e5da5Sopenharmony_ci "%62 = OpLoad %float %52", 703fd4e5da5Sopenharmony_ci "OpStore %53 %62", 704fd4e5da5Sopenharmony_ci "%31 = OpLoad %float %53", 705fd4e5da5Sopenharmony_ci "%32 = OpFOrdGreaterThan %bool %31 %float_2", 706fd4e5da5Sopenharmony_ci "OpSelectionMerge %33 None", 707fd4e5da5Sopenharmony_ci "OpBranchConditional %32 %34 %33", 708fd4e5da5Sopenharmony_ci "%34 = OpLabel", 709fd4e5da5Sopenharmony_ci "%35 = OpAccessChain %_ptr_Function_float %color %uint_1", 710fd4e5da5Sopenharmony_ci "%36 = OpLoad %float %35", 711fd4e5da5Sopenharmony_ci "OpStore %param_0 %36", 712fd4e5da5Sopenharmony_ci "%66 = OpLoad %float %param_0", 713fd4e5da5Sopenharmony_ci "OpStore %63 %66", 714fd4e5da5Sopenharmony_ci "%67 = OpLoad %float %63", 715fd4e5da5Sopenharmony_ci "%68 = OpFOrdLessThan %bool %67 %float_0", 716fd4e5da5Sopenharmony_ci "OpSelectionMerge %72 None", 717fd4e5da5Sopenharmony_ci "OpBranchConditional %68 %69 %72", 718fd4e5da5Sopenharmony_ci "%69 = OpLabel", 719fd4e5da5Sopenharmony_ci "%70 = OpLoad %float %63", 720fd4e5da5Sopenharmony_ci "%71 = OpFNegate %float %70", 721fd4e5da5Sopenharmony_ci "OpStore %63 %71", 722fd4e5da5Sopenharmony_ci "OpBranch %72", 723fd4e5da5Sopenharmony_ci "%72 = OpLabel", 724fd4e5da5Sopenharmony_ci "%73 = OpLoad %float %63", 725fd4e5da5Sopenharmony_ci "OpStore %64 %73", 726fd4e5da5Sopenharmony_ci "%37 = OpLoad %float %64", 727fd4e5da5Sopenharmony_ci "%38 = OpFOrdGreaterThan %bool %37 %float_2", 728fd4e5da5Sopenharmony_ci "OpBranch %33", 729fd4e5da5Sopenharmony_ci "%33 = OpLabel", 730fd4e5da5Sopenharmony_ci "%39 = OpPhi %bool %32 %61 %38 %72", 731fd4e5da5Sopenharmony_ci "OpSelectionMerge %40 None", 732fd4e5da5Sopenharmony_ci "OpBranchConditional %39 %41 %40", 733fd4e5da5Sopenharmony_ci "%41 = OpLabel", 734fd4e5da5Sopenharmony_ci "OpStore %color %25", 735fd4e5da5Sopenharmony_ci "OpBranch %40", 736fd4e5da5Sopenharmony_ci "%40 = OpLabel", 737fd4e5da5Sopenharmony_ci "%42 = OpLoad %v4float %color", 738fd4e5da5Sopenharmony_ci "OpStore %gl_FragColor %42", 739fd4e5da5Sopenharmony_ci "OpReturn", 740fd4e5da5Sopenharmony_ci "OpFunctionEnd", 741fd4e5da5Sopenharmony_ci // clang-format on 742fd4e5da5Sopenharmony_ci }; 743fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>( 744fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)), 745fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)), 746fd4e5da5Sopenharmony_ci /* skip_nop = */ false, /* do_validate = */ true); 747fd4e5da5Sopenharmony_ci} 748fd4e5da5Sopenharmony_ci 749fd4e5da5Sopenharmony_ciTEST_F(InlineTest, OpSampledImageOutOfBlock) { 750fd4e5da5Sopenharmony_ci // #version 450 751fd4e5da5Sopenharmony_ci // 752fd4e5da5Sopenharmony_ci // uniform texture2D t2D; 753fd4e5da5Sopenharmony_ci // uniform sampler samp; 754fd4e5da5Sopenharmony_ci // out vec4 FragColor; 755fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 756fd4e5da5Sopenharmony_ci // 757fd4e5da5Sopenharmony_ci // float foo(vec4 bar) 758fd4e5da5Sopenharmony_ci // { 759fd4e5da5Sopenharmony_ci // float r = bar.x; 760fd4e5da5Sopenharmony_ci // if (r < 0.0) 761fd4e5da5Sopenharmony_ci // r = -r; 762fd4e5da5Sopenharmony_ci // return r; 763fd4e5da5Sopenharmony_ci // } 764fd4e5da5Sopenharmony_ci // 765fd4e5da5Sopenharmony_ci // void main() 766fd4e5da5Sopenharmony_ci // { 767fd4e5da5Sopenharmony_ci // vec4 color1 = texture(sampler2D(t2D, samp), vec2(1.0)); 768fd4e5da5Sopenharmony_ci // vec4 color2 = vec4(foo(BaseColor)); 769fd4e5da5Sopenharmony_ci // vec4 color3 = texture(sampler2D(t2D, samp), vec2(0.5)); 770fd4e5da5Sopenharmony_ci // FragColor = (color1 + color2 + color3)/3; 771fd4e5da5Sopenharmony_ci // } 772fd4e5da5Sopenharmony_ci // 773fd4e5da5Sopenharmony_ci // Note: the before SPIR-V will need to be edited to create a use of 774fd4e5da5Sopenharmony_ci // the OpSampledImage across the function call. 775fd4e5da5Sopenharmony_ci const std::vector<const char*> predefs = { 776fd4e5da5Sopenharmony_ci // clang-format off 777fd4e5da5Sopenharmony_ci "OpCapability Shader", 778fd4e5da5Sopenharmony_ci "%1 = OpExtInstImport \"GLSL.std.450\"", 779fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 780fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\" %BaseColor %FragColor", 781fd4e5da5Sopenharmony_ci "OpExecutionMode %main OriginUpperLeft", 782fd4e5da5Sopenharmony_ci "OpSource GLSL 450", 783fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 784fd4e5da5Sopenharmony_ci "OpName %foo_vf4_ \"foo(vf4;\"", 785fd4e5da5Sopenharmony_ci "OpName %bar \"bar\"", 786fd4e5da5Sopenharmony_ci "OpName %r \"r\"", 787fd4e5da5Sopenharmony_ci "OpName %color1 \"color1\"", 788fd4e5da5Sopenharmony_ci "OpName %t2D \"t2D\"", 789fd4e5da5Sopenharmony_ci "OpName %samp \"samp\"", 790fd4e5da5Sopenharmony_ci "OpName %color2 \"color2\"", 791fd4e5da5Sopenharmony_ci "OpName %BaseColor \"BaseColor\"", 792fd4e5da5Sopenharmony_ci "OpName %param \"param\"", 793fd4e5da5Sopenharmony_ci "OpName %color3 \"color3\"", 794fd4e5da5Sopenharmony_ci "OpName %FragColor \"FragColor\"", 795fd4e5da5Sopenharmony_ci "OpDecorate %t2D DescriptorSet 0", 796fd4e5da5Sopenharmony_ci "OpDecorate %samp DescriptorSet 0", 797fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 798fd4e5da5Sopenharmony_ci "%15 = OpTypeFunction %void", 799fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 800fd4e5da5Sopenharmony_ci "%v4float = OpTypeVector %float 4", 801fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float", 802fd4e5da5Sopenharmony_ci "%19 = OpTypeFunction %float %_ptr_Function_v4float", 803fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float", 804fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 805fd4e5da5Sopenharmony_ci "%uint_0 = OpConstant %uint 0", 806fd4e5da5Sopenharmony_ci "%float_0 = OpConstant %float 0", 807fd4e5da5Sopenharmony_ci "%bool = OpTypeBool", 808fd4e5da5Sopenharmony_ci "%25 = OpTypeImage %float 2D 0 0 0 1 Unknown", 809fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25", 810fd4e5da5Sopenharmony_ci "%t2D = OpVariable %_ptr_UniformConstant_25 UniformConstant", 811fd4e5da5Sopenharmony_ci "%27 = OpTypeSampler", 812fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_27 = OpTypePointer UniformConstant %27", 813fd4e5da5Sopenharmony_ci "%samp = OpVariable %_ptr_UniformConstant_27 UniformConstant", 814fd4e5da5Sopenharmony_ci "%29 = OpTypeSampledImage %25", 815fd4e5da5Sopenharmony_ci "%v2float = OpTypeVector %float 2", 816fd4e5da5Sopenharmony_ci "%float_1 = OpConstant %float 1", 817fd4e5da5Sopenharmony_ci "%32 = OpConstantComposite %v2float %float_1 %float_1", 818fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float", 819fd4e5da5Sopenharmony_ci "%BaseColor = OpVariable %_ptr_Input_v4float Input", 820fd4e5da5Sopenharmony_ci "%float_0_5 = OpConstant %float 0.5", 821fd4e5da5Sopenharmony_ci "%35 = OpConstantComposite %v2float %float_0_5 %float_0_5", 822fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float", 823fd4e5da5Sopenharmony_ci "%FragColor = OpVariable %_ptr_Output_v4float Output", 824fd4e5da5Sopenharmony_ci "%float_3 = OpConstant %float 3", 825fd4e5da5Sopenharmony_ci // clang-format on 826fd4e5da5Sopenharmony_ci }; 827fd4e5da5Sopenharmony_ci 828fd4e5da5Sopenharmony_ci const std::vector<const char*> nonEntryFuncs = { 829fd4e5da5Sopenharmony_ci // clang-format off 830fd4e5da5Sopenharmony_ci "%foo_vf4_ = OpFunction %float None %19", 831fd4e5da5Sopenharmony_ci "%bar = OpFunctionParameter %_ptr_Function_v4float", 832fd4e5da5Sopenharmony_ci "%56 = OpLabel", 833fd4e5da5Sopenharmony_ci "%r = OpVariable %_ptr_Function_float Function", 834fd4e5da5Sopenharmony_ci "%57 = OpAccessChain %_ptr_Function_float %bar %uint_0", 835fd4e5da5Sopenharmony_ci "%58 = OpLoad %float %57", 836fd4e5da5Sopenharmony_ci "OpStore %r %58", 837fd4e5da5Sopenharmony_ci "%59 = OpLoad %float %r", 838fd4e5da5Sopenharmony_ci "%60 = OpFOrdLessThan %bool %59 %float_0", 839fd4e5da5Sopenharmony_ci "OpSelectionMerge %61 None", 840fd4e5da5Sopenharmony_ci "OpBranchConditional %60 %62 %61", 841fd4e5da5Sopenharmony_ci "%62 = OpLabel", 842fd4e5da5Sopenharmony_ci "%63 = OpLoad %float %r", 843fd4e5da5Sopenharmony_ci "%64 = OpFNegate %float %63", 844fd4e5da5Sopenharmony_ci "OpStore %r %64", 845fd4e5da5Sopenharmony_ci "OpBranch %61", 846fd4e5da5Sopenharmony_ci "%61 = OpLabel", 847fd4e5da5Sopenharmony_ci "%65 = OpLoad %float %r", 848fd4e5da5Sopenharmony_ci "OpReturnValue %65", 849fd4e5da5Sopenharmony_ci "OpFunctionEnd", 850fd4e5da5Sopenharmony_ci // clang-format on 851fd4e5da5Sopenharmony_ci }; 852fd4e5da5Sopenharmony_ci 853fd4e5da5Sopenharmony_ci const std::vector<const char*> before = { 854fd4e5da5Sopenharmony_ci // clang-format off 855fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %15", 856fd4e5da5Sopenharmony_ci "%38 = OpLabel", 857fd4e5da5Sopenharmony_ci "%color1 = OpVariable %_ptr_Function_v4float Function", 858fd4e5da5Sopenharmony_ci "%color2 = OpVariable %_ptr_Function_v4float Function", 859fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 860fd4e5da5Sopenharmony_ci "%color3 = OpVariable %_ptr_Function_v4float Function", 861fd4e5da5Sopenharmony_ci "%39 = OpLoad %25 %t2D", 862fd4e5da5Sopenharmony_ci "%40 = OpLoad %27 %samp", 863fd4e5da5Sopenharmony_ci "%41 = OpSampledImage %29 %39 %40", 864fd4e5da5Sopenharmony_ci "%42 = OpImageSampleImplicitLod %v4float %41 %32", 865fd4e5da5Sopenharmony_ci "OpStore %color1 %42", 866fd4e5da5Sopenharmony_ci "%43 = OpLoad %v4float %BaseColor", 867fd4e5da5Sopenharmony_ci "OpStore %param %43", 868fd4e5da5Sopenharmony_ci "%44 = OpFunctionCall %float %foo_vf4_ %param", 869fd4e5da5Sopenharmony_ci "%45 = OpCompositeConstruct %v4float %44 %44 %44 %44", 870fd4e5da5Sopenharmony_ci "OpStore %color2 %45", 871fd4e5da5Sopenharmony_ci "%46 = OpLoad %25 %t2D", 872fd4e5da5Sopenharmony_ci "%47 = OpLoad %27 %samp", 873fd4e5da5Sopenharmony_ci "%48 = OpImageSampleImplicitLod %v4float %41 %35", 874fd4e5da5Sopenharmony_ci "OpStore %color3 %48", 875fd4e5da5Sopenharmony_ci "%49 = OpLoad %v4float %color1", 876fd4e5da5Sopenharmony_ci "%50 = OpLoad %v4float %color2", 877fd4e5da5Sopenharmony_ci "%51 = OpFAdd %v4float %49 %50", 878fd4e5da5Sopenharmony_ci "%52 = OpLoad %v4float %color3", 879fd4e5da5Sopenharmony_ci "%53 = OpFAdd %v4float %51 %52", 880fd4e5da5Sopenharmony_ci "%54 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3", 881fd4e5da5Sopenharmony_ci "%55 = OpFDiv %v4float %53 %54", 882fd4e5da5Sopenharmony_ci "OpStore %FragColor %55", 883fd4e5da5Sopenharmony_ci "OpReturn", 884fd4e5da5Sopenharmony_ci "OpFunctionEnd", 885fd4e5da5Sopenharmony_ci // clang-format on 886fd4e5da5Sopenharmony_ci }; 887fd4e5da5Sopenharmony_ci 888fd4e5da5Sopenharmony_ci const std::vector<const char*> after = { 889fd4e5da5Sopenharmony_ci // clang-format off 890fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %15", 891fd4e5da5Sopenharmony_ci "%38 = OpLabel", 892fd4e5da5Sopenharmony_ci "%66 = OpVariable %_ptr_Function_float Function", 893fd4e5da5Sopenharmony_ci "%67 = OpVariable %_ptr_Function_float Function", 894fd4e5da5Sopenharmony_ci "%color1 = OpVariable %_ptr_Function_v4float Function", 895fd4e5da5Sopenharmony_ci "%color2 = OpVariable %_ptr_Function_v4float Function", 896fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 897fd4e5da5Sopenharmony_ci "%color3 = OpVariable %_ptr_Function_v4float Function", 898fd4e5da5Sopenharmony_ci "%39 = OpLoad %25 %t2D", 899fd4e5da5Sopenharmony_ci "%40 = OpLoad %27 %samp", 900fd4e5da5Sopenharmony_ci "%41 = OpSampledImage %29 %39 %40", 901fd4e5da5Sopenharmony_ci "%42 = OpImageSampleImplicitLod %v4float %41 %32", 902fd4e5da5Sopenharmony_ci "OpStore %color1 %42", 903fd4e5da5Sopenharmony_ci "%43 = OpLoad %v4float %BaseColor", 904fd4e5da5Sopenharmony_ci "OpStore %param %43", 905fd4e5da5Sopenharmony_ci "%69 = OpAccessChain %_ptr_Function_float %param %uint_0", 906fd4e5da5Sopenharmony_ci "%70 = OpLoad %float %69", 907fd4e5da5Sopenharmony_ci "OpStore %66 %70", 908fd4e5da5Sopenharmony_ci "%71 = OpLoad %float %66", 909fd4e5da5Sopenharmony_ci "%72 = OpFOrdLessThan %bool %71 %float_0", 910fd4e5da5Sopenharmony_ci "OpSelectionMerge %76 None", 911fd4e5da5Sopenharmony_ci "OpBranchConditional %72 %73 %76", 912fd4e5da5Sopenharmony_ci "%73 = OpLabel", 913fd4e5da5Sopenharmony_ci "%74 = OpLoad %float %66", 914fd4e5da5Sopenharmony_ci "%75 = OpFNegate %float %74", 915fd4e5da5Sopenharmony_ci "OpStore %66 %75", 916fd4e5da5Sopenharmony_ci "OpBranch %76", 917fd4e5da5Sopenharmony_ci "%76 = OpLabel", 918fd4e5da5Sopenharmony_ci "%77 = OpLoad %float %66", 919fd4e5da5Sopenharmony_ci "OpStore %67 %77", 920fd4e5da5Sopenharmony_ci "%44 = OpLoad %float %67", 921fd4e5da5Sopenharmony_ci "%45 = OpCompositeConstruct %v4float %44 %44 %44 %44", 922fd4e5da5Sopenharmony_ci "OpStore %color2 %45", 923fd4e5da5Sopenharmony_ci "%46 = OpLoad %25 %t2D", 924fd4e5da5Sopenharmony_ci "%47 = OpLoad %27 %samp", 925fd4e5da5Sopenharmony_ci "%78 = OpSampledImage %29 %39 %40", 926fd4e5da5Sopenharmony_ci "%48 = OpImageSampleImplicitLod %v4float %78 %35", 927fd4e5da5Sopenharmony_ci "OpStore %color3 %48", 928fd4e5da5Sopenharmony_ci "%49 = OpLoad %v4float %color1", 929fd4e5da5Sopenharmony_ci "%50 = OpLoad %v4float %color2", 930fd4e5da5Sopenharmony_ci "%51 = OpFAdd %v4float %49 %50", 931fd4e5da5Sopenharmony_ci "%52 = OpLoad %v4float %color3", 932fd4e5da5Sopenharmony_ci "%53 = OpFAdd %v4float %51 %52", 933fd4e5da5Sopenharmony_ci "%54 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3", 934fd4e5da5Sopenharmony_ci "%55 = OpFDiv %v4float %53 %54", 935fd4e5da5Sopenharmony_ci "OpStore %FragColor %55", 936fd4e5da5Sopenharmony_ci "OpReturn", 937fd4e5da5Sopenharmony_ci "OpFunctionEnd", 938fd4e5da5Sopenharmony_ci // clang-format on 939fd4e5da5Sopenharmony_ci }; 940fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>( 941fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)), 942fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)), 943fd4e5da5Sopenharmony_ci /* skip_nop = */ false, /* do_validate = */ true); 944fd4e5da5Sopenharmony_ci} 945fd4e5da5Sopenharmony_ci 946fd4e5da5Sopenharmony_ciTEST_F(InlineTest, OpImageOutOfBlock) { 947fd4e5da5Sopenharmony_ci // #version 450 948fd4e5da5Sopenharmony_ci // 949fd4e5da5Sopenharmony_ci // uniform texture2D t2D; 950fd4e5da5Sopenharmony_ci // uniform sampler samp; 951fd4e5da5Sopenharmony_ci // uniform sampler samp2; 952fd4e5da5Sopenharmony_ci // 953fd4e5da5Sopenharmony_ci // out vec4 FragColor; 954fd4e5da5Sopenharmony_ci // 955fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 956fd4e5da5Sopenharmony_ci // 957fd4e5da5Sopenharmony_ci // float foo(vec4 bar) 958fd4e5da5Sopenharmony_ci // { 959fd4e5da5Sopenharmony_ci // float r = bar.x; 960fd4e5da5Sopenharmony_ci // if (r < 0.0) 961fd4e5da5Sopenharmony_ci // r = -r; 962fd4e5da5Sopenharmony_ci // return r; 963fd4e5da5Sopenharmony_ci // } 964fd4e5da5Sopenharmony_ci // 965fd4e5da5Sopenharmony_ci // void main() 966fd4e5da5Sopenharmony_ci // { 967fd4e5da5Sopenharmony_ci // vec4 color1 = texture(sampler2D(t2D, samp), vec2(1.0)); 968fd4e5da5Sopenharmony_ci // vec4 color2 = vec4(foo(BaseColor)); 969fd4e5da5Sopenharmony_ci // vec4 color3 = texture(sampler2D(t2D, samp2), vec2(0.5)); 970fd4e5da5Sopenharmony_ci // FragColor = (color1 + color2 + color3)/3; 971fd4e5da5Sopenharmony_ci // } 972fd4e5da5Sopenharmony_ci // Note: the before SPIR-V will need to be edited to create an OpImage 973fd4e5da5Sopenharmony_ci // from the first OpSampledImage, place it before the call and use it 974fd4e5da5Sopenharmony_ci // in the second OpSampledImage following the call. 975fd4e5da5Sopenharmony_ci const std::vector<const char*> predefs = { 976fd4e5da5Sopenharmony_ci // clang-format off 977fd4e5da5Sopenharmony_ci "OpCapability Shader", 978fd4e5da5Sopenharmony_ci "%1 = OpExtInstImport \"GLSL.std.450\"", 979fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 980fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\" %BaseColor %FragColor", 981fd4e5da5Sopenharmony_ci "OpExecutionMode %main OriginUpperLeft", 982fd4e5da5Sopenharmony_ci "OpSource GLSL 450", 983fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 984fd4e5da5Sopenharmony_ci "OpName %foo_vf4_ \"foo(vf4;\"", 985fd4e5da5Sopenharmony_ci "OpName %bar \"bar\"", 986fd4e5da5Sopenharmony_ci "OpName %r \"r\"", 987fd4e5da5Sopenharmony_ci "OpName %color1 \"color1\"", 988fd4e5da5Sopenharmony_ci "OpName %t2D \"t2D\"", 989fd4e5da5Sopenharmony_ci "OpName %samp \"samp\"", 990fd4e5da5Sopenharmony_ci "OpName %color2 \"color2\"", 991fd4e5da5Sopenharmony_ci "OpName %BaseColor \"BaseColor\"", 992fd4e5da5Sopenharmony_ci "OpName %param \"param\"", 993fd4e5da5Sopenharmony_ci "OpName %color3 \"color3\"", 994fd4e5da5Sopenharmony_ci "OpName %samp2 \"samp2\"", 995fd4e5da5Sopenharmony_ci "OpName %FragColor \"FragColor\"", 996fd4e5da5Sopenharmony_ci "OpDecorate %t2D DescriptorSet 0", 997fd4e5da5Sopenharmony_ci "OpDecorate %samp DescriptorSet 0", 998fd4e5da5Sopenharmony_ci "OpDecorate %samp2 DescriptorSet 0", 999fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 1000fd4e5da5Sopenharmony_ci "%16 = OpTypeFunction %void", 1001fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 1002fd4e5da5Sopenharmony_ci "%v4float = OpTypeVector %float 4", 1003fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float", 1004fd4e5da5Sopenharmony_ci "%20 = OpTypeFunction %float %_ptr_Function_v4float", 1005fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float", 1006fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 1007fd4e5da5Sopenharmony_ci "%uint_0 = OpConstant %uint 0", 1008fd4e5da5Sopenharmony_ci "%float_0 = OpConstant %float 0", 1009fd4e5da5Sopenharmony_ci "%bool = OpTypeBool", 1010fd4e5da5Sopenharmony_ci "%26 = OpTypeImage %float 2D 0 0 0 1 Unknown", 1011fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_26 = OpTypePointer UniformConstant %26", 1012fd4e5da5Sopenharmony_ci "%t2D = OpVariable %_ptr_UniformConstant_26 UniformConstant", 1013fd4e5da5Sopenharmony_ci "%28 = OpTypeSampler", 1014fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_28 = OpTypePointer UniformConstant %28", 1015fd4e5da5Sopenharmony_ci "%samp = OpVariable %_ptr_UniformConstant_28 UniformConstant", 1016fd4e5da5Sopenharmony_ci "%30 = OpTypeSampledImage %26", 1017fd4e5da5Sopenharmony_ci "%v2float = OpTypeVector %float 2", 1018fd4e5da5Sopenharmony_ci "%float_1 = OpConstant %float 1", 1019fd4e5da5Sopenharmony_ci "%33 = OpConstantComposite %v2float %float_1 %float_1", 1020fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float", 1021fd4e5da5Sopenharmony_ci "%BaseColor = OpVariable %_ptr_Input_v4float Input", 1022fd4e5da5Sopenharmony_ci "%samp2 = OpVariable %_ptr_UniformConstant_28 UniformConstant", 1023fd4e5da5Sopenharmony_ci "%float_0_5 = OpConstant %float 0.5", 1024fd4e5da5Sopenharmony_ci "%36 = OpConstantComposite %v2float %float_0_5 %float_0_5", 1025fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float", 1026fd4e5da5Sopenharmony_ci "%FragColor = OpVariable %_ptr_Output_v4float Output", 1027fd4e5da5Sopenharmony_ci "%float_3 = OpConstant %float 3", 1028fd4e5da5Sopenharmony_ci // clang-format on 1029fd4e5da5Sopenharmony_ci }; 1030fd4e5da5Sopenharmony_ci 1031fd4e5da5Sopenharmony_ci const std::vector<const char*> nonEntryFuncs = { 1032fd4e5da5Sopenharmony_ci // clang-format off 1033fd4e5da5Sopenharmony_ci "%foo_vf4_ = OpFunction %float None %20", 1034fd4e5da5Sopenharmony_ci "%bar = OpFunctionParameter %_ptr_Function_v4float", 1035fd4e5da5Sopenharmony_ci "%58 = OpLabel", 1036fd4e5da5Sopenharmony_ci "%r = OpVariable %_ptr_Function_float Function", 1037fd4e5da5Sopenharmony_ci "%59 = OpAccessChain %_ptr_Function_float %bar %uint_0", 1038fd4e5da5Sopenharmony_ci "%60 = OpLoad %float %59", 1039fd4e5da5Sopenharmony_ci "OpStore %r %60", 1040fd4e5da5Sopenharmony_ci "%61 = OpLoad %float %r", 1041fd4e5da5Sopenharmony_ci "%62 = OpFOrdLessThan %bool %61 %float_0", 1042fd4e5da5Sopenharmony_ci "OpSelectionMerge %63 None", 1043fd4e5da5Sopenharmony_ci "OpBranchConditional %62 %64 %63", 1044fd4e5da5Sopenharmony_ci "%64 = OpLabel", 1045fd4e5da5Sopenharmony_ci "%65 = OpLoad %float %r", 1046fd4e5da5Sopenharmony_ci "%66 = OpFNegate %float %65", 1047fd4e5da5Sopenharmony_ci "OpStore %r %66", 1048fd4e5da5Sopenharmony_ci "OpBranch %63", 1049fd4e5da5Sopenharmony_ci "%63 = OpLabel", 1050fd4e5da5Sopenharmony_ci "%67 = OpLoad %float %r", 1051fd4e5da5Sopenharmony_ci "OpReturnValue %67", 1052fd4e5da5Sopenharmony_ci "OpFunctionEnd", 1053fd4e5da5Sopenharmony_ci // clang-format on 1054fd4e5da5Sopenharmony_ci }; 1055fd4e5da5Sopenharmony_ci 1056fd4e5da5Sopenharmony_ci const std::vector<const char*> before = { 1057fd4e5da5Sopenharmony_ci // clang-format off 1058fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %16", 1059fd4e5da5Sopenharmony_ci "%39 = OpLabel", 1060fd4e5da5Sopenharmony_ci "%color1 = OpVariable %_ptr_Function_v4float Function", 1061fd4e5da5Sopenharmony_ci "%color2 = OpVariable %_ptr_Function_v4float Function", 1062fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 1063fd4e5da5Sopenharmony_ci "%color3 = OpVariable %_ptr_Function_v4float Function", 1064fd4e5da5Sopenharmony_ci "%40 = OpLoad %26 %t2D", 1065fd4e5da5Sopenharmony_ci "%41 = OpLoad %28 %samp", 1066fd4e5da5Sopenharmony_ci "%42 = OpSampledImage %30 %40 %41", 1067fd4e5da5Sopenharmony_ci "%43 = OpImageSampleImplicitLod %v4float %42 %33", 1068fd4e5da5Sopenharmony_ci "%44 = OpImage %26 %42", 1069fd4e5da5Sopenharmony_ci "%45 = OpLoad %28 %samp2", 1070fd4e5da5Sopenharmony_ci "OpStore %color1 %43", 1071fd4e5da5Sopenharmony_ci "%46 = OpLoad %v4float %BaseColor", 1072fd4e5da5Sopenharmony_ci "OpStore %param %46", 1073fd4e5da5Sopenharmony_ci "%47 = OpFunctionCall %float %foo_vf4_ %param", 1074fd4e5da5Sopenharmony_ci "%48 = OpCompositeConstruct %v4float %47 %47 %47 %47", 1075fd4e5da5Sopenharmony_ci "OpStore %color2 %48", 1076fd4e5da5Sopenharmony_ci "%49 = OpSampledImage %30 %44 %45", 1077fd4e5da5Sopenharmony_ci "%50 = OpImageSampleImplicitLod %v4float %49 %36", 1078fd4e5da5Sopenharmony_ci "OpStore %color3 %50", 1079fd4e5da5Sopenharmony_ci "%51 = OpLoad %v4float %color1", 1080fd4e5da5Sopenharmony_ci "%52 = OpLoad %v4float %color2", 1081fd4e5da5Sopenharmony_ci "%53 = OpFAdd %v4float %51 %52", 1082fd4e5da5Sopenharmony_ci "%54 = OpLoad %v4float %color3", 1083fd4e5da5Sopenharmony_ci "%55 = OpFAdd %v4float %53 %54", 1084fd4e5da5Sopenharmony_ci "%56 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3", 1085fd4e5da5Sopenharmony_ci "%57 = OpFDiv %v4float %55 %56", 1086fd4e5da5Sopenharmony_ci "OpStore %FragColor %57", 1087fd4e5da5Sopenharmony_ci "OpReturn", 1088fd4e5da5Sopenharmony_ci "OpFunctionEnd", 1089fd4e5da5Sopenharmony_ci // clang-format on 1090fd4e5da5Sopenharmony_ci }; 1091fd4e5da5Sopenharmony_ci 1092fd4e5da5Sopenharmony_ci const std::vector<const char*> after = { 1093fd4e5da5Sopenharmony_ci // clang-format off 1094fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %16", 1095fd4e5da5Sopenharmony_ci "%39 = OpLabel", 1096fd4e5da5Sopenharmony_ci "%68 = OpVariable %_ptr_Function_float Function", 1097fd4e5da5Sopenharmony_ci "%69 = OpVariable %_ptr_Function_float Function", 1098fd4e5da5Sopenharmony_ci "%color1 = OpVariable %_ptr_Function_v4float Function", 1099fd4e5da5Sopenharmony_ci "%color2 = OpVariable %_ptr_Function_v4float Function", 1100fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 1101fd4e5da5Sopenharmony_ci "%color3 = OpVariable %_ptr_Function_v4float Function", 1102fd4e5da5Sopenharmony_ci "%40 = OpLoad %26 %t2D", 1103fd4e5da5Sopenharmony_ci "%41 = OpLoad %28 %samp", 1104fd4e5da5Sopenharmony_ci "%42 = OpSampledImage %30 %40 %41", 1105fd4e5da5Sopenharmony_ci "%43 = OpImageSampleImplicitLod %v4float %42 %33", 1106fd4e5da5Sopenharmony_ci "%44 = OpImage %26 %42", 1107fd4e5da5Sopenharmony_ci "%45 = OpLoad %28 %samp2", 1108fd4e5da5Sopenharmony_ci "OpStore %color1 %43", 1109fd4e5da5Sopenharmony_ci "%46 = OpLoad %v4float %BaseColor", 1110fd4e5da5Sopenharmony_ci "OpStore %param %46", 1111fd4e5da5Sopenharmony_ci "%71 = OpAccessChain %_ptr_Function_float %param %uint_0", 1112fd4e5da5Sopenharmony_ci "%72 = OpLoad %float %71", 1113fd4e5da5Sopenharmony_ci "OpStore %68 %72", 1114fd4e5da5Sopenharmony_ci "%73 = OpLoad %float %68", 1115fd4e5da5Sopenharmony_ci "%74 = OpFOrdLessThan %bool %73 %float_0", 1116fd4e5da5Sopenharmony_ci "OpSelectionMerge %78 None", 1117fd4e5da5Sopenharmony_ci "OpBranchConditional %74 %75 %78", 1118fd4e5da5Sopenharmony_ci "%75 = OpLabel", 1119fd4e5da5Sopenharmony_ci "%76 = OpLoad %float %68", 1120fd4e5da5Sopenharmony_ci "%77 = OpFNegate %float %76", 1121fd4e5da5Sopenharmony_ci "OpStore %68 %77", 1122fd4e5da5Sopenharmony_ci "OpBranch %78", 1123fd4e5da5Sopenharmony_ci "%78 = OpLabel", 1124fd4e5da5Sopenharmony_ci "%79 = OpLoad %float %68", 1125fd4e5da5Sopenharmony_ci "OpStore %69 %79", 1126fd4e5da5Sopenharmony_ci "%47 = OpLoad %float %69", 1127fd4e5da5Sopenharmony_ci "%48 = OpCompositeConstruct %v4float %47 %47 %47 %47", 1128fd4e5da5Sopenharmony_ci "OpStore %color2 %48", 1129fd4e5da5Sopenharmony_ci "%80 = OpSampledImage %30 %40 %41", 1130fd4e5da5Sopenharmony_ci "%81 = OpImage %26 %80", 1131fd4e5da5Sopenharmony_ci "%49 = OpSampledImage %30 %81 %45", 1132fd4e5da5Sopenharmony_ci "%50 = OpImageSampleImplicitLod %v4float %49 %36", 1133fd4e5da5Sopenharmony_ci "OpStore %color3 %50", 1134fd4e5da5Sopenharmony_ci "%51 = OpLoad %v4float %color1", 1135fd4e5da5Sopenharmony_ci "%52 = OpLoad %v4float %color2", 1136fd4e5da5Sopenharmony_ci "%53 = OpFAdd %v4float %51 %52", 1137fd4e5da5Sopenharmony_ci "%54 = OpLoad %v4float %color3", 1138fd4e5da5Sopenharmony_ci "%55 = OpFAdd %v4float %53 %54", 1139fd4e5da5Sopenharmony_ci "%56 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3", 1140fd4e5da5Sopenharmony_ci "%57 = OpFDiv %v4float %55 %56", 1141fd4e5da5Sopenharmony_ci "OpStore %FragColor %57", 1142fd4e5da5Sopenharmony_ci "OpReturn", 1143fd4e5da5Sopenharmony_ci "OpFunctionEnd", 1144fd4e5da5Sopenharmony_ci // clang-format on 1145fd4e5da5Sopenharmony_ci }; 1146fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>( 1147fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)), 1148fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)), 1149fd4e5da5Sopenharmony_ci /* skip_nop = */ false, /* do_validate = */ true); 1150fd4e5da5Sopenharmony_ci} 1151fd4e5da5Sopenharmony_ci 1152fd4e5da5Sopenharmony_ciTEST_F(InlineTest, OpImageAndOpSampledImageOutOfBlock) { 1153fd4e5da5Sopenharmony_ci // #version 450 1154fd4e5da5Sopenharmony_ci // 1155fd4e5da5Sopenharmony_ci // uniform texture2D t2D; 1156fd4e5da5Sopenharmony_ci // uniform sampler samp; 1157fd4e5da5Sopenharmony_ci // uniform sampler samp2; 1158fd4e5da5Sopenharmony_ci // 1159fd4e5da5Sopenharmony_ci // out vec4 FragColor; 1160fd4e5da5Sopenharmony_ci // 1161fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 1162fd4e5da5Sopenharmony_ci // 1163fd4e5da5Sopenharmony_ci // float foo(vec4 bar) 1164fd4e5da5Sopenharmony_ci // { 1165fd4e5da5Sopenharmony_ci // float r = bar.x; 1166fd4e5da5Sopenharmony_ci // if (r < 0.0) 1167fd4e5da5Sopenharmony_ci // r = -r; 1168fd4e5da5Sopenharmony_ci // return r; 1169fd4e5da5Sopenharmony_ci // } 1170fd4e5da5Sopenharmony_ci // 1171fd4e5da5Sopenharmony_ci // void main() 1172fd4e5da5Sopenharmony_ci // { 1173fd4e5da5Sopenharmony_ci // vec4 color1 = texture(sampler2D(t2D, samp), vec2(1.0)); 1174fd4e5da5Sopenharmony_ci // vec4 color2 = vec4(foo(BaseColor)); 1175fd4e5da5Sopenharmony_ci // vec4 color3 = texture(sampler2D(t2D, samp2), vec2(0.5)); 1176fd4e5da5Sopenharmony_ci // FragColor = (color1 + color2 + color3)/3; 1177fd4e5da5Sopenharmony_ci // } 1178fd4e5da5Sopenharmony_ci // Note: the before SPIR-V will need to be edited to create an OpImage 1179fd4e5da5Sopenharmony_ci // and subsequent OpSampledImage that is used across the function call. 1180fd4e5da5Sopenharmony_ci const std::vector<const char*> predefs = { 1181fd4e5da5Sopenharmony_ci // clang-format off 1182fd4e5da5Sopenharmony_ci "OpCapability Shader", 1183fd4e5da5Sopenharmony_ci "%1 = OpExtInstImport \"GLSL.std.450\"", 1184fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 1185fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\" %BaseColor %FragColor", 1186fd4e5da5Sopenharmony_ci "OpExecutionMode %main OriginUpperLeft", 1187fd4e5da5Sopenharmony_ci "OpSource GLSL 450", 1188fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 1189fd4e5da5Sopenharmony_ci "OpName %foo_vf4_ \"foo(vf4;\"", 1190fd4e5da5Sopenharmony_ci "OpName %bar \"bar\"", 1191fd4e5da5Sopenharmony_ci "OpName %r \"r\"", 1192fd4e5da5Sopenharmony_ci "OpName %color1 \"color1\"", 1193fd4e5da5Sopenharmony_ci "OpName %t2D \"t2D\"", 1194fd4e5da5Sopenharmony_ci "OpName %samp \"samp\"", 1195fd4e5da5Sopenharmony_ci "OpName %color2 \"color2\"", 1196fd4e5da5Sopenharmony_ci "OpName %BaseColor \"BaseColor\"", 1197fd4e5da5Sopenharmony_ci "OpName %param \"param\"", 1198fd4e5da5Sopenharmony_ci "OpName %color3 \"color3\"", 1199fd4e5da5Sopenharmony_ci "OpName %samp2 \"samp2\"", 1200fd4e5da5Sopenharmony_ci "OpName %FragColor \"FragColor\"", 1201fd4e5da5Sopenharmony_ci "OpDecorate %t2D DescriptorSet 0", 1202fd4e5da5Sopenharmony_ci "OpDecorate %samp DescriptorSet 0", 1203fd4e5da5Sopenharmony_ci "OpDecorate %samp2 DescriptorSet 0", 1204fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 1205fd4e5da5Sopenharmony_ci "%16 = OpTypeFunction %void", 1206fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 1207fd4e5da5Sopenharmony_ci "%v4float = OpTypeVector %float 4", 1208fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float", 1209fd4e5da5Sopenharmony_ci "%20 = OpTypeFunction %float %_ptr_Function_v4float", 1210fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float", 1211fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 1212fd4e5da5Sopenharmony_ci "%uint_0 = OpConstant %uint 0", 1213fd4e5da5Sopenharmony_ci "%float_0 = OpConstant %float 0", 1214fd4e5da5Sopenharmony_ci "%bool = OpTypeBool", 1215fd4e5da5Sopenharmony_ci "%26 = OpTypeImage %float 2D 0 0 0 1 Unknown", 1216fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_26 = OpTypePointer UniformConstant %26", 1217fd4e5da5Sopenharmony_ci "%t2D = OpVariable %_ptr_UniformConstant_26 UniformConstant", 1218fd4e5da5Sopenharmony_ci "%28 = OpTypeSampler", 1219fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_28 = OpTypePointer UniformConstant %28", 1220fd4e5da5Sopenharmony_ci "%samp = OpVariable %_ptr_UniformConstant_28 UniformConstant", 1221fd4e5da5Sopenharmony_ci "%30 = OpTypeSampledImage %26", 1222fd4e5da5Sopenharmony_ci "%v2float = OpTypeVector %float 2", 1223fd4e5da5Sopenharmony_ci "%float_1 = OpConstant %float 1", 1224fd4e5da5Sopenharmony_ci "%33 = OpConstantComposite %v2float %float_1 %float_1", 1225fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float", 1226fd4e5da5Sopenharmony_ci "%BaseColor = OpVariable %_ptr_Input_v4float Input", 1227fd4e5da5Sopenharmony_ci "%samp2 = OpVariable %_ptr_UniformConstant_28 UniformConstant", 1228fd4e5da5Sopenharmony_ci "%float_0_5 = OpConstant %float 0.5", 1229fd4e5da5Sopenharmony_ci "%36 = OpConstantComposite %v2float %float_0_5 %float_0_5", 1230fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float", 1231fd4e5da5Sopenharmony_ci "%FragColor = OpVariable %_ptr_Output_v4float Output", 1232fd4e5da5Sopenharmony_ci "%float_3 = OpConstant %float 3", 1233fd4e5da5Sopenharmony_ci // clang-format on 1234fd4e5da5Sopenharmony_ci }; 1235fd4e5da5Sopenharmony_ci 1236fd4e5da5Sopenharmony_ci const std::vector<const char*> nonEntryFuncs = { 1237fd4e5da5Sopenharmony_ci // clang-format off 1238fd4e5da5Sopenharmony_ci "%foo_vf4_ = OpFunction %float None %20", 1239fd4e5da5Sopenharmony_ci "%bar = OpFunctionParameter %_ptr_Function_v4float", 1240fd4e5da5Sopenharmony_ci "%58 = OpLabel", 1241fd4e5da5Sopenharmony_ci "%r = OpVariable %_ptr_Function_float Function", 1242fd4e5da5Sopenharmony_ci "%59 = OpAccessChain %_ptr_Function_float %bar %uint_0", 1243fd4e5da5Sopenharmony_ci "%60 = OpLoad %float %59", 1244fd4e5da5Sopenharmony_ci "OpStore %r %60", 1245fd4e5da5Sopenharmony_ci "%61 = OpLoad %float %r", 1246fd4e5da5Sopenharmony_ci "%62 = OpFOrdLessThan %bool %61 %float_0", 1247fd4e5da5Sopenharmony_ci "OpSelectionMerge %63 None", 1248fd4e5da5Sopenharmony_ci "OpBranchConditional %62 %64 %63", 1249fd4e5da5Sopenharmony_ci "%64 = OpLabel", 1250fd4e5da5Sopenharmony_ci "%65 = OpLoad %float %r", 1251fd4e5da5Sopenharmony_ci "%66 = OpFNegate %float %65", 1252fd4e5da5Sopenharmony_ci "OpStore %r %66", 1253fd4e5da5Sopenharmony_ci "OpBranch %63", 1254fd4e5da5Sopenharmony_ci "%63 = OpLabel", 1255fd4e5da5Sopenharmony_ci "%67 = OpLoad %float %r", 1256fd4e5da5Sopenharmony_ci "OpReturnValue %67", 1257fd4e5da5Sopenharmony_ci "OpFunctionEnd", 1258fd4e5da5Sopenharmony_ci // clang-format on 1259fd4e5da5Sopenharmony_ci }; 1260fd4e5da5Sopenharmony_ci 1261fd4e5da5Sopenharmony_ci const std::vector<const char*> before = { 1262fd4e5da5Sopenharmony_ci // clang-format off 1263fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %16", 1264fd4e5da5Sopenharmony_ci "%39 = OpLabel", 1265fd4e5da5Sopenharmony_ci "%color1 = OpVariable %_ptr_Function_v4float Function", 1266fd4e5da5Sopenharmony_ci "%color2 = OpVariable %_ptr_Function_v4float Function", 1267fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 1268fd4e5da5Sopenharmony_ci "%color3 = OpVariable %_ptr_Function_v4float Function", 1269fd4e5da5Sopenharmony_ci "%40 = OpLoad %26 %t2D", 1270fd4e5da5Sopenharmony_ci "%41 = OpLoad %28 %samp", 1271fd4e5da5Sopenharmony_ci "%42 = OpSampledImage %30 %40 %41", 1272fd4e5da5Sopenharmony_ci "%43 = OpImageSampleImplicitLod %v4float %42 %33", 1273fd4e5da5Sopenharmony_ci "%44 = OpImage %26 %42", 1274fd4e5da5Sopenharmony_ci "%45 = OpLoad %28 %samp2", 1275fd4e5da5Sopenharmony_ci "%46 = OpSampledImage %30 %44 %45", 1276fd4e5da5Sopenharmony_ci "OpStore %color1 %43", 1277fd4e5da5Sopenharmony_ci "%47 = OpLoad %v4float %BaseColor", 1278fd4e5da5Sopenharmony_ci "OpStore %param %47", 1279fd4e5da5Sopenharmony_ci "%48 = OpFunctionCall %float %foo_vf4_ %param", 1280fd4e5da5Sopenharmony_ci "%49 = OpCompositeConstruct %v4float %48 %48 %48 %48", 1281fd4e5da5Sopenharmony_ci "OpStore %color2 %49", 1282fd4e5da5Sopenharmony_ci "%50 = OpImageSampleImplicitLod %v4float %46 %36", 1283fd4e5da5Sopenharmony_ci "OpStore %color3 %50", 1284fd4e5da5Sopenharmony_ci "%51 = OpLoad %v4float %color1", 1285fd4e5da5Sopenharmony_ci "%52 = OpLoad %v4float %color2", 1286fd4e5da5Sopenharmony_ci "%53 = OpFAdd %v4float %51 %52", 1287fd4e5da5Sopenharmony_ci "%54 = OpLoad %v4float %color3", 1288fd4e5da5Sopenharmony_ci "%55 = OpFAdd %v4float %53 %54", 1289fd4e5da5Sopenharmony_ci "%56 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3", 1290fd4e5da5Sopenharmony_ci "%57 = OpFDiv %v4float %55 %56", 1291fd4e5da5Sopenharmony_ci "OpStore %FragColor %57", 1292fd4e5da5Sopenharmony_ci "OpReturn", 1293fd4e5da5Sopenharmony_ci "OpFunctionEnd", 1294fd4e5da5Sopenharmony_ci // clang-format on 1295fd4e5da5Sopenharmony_ci }; 1296fd4e5da5Sopenharmony_ci 1297fd4e5da5Sopenharmony_ci const std::vector<const char*> after = { 1298fd4e5da5Sopenharmony_ci // clang-format off 1299fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %16", 1300fd4e5da5Sopenharmony_ci "%39 = OpLabel", 1301fd4e5da5Sopenharmony_ci "%68 = OpVariable %_ptr_Function_float Function", 1302fd4e5da5Sopenharmony_ci "%69 = OpVariable %_ptr_Function_float Function", 1303fd4e5da5Sopenharmony_ci "%color1 = OpVariable %_ptr_Function_v4float Function", 1304fd4e5da5Sopenharmony_ci "%color2 = OpVariable %_ptr_Function_v4float Function", 1305fd4e5da5Sopenharmony_ci "%param = OpVariable %_ptr_Function_v4float Function", 1306fd4e5da5Sopenharmony_ci "%color3 = OpVariable %_ptr_Function_v4float Function", 1307fd4e5da5Sopenharmony_ci "%40 = OpLoad %26 %t2D", 1308fd4e5da5Sopenharmony_ci "%41 = OpLoad %28 %samp", 1309fd4e5da5Sopenharmony_ci "%42 = OpSampledImage %30 %40 %41", 1310fd4e5da5Sopenharmony_ci "%43 = OpImageSampleImplicitLod %v4float %42 %33", 1311fd4e5da5Sopenharmony_ci "%44 = OpImage %26 %42", 1312fd4e5da5Sopenharmony_ci "%45 = OpLoad %28 %samp2", 1313fd4e5da5Sopenharmony_ci "%46 = OpSampledImage %30 %44 %45", 1314fd4e5da5Sopenharmony_ci "OpStore %color1 %43", 1315fd4e5da5Sopenharmony_ci "%47 = OpLoad %v4float %BaseColor", 1316fd4e5da5Sopenharmony_ci "OpStore %param %47", 1317fd4e5da5Sopenharmony_ci "%71 = OpAccessChain %_ptr_Function_float %param %uint_0", 1318fd4e5da5Sopenharmony_ci "%72 = OpLoad %float %71", 1319fd4e5da5Sopenharmony_ci "OpStore %68 %72", 1320fd4e5da5Sopenharmony_ci "%73 = OpLoad %float %68", 1321fd4e5da5Sopenharmony_ci "%74 = OpFOrdLessThan %bool %73 %float_0", 1322fd4e5da5Sopenharmony_ci "OpSelectionMerge %78 None", 1323fd4e5da5Sopenharmony_ci "OpBranchConditional %74 %75 %78", 1324fd4e5da5Sopenharmony_ci "%75 = OpLabel", 1325fd4e5da5Sopenharmony_ci "%76 = OpLoad %float %68", 1326fd4e5da5Sopenharmony_ci "%77 = OpFNegate %float %76", 1327fd4e5da5Sopenharmony_ci "OpStore %68 %77", 1328fd4e5da5Sopenharmony_ci "OpBranch %78", 1329fd4e5da5Sopenharmony_ci "%78 = OpLabel", 1330fd4e5da5Sopenharmony_ci "%79 = OpLoad %float %68", 1331fd4e5da5Sopenharmony_ci "OpStore %69 %79", 1332fd4e5da5Sopenharmony_ci "%48 = OpLoad %float %69", 1333fd4e5da5Sopenharmony_ci "%49 = OpCompositeConstruct %v4float %48 %48 %48 %48", 1334fd4e5da5Sopenharmony_ci "OpStore %color2 %49", 1335fd4e5da5Sopenharmony_ci "%80 = OpSampledImage %30 %40 %41", 1336fd4e5da5Sopenharmony_ci "%81 = OpImage %26 %80", 1337fd4e5da5Sopenharmony_ci "%82 = OpSampledImage %30 %81 %45", 1338fd4e5da5Sopenharmony_ci "%50 = OpImageSampleImplicitLod %v4float %82 %36", 1339fd4e5da5Sopenharmony_ci "OpStore %color3 %50", 1340fd4e5da5Sopenharmony_ci "%51 = OpLoad %v4float %color1", 1341fd4e5da5Sopenharmony_ci "%52 = OpLoad %v4float %color2", 1342fd4e5da5Sopenharmony_ci "%53 = OpFAdd %v4float %51 %52", 1343fd4e5da5Sopenharmony_ci "%54 = OpLoad %v4float %color3", 1344fd4e5da5Sopenharmony_ci "%55 = OpFAdd %v4float %53 %54", 1345fd4e5da5Sopenharmony_ci "%56 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3", 1346fd4e5da5Sopenharmony_ci "%57 = OpFDiv %v4float %55 %56", 1347fd4e5da5Sopenharmony_ci "OpStore %FragColor %57", 1348fd4e5da5Sopenharmony_ci "OpReturn", 1349fd4e5da5Sopenharmony_ci "OpFunctionEnd", 1350fd4e5da5Sopenharmony_ci // clang-format on 1351fd4e5da5Sopenharmony_ci }; 1352fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>( 1353fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)), 1354fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)), 1355fd4e5da5Sopenharmony_ci /* skip_nop = */ false, /* do_validate = */ true); 1356fd4e5da5Sopenharmony_ci} 1357fd4e5da5Sopenharmony_ci 1358fd4e5da5Sopenharmony_ciTEST_F(InlineTest, EarlyReturnInLoopIsNotInlined) { 1359fd4e5da5Sopenharmony_ci // #version 140 1360fd4e5da5Sopenharmony_ci // 1361fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 1362fd4e5da5Sopenharmony_ci // 1363fd4e5da5Sopenharmony_ci // float foo(vec4 bar) 1364fd4e5da5Sopenharmony_ci // { 1365fd4e5da5Sopenharmony_ci // while (true) { 1366fd4e5da5Sopenharmony_ci // if (bar.x < 0.0) 1367fd4e5da5Sopenharmony_ci // return 0.0; 1368fd4e5da5Sopenharmony_ci // return bar.x; 1369fd4e5da5Sopenharmony_ci // } 1370fd4e5da5Sopenharmony_ci // } 1371fd4e5da5Sopenharmony_ci // 1372fd4e5da5Sopenharmony_ci // void main() 1373fd4e5da5Sopenharmony_ci // { 1374fd4e5da5Sopenharmony_ci // vec4 color = vec4(foo(BaseColor)); 1375fd4e5da5Sopenharmony_ci // gl_FragColor = color; 1376fd4e5da5Sopenharmony_ci // } 1377fd4e5da5Sopenharmony_ci 1378fd4e5da5Sopenharmony_ci const std::string assembly = 1379fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1380fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1381fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1382fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 1383fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1384fd4e5da5Sopenharmony_ciOpSource GLSL 140 1385fd4e5da5Sopenharmony_ciOpName %main "main" 1386fd4e5da5Sopenharmony_ciOpName %foo_vf4_ "foo(vf4;" 1387fd4e5da5Sopenharmony_ciOpName %bar "bar" 1388fd4e5da5Sopenharmony_ciOpName %color "color" 1389fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 1390fd4e5da5Sopenharmony_ciOpName %param "param" 1391fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 1392fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1393fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void 1394fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1395fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1396fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1397fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %float %_ptr_Function_v4float 1398fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1399fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1400fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1401fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1402fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 1403fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 1404fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 1405fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 1406fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1407fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 1408fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10 1409fd4e5da5Sopenharmony_ci%23 = OpLabel 1410fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function 1411fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function 1412fd4e5da5Sopenharmony_ci%24 = OpLoad %v4float %BaseColor 1413fd4e5da5Sopenharmony_ciOpStore %param %24 1414fd4e5da5Sopenharmony_ci%25 = OpFunctionCall %float %foo_vf4_ %param 1415fd4e5da5Sopenharmony_ci%26 = OpCompositeConstruct %v4float %25 %25 %25 %25 1416fd4e5da5Sopenharmony_ciOpStore %color %26 1417fd4e5da5Sopenharmony_ci%27 = OpLoad %v4float %color 1418fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %27 1419fd4e5da5Sopenharmony_ciOpReturn 1420fd4e5da5Sopenharmony_ciOpFunctionEnd 1421fd4e5da5Sopenharmony_ci%foo_vf4_ = OpFunction %float None %14 1422fd4e5da5Sopenharmony_ci%bar = OpFunctionParameter %_ptr_Function_v4float 1423fd4e5da5Sopenharmony_ci%28 = OpLabel 1424fd4e5da5Sopenharmony_ciOpBranch %29 1425fd4e5da5Sopenharmony_ci%29 = OpLabel 1426fd4e5da5Sopenharmony_ciOpLoopMerge %30 %31 None 1427fd4e5da5Sopenharmony_ciOpBranch %32 1428fd4e5da5Sopenharmony_ci%32 = OpLabel 1429fd4e5da5Sopenharmony_ciOpBranchConditional %true %33 %30 1430fd4e5da5Sopenharmony_ci%33 = OpLabel 1431fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Function_float %bar %uint_0 1432fd4e5da5Sopenharmony_ci%35 = OpLoad %float %34 1433fd4e5da5Sopenharmony_ci%36 = OpFOrdLessThan %bool %35 %float_0 1434fd4e5da5Sopenharmony_ciOpSelectionMerge %37 None 1435fd4e5da5Sopenharmony_ciOpBranchConditional %36 %38 %37 1436fd4e5da5Sopenharmony_ci%38 = OpLabel 1437fd4e5da5Sopenharmony_ciOpReturnValue %float_0 1438fd4e5da5Sopenharmony_ci%37 = OpLabel 1439fd4e5da5Sopenharmony_ci%39 = OpAccessChain %_ptr_Function_float %bar %uint_0 1440fd4e5da5Sopenharmony_ci%40 = OpLoad %float %39 1441fd4e5da5Sopenharmony_ciOpReturnValue %40 1442fd4e5da5Sopenharmony_ci%31 = OpLabel 1443fd4e5da5Sopenharmony_ciOpBranch %29 1444fd4e5da5Sopenharmony_ci%30 = OpLabel 1445fd4e5da5Sopenharmony_ci%41 = OpUndef %float 1446fd4e5da5Sopenharmony_ciOpReturnValue %41 1447fd4e5da5Sopenharmony_ciOpFunctionEnd 1448fd4e5da5Sopenharmony_ci)"; 1449fd4e5da5Sopenharmony_ci 1450fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(assembly, assembly, false, true); 1451fd4e5da5Sopenharmony_ci} 1452fd4e5da5Sopenharmony_ci 1453fd4e5da5Sopenharmony_ciTEST_F(InlineTest, ExternalFunctionIsNotInlined) { 1454fd4e5da5Sopenharmony_ci // In particular, don't crash. 1455fd4e5da5Sopenharmony_ci // See report https://github.com/KhronosGroup/SPIRV-Tools/issues/605 1456fd4e5da5Sopenharmony_ci const std::string assembly = 1457fd4e5da5Sopenharmony_ci R"(OpCapability Addresses 1458fd4e5da5Sopenharmony_ciOpCapability Kernel 1459fd4e5da5Sopenharmony_ciOpCapability Linkage 1460fd4e5da5Sopenharmony_ciOpMemoryModel Physical32 OpenCL 1461fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %1 "entry_pt" 1462fd4e5da5Sopenharmony_ciOpDecorate %2 LinkageAttributes "external" Import 1463fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1464fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 1465fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %4 1466fd4e5da5Sopenharmony_ciOpFunctionEnd 1467fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %4 1468fd4e5da5Sopenharmony_ci%5 = OpLabel 1469fd4e5da5Sopenharmony_ci%6 = OpFunctionCall %void %2 1470fd4e5da5Sopenharmony_ciOpReturn 1471fd4e5da5Sopenharmony_ciOpFunctionEnd 1472fd4e5da5Sopenharmony_ci)"; 1473fd4e5da5Sopenharmony_ci 1474fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(assembly, assembly, false, true); 1475fd4e5da5Sopenharmony_ci} 1476fd4e5da5Sopenharmony_ci 1477fd4e5da5Sopenharmony_ciTEST_F(InlineTest, SingleBlockLoopCallsMultiBlockCallee) { 1478fd4e5da5Sopenharmony_ci // Example from https://github.com/KhronosGroup/SPIRV-Tools/issues/787 1479fd4e5da5Sopenharmony_ci // 1480fd4e5da5Sopenharmony_ci // CFG structure is: 1481fd4e5da5Sopenharmony_ci // foo: 1482fd4e5da5Sopenharmony_ci // fooentry -> fooexit 1483fd4e5da5Sopenharmony_ci // 1484fd4e5da5Sopenharmony_ci // main: 1485fd4e5da5Sopenharmony_ci // entry -> loop 1486fd4e5da5Sopenharmony_ci // loop -> loop, merge 1487fd4e5da5Sopenharmony_ci // loop calls foo() 1488fd4e5da5Sopenharmony_ci // merge 1489fd4e5da5Sopenharmony_ci // 1490fd4e5da5Sopenharmony_ci // Since the callee has multiple blocks, it will split the calling block 1491fd4e5da5Sopenharmony_ci // into at least two, resulting in a new "back-half" block that contains 1492fd4e5da5Sopenharmony_ci // the instructions after the inlined function call. If the calling block 1493fd4e5da5Sopenharmony_ci // has an OpLoopMerge that points back to the calling block itself, then 1494fd4e5da5Sopenharmony_ci // the OpLoopMerge can't remain in the back-half block, but must be 1495fd4e5da5Sopenharmony_ci // moved to the end of the original calling block, and it continue target 1496fd4e5da5Sopenharmony_ci // operand updated to point to the back-half block. 1497fd4e5da5Sopenharmony_ci 1498fd4e5da5Sopenharmony_ci const std::string predefs = 1499fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1500fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1501fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %1 "main" 1502fd4e5da5Sopenharmony_ciOpSource OpenCL_C 120 1503fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1504fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1505fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1506fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 1507fd4e5da5Sopenharmony_ci)"; 1508fd4e5da5Sopenharmony_ci 1509fd4e5da5Sopenharmony_ci const std::string nonEntryFuncs = 1510fd4e5da5Sopenharmony_ci R"(%6 = OpFunction %void None %5 1511fd4e5da5Sopenharmony_ci%7 = OpLabel 1512fd4e5da5Sopenharmony_ciOpBranch %8 1513fd4e5da5Sopenharmony_ci%8 = OpLabel 1514fd4e5da5Sopenharmony_ciOpReturn 1515fd4e5da5Sopenharmony_ciOpFunctionEnd 1516fd4e5da5Sopenharmony_ci)"; 1517fd4e5da5Sopenharmony_ci 1518fd4e5da5Sopenharmony_ci const std::string before = 1519fd4e5da5Sopenharmony_ci R"(%1 = OpFunction %void None %5 1520fd4e5da5Sopenharmony_ci%9 = OpLabel 1521fd4e5da5Sopenharmony_ciOpBranch %10 1522fd4e5da5Sopenharmony_ci%10 = OpLabel 1523fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %void %6 1524fd4e5da5Sopenharmony_ciOpLoopMerge %12 %10 None 1525fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %12 1526fd4e5da5Sopenharmony_ci%12 = OpLabel 1527fd4e5da5Sopenharmony_ciOpReturn 1528fd4e5da5Sopenharmony_ciOpFunctionEnd 1529fd4e5da5Sopenharmony_ci)"; 1530fd4e5da5Sopenharmony_ci 1531fd4e5da5Sopenharmony_ci const std::string after = 1532fd4e5da5Sopenharmony_ci R"(%1 = OpFunction %void None %5 1533fd4e5da5Sopenharmony_ci%9 = OpLabel 1534fd4e5da5Sopenharmony_ciOpBranch %10 1535fd4e5da5Sopenharmony_ci%10 = OpLabel 1536fd4e5da5Sopenharmony_ciOpLoopMerge %12 %15 None 1537fd4e5da5Sopenharmony_ciOpBranch %14 1538fd4e5da5Sopenharmony_ci%14 = OpLabel 1539fd4e5da5Sopenharmony_ciOpBranch %15 1540fd4e5da5Sopenharmony_ci%15 = OpLabel 1541fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %12 1542fd4e5da5Sopenharmony_ci%12 = OpLabel 1543fd4e5da5Sopenharmony_ciOpReturn 1544fd4e5da5Sopenharmony_ciOpFunctionEnd 1545fd4e5da5Sopenharmony_ci)"; 1546fd4e5da5Sopenharmony_ci 1547fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(predefs + nonEntryFuncs + before, 1548fd4e5da5Sopenharmony_ci predefs + nonEntryFuncs + after, 1549fd4e5da5Sopenharmony_ci false, true); 1550fd4e5da5Sopenharmony_ci} 1551fd4e5da5Sopenharmony_ci 1552fd4e5da5Sopenharmony_ciTEST_F(InlineTest, MultiBlockLoopHeaderCallsMultiBlockCallee) { 1553fd4e5da5Sopenharmony_ci // Like SingleBlockLoopCallsMultiBlockCallee but the loop has several 1554fd4e5da5Sopenharmony_ci // blocks, but the function call still occurs in the loop header. 1555fd4e5da5Sopenharmony_ci // Example from https://github.com/KhronosGroup/SPIRV-Tools/issues/800 1556fd4e5da5Sopenharmony_ci 1557fd4e5da5Sopenharmony_ci const std::string predefs = 1558fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1559fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1560fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %1 "main" 1561fd4e5da5Sopenharmony_ciOpSource OpenCL_C 120 1562fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1563fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1564fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1565fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1566fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2 1567fd4e5da5Sopenharmony_ci%int_3 = OpConstant %int 3 1568fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4 1569fd4e5da5Sopenharmony_ci%int_5 = OpConstant %int 5 1570fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1571fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void 1572fd4e5da5Sopenharmony_ci)"; 1573fd4e5da5Sopenharmony_ci 1574fd4e5da5Sopenharmony_ci const std::string nonEntryFuncs = 1575fd4e5da5Sopenharmony_ci R"(%12 = OpFunction %void None %11 1576fd4e5da5Sopenharmony_ci%13 = OpLabel 1577fd4e5da5Sopenharmony_ci%14 = OpCopyObject %int %int_1 1578fd4e5da5Sopenharmony_ciOpBranch %15 1579fd4e5da5Sopenharmony_ci%15 = OpLabel 1580fd4e5da5Sopenharmony_ci%16 = OpCopyObject %int %int_2 1581fd4e5da5Sopenharmony_ciOpReturn 1582fd4e5da5Sopenharmony_ciOpFunctionEnd 1583fd4e5da5Sopenharmony_ci)"; 1584fd4e5da5Sopenharmony_ci 1585fd4e5da5Sopenharmony_ci const std::string before = 1586fd4e5da5Sopenharmony_ci R"(%1 = OpFunction %void None %11 1587fd4e5da5Sopenharmony_ci%17 = OpLabel 1588fd4e5da5Sopenharmony_ciOpBranch %18 1589fd4e5da5Sopenharmony_ci%18 = OpLabel 1590fd4e5da5Sopenharmony_ci%19 = OpCopyObject %int %int_3 1591fd4e5da5Sopenharmony_ci%20 = OpFunctionCall %void %12 1592fd4e5da5Sopenharmony_ci%21 = OpCopyObject %int %int_4 1593fd4e5da5Sopenharmony_ciOpLoopMerge %22 %23 None 1594fd4e5da5Sopenharmony_ciOpBranchConditional %true %23 %22 1595fd4e5da5Sopenharmony_ci%23 = OpLabel 1596fd4e5da5Sopenharmony_ci%24 = OpCopyObject %int %int_5 1597fd4e5da5Sopenharmony_ciOpBranchConditional %true %18 %22 1598fd4e5da5Sopenharmony_ci%22 = OpLabel 1599fd4e5da5Sopenharmony_ciOpReturn 1600fd4e5da5Sopenharmony_ciOpFunctionEnd 1601fd4e5da5Sopenharmony_ci)"; 1602fd4e5da5Sopenharmony_ci 1603fd4e5da5Sopenharmony_ci const std::string after = 1604fd4e5da5Sopenharmony_ci R"(%1 = OpFunction %void None %11 1605fd4e5da5Sopenharmony_ci%17 = OpLabel 1606fd4e5da5Sopenharmony_ciOpBranch %18 1607fd4e5da5Sopenharmony_ci%18 = OpLabel 1608fd4e5da5Sopenharmony_ci%19 = OpCopyObject %int %int_3 1609fd4e5da5Sopenharmony_ci%26 = OpCopyObject %int %int_1 1610fd4e5da5Sopenharmony_ciOpLoopMerge %22 %23 None 1611fd4e5da5Sopenharmony_ciOpBranch %27 1612fd4e5da5Sopenharmony_ci%27 = OpLabel 1613fd4e5da5Sopenharmony_ci%28 = OpCopyObject %int %int_2 1614fd4e5da5Sopenharmony_ci%21 = OpCopyObject %int %int_4 1615fd4e5da5Sopenharmony_ciOpBranchConditional %true %23 %22 1616fd4e5da5Sopenharmony_ci%23 = OpLabel 1617fd4e5da5Sopenharmony_ci%24 = OpCopyObject %int %int_5 1618fd4e5da5Sopenharmony_ciOpBranchConditional %true %18 %22 1619fd4e5da5Sopenharmony_ci%22 = OpLabel 1620fd4e5da5Sopenharmony_ciOpReturn 1621fd4e5da5Sopenharmony_ciOpFunctionEnd 1622fd4e5da5Sopenharmony_ci)"; 1623fd4e5da5Sopenharmony_ci 1624fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(predefs + nonEntryFuncs + before, 1625fd4e5da5Sopenharmony_ci predefs + nonEntryFuncs + after, 1626fd4e5da5Sopenharmony_ci false, true); 1627fd4e5da5Sopenharmony_ci} 1628fd4e5da5Sopenharmony_ci 1629fd4e5da5Sopenharmony_ciTEST_F(InlineTest, SingleBlockLoopCallsMultiBlockCalleeHavingSelectionMerge) { 1630fd4e5da5Sopenharmony_ci // This is similar to SingleBlockLoopCallsMultiBlockCallee except 1631fd4e5da5Sopenharmony_ci // that calleee block also has a merge instruction in its first block. 1632fd4e5da5Sopenharmony_ci // That merge instruction must be an OpSelectionMerge (because the entry 1633fd4e5da5Sopenharmony_ci // block of a function can't be the header of a loop since the entry 1634fd4e5da5Sopenharmony_ci // block can't be the target of a branch). 1635fd4e5da5Sopenharmony_ci // 1636fd4e5da5Sopenharmony_ci // In this case the OpLoopMerge can't be placed in the same block as 1637fd4e5da5Sopenharmony_ci // the OpSelectionMerge, so inlining must create a new block to contain 1638fd4e5da5Sopenharmony_ci // the callee contents. 1639fd4e5da5Sopenharmony_ci // 1640fd4e5da5Sopenharmony_ci // Additionally, we have two extra OpCopyObject instructions to prove that 1641fd4e5da5Sopenharmony_ci // the OpLoopMerge is moved to the right location. 1642fd4e5da5Sopenharmony_ci // 1643fd4e5da5Sopenharmony_ci // Also ensure that OpPhis within the cloned callee code are valid. 1644fd4e5da5Sopenharmony_ci // We need to test that the predecessor blocks are remapped correctly so that 1645fd4e5da5Sopenharmony_ci // dominance rules are satisfied 1646fd4e5da5Sopenharmony_ci 1647fd4e5da5Sopenharmony_ci const std::string predefs = 1648fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1649fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1650fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %1 "main" 1651fd4e5da5Sopenharmony_ciOpSource OpenCL_C 120 1652fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1653fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1654fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1655fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1656fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void 1657fd4e5da5Sopenharmony_ci)"; 1658fd4e5da5Sopenharmony_ci 1659fd4e5da5Sopenharmony_ci // This callee has multiple blocks, and an OpPhi in the last block 1660fd4e5da5Sopenharmony_ci // that references a value from the first block. This tests that 1661fd4e5da5Sopenharmony_ci // cloned block IDs are remapped appropriately. The OpPhi dominance 1662fd4e5da5Sopenharmony_ci // requires that the remapped %9 must be in a block that dominates 1663fd4e5da5Sopenharmony_ci // the remapped %8. 1664fd4e5da5Sopenharmony_ci const std::string nonEntryFuncs = 1665fd4e5da5Sopenharmony_ci R"(%7 = OpFunction %void None %6 1666fd4e5da5Sopenharmony_ci%8 = OpLabel 1667fd4e5da5Sopenharmony_ci%9 = OpCopyObject %bool %true 1668fd4e5da5Sopenharmony_ciOpSelectionMerge %10 None 1669fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %10 1670fd4e5da5Sopenharmony_ci%10 = OpLabel 1671fd4e5da5Sopenharmony_ci%11 = OpPhi %bool %9 %8 1672fd4e5da5Sopenharmony_ciOpReturn 1673fd4e5da5Sopenharmony_ciOpFunctionEnd 1674fd4e5da5Sopenharmony_ci)"; 1675fd4e5da5Sopenharmony_ci 1676fd4e5da5Sopenharmony_ci const std::string before = 1677fd4e5da5Sopenharmony_ci R"(%1 = OpFunction %void None %6 1678fd4e5da5Sopenharmony_ci%12 = OpLabel 1679fd4e5da5Sopenharmony_ciOpBranch %13 1680fd4e5da5Sopenharmony_ci%13 = OpLabel 1681fd4e5da5Sopenharmony_ci%14 = OpCopyObject %bool %false 1682fd4e5da5Sopenharmony_ci%15 = OpFunctionCall %void %7 1683fd4e5da5Sopenharmony_ciOpLoopMerge %16 %13 None 1684fd4e5da5Sopenharmony_ciOpBranchConditional %true %13 %16 1685fd4e5da5Sopenharmony_ci%16 = OpLabel 1686fd4e5da5Sopenharmony_ciOpReturn 1687fd4e5da5Sopenharmony_ciOpFunctionEnd 1688fd4e5da5Sopenharmony_ci)"; 1689fd4e5da5Sopenharmony_ci 1690fd4e5da5Sopenharmony_ci // Note the remapped Phi uses %17 as the parent instead 1691fd4e5da5Sopenharmony_ci // of %13, demonstrating that the parent block has been remapped 1692fd4e5da5Sopenharmony_ci // correctly. 1693fd4e5da5Sopenharmony_ci const std::string after = 1694fd4e5da5Sopenharmony_ci R"(%1 = OpFunction %void None %6 1695fd4e5da5Sopenharmony_ci%12 = OpLabel 1696fd4e5da5Sopenharmony_ciOpBranch %13 1697fd4e5da5Sopenharmony_ci%13 = OpLabel 1698fd4e5da5Sopenharmony_ci%14 = OpCopyObject %bool %false 1699fd4e5da5Sopenharmony_ciOpLoopMerge %16 %22 None 1700fd4e5da5Sopenharmony_ciOpBranch %17 1701fd4e5da5Sopenharmony_ci%17 = OpLabel 1702fd4e5da5Sopenharmony_ci%19 = OpCopyObject %bool %true 1703fd4e5da5Sopenharmony_ciOpSelectionMerge %20 None 1704fd4e5da5Sopenharmony_ciOpBranchConditional %true %20 %20 1705fd4e5da5Sopenharmony_ci%20 = OpLabel 1706fd4e5da5Sopenharmony_ci%21 = OpPhi %bool %19 %17 1707fd4e5da5Sopenharmony_ciOpBranch %22 1708fd4e5da5Sopenharmony_ci%22 = OpLabel 1709fd4e5da5Sopenharmony_ciOpBranchConditional %true %13 %16 1710fd4e5da5Sopenharmony_ci%16 = OpLabel 1711fd4e5da5Sopenharmony_ciOpReturn 1712fd4e5da5Sopenharmony_ciOpFunctionEnd 1713fd4e5da5Sopenharmony_ci)"; 1714fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(predefs + nonEntryFuncs + before, 1715fd4e5da5Sopenharmony_ci predefs + nonEntryFuncs + after, 1716fd4e5da5Sopenharmony_ci false, true); 1717fd4e5da5Sopenharmony_ci} 1718fd4e5da5Sopenharmony_ci 1719fd4e5da5Sopenharmony_ciTEST_F(InlineTest, 1720fd4e5da5Sopenharmony_ci MultiBlockLoopHeaderCallsFromToMultiBlockCalleeHavingSelectionMerge) { 1721fd4e5da5Sopenharmony_ci // This is similar to SingleBlockLoopCallsMultiBlockCalleeHavingSelectionMerge 1722fd4e5da5Sopenharmony_ci // but the call is in the header block of a multi block loop. 1723fd4e5da5Sopenharmony_ci 1724fd4e5da5Sopenharmony_ci const std::string predefs = 1725fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1726fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1727fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %1 "main" 1728fd4e5da5Sopenharmony_ciOpSource OpenCL_C 120 1729fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1730fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1731fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1732fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1733fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2 1734fd4e5da5Sopenharmony_ci%int_3 = OpConstant %int 3 1735fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4 1736fd4e5da5Sopenharmony_ci%int_5 = OpConstant %int 5 1737fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1738fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void 1739fd4e5da5Sopenharmony_ci)"; 1740fd4e5da5Sopenharmony_ci 1741fd4e5da5Sopenharmony_ci const std::string nonEntryFuncs = 1742fd4e5da5Sopenharmony_ci R"(%12 = OpFunction %void None %11 1743fd4e5da5Sopenharmony_ci%13 = OpLabel 1744fd4e5da5Sopenharmony_ci%14 = OpCopyObject %int %int_1 1745fd4e5da5Sopenharmony_ciOpSelectionMerge %15 None 1746fd4e5da5Sopenharmony_ciOpBranchConditional %true %15 %15 1747fd4e5da5Sopenharmony_ci%15 = OpLabel 1748fd4e5da5Sopenharmony_ci%16 = OpCopyObject %int %int_2 1749fd4e5da5Sopenharmony_ciOpReturn 1750fd4e5da5Sopenharmony_ciOpFunctionEnd 1751fd4e5da5Sopenharmony_ci)"; 1752fd4e5da5Sopenharmony_ci 1753fd4e5da5Sopenharmony_ci const std::string before = 1754fd4e5da5Sopenharmony_ci R"(%1 = OpFunction %void None %11 1755fd4e5da5Sopenharmony_ci%17 = OpLabel 1756fd4e5da5Sopenharmony_ciOpBranch %18 1757fd4e5da5Sopenharmony_ci%18 = OpLabel 1758fd4e5da5Sopenharmony_ci%19 = OpCopyObject %int %int_3 1759fd4e5da5Sopenharmony_ci%20 = OpFunctionCall %void %12 1760fd4e5da5Sopenharmony_ci%21 = OpCopyObject %int %int_4 1761fd4e5da5Sopenharmony_ciOpLoopMerge %22 %23 None 1762fd4e5da5Sopenharmony_ciOpBranchConditional %true %23 %22 1763fd4e5da5Sopenharmony_ci%23 = OpLabel 1764fd4e5da5Sopenharmony_ci%24 = OpCopyObject %int %int_5 1765fd4e5da5Sopenharmony_ciOpBranchConditional %true %18 %22 1766fd4e5da5Sopenharmony_ci%22 = OpLabel 1767fd4e5da5Sopenharmony_ciOpReturn 1768fd4e5da5Sopenharmony_ciOpFunctionEnd 1769fd4e5da5Sopenharmony_ci)"; 1770fd4e5da5Sopenharmony_ci 1771fd4e5da5Sopenharmony_ci const std::string after = 1772fd4e5da5Sopenharmony_ci R"(%1 = OpFunction %void None %11 1773fd4e5da5Sopenharmony_ci%17 = OpLabel 1774fd4e5da5Sopenharmony_ciOpBranch %18 1775fd4e5da5Sopenharmony_ci%18 = OpLabel 1776fd4e5da5Sopenharmony_ci%19 = OpCopyObject %int %int_3 1777fd4e5da5Sopenharmony_ciOpLoopMerge %22 %23 None 1778fd4e5da5Sopenharmony_ciOpBranch %25 1779fd4e5da5Sopenharmony_ci%25 = OpLabel 1780fd4e5da5Sopenharmony_ci%27 = OpCopyObject %int %int_1 1781fd4e5da5Sopenharmony_ciOpSelectionMerge %28 None 1782fd4e5da5Sopenharmony_ciOpBranchConditional %true %28 %28 1783fd4e5da5Sopenharmony_ci%28 = OpLabel 1784fd4e5da5Sopenharmony_ci%29 = OpCopyObject %int %int_2 1785fd4e5da5Sopenharmony_ci%21 = OpCopyObject %int %int_4 1786fd4e5da5Sopenharmony_ciOpBranchConditional %true %23 %22 1787fd4e5da5Sopenharmony_ci%23 = OpLabel 1788fd4e5da5Sopenharmony_ci%24 = OpCopyObject %int %int_5 1789fd4e5da5Sopenharmony_ciOpBranchConditional %true %18 %22 1790fd4e5da5Sopenharmony_ci%22 = OpLabel 1791fd4e5da5Sopenharmony_ciOpReturn 1792fd4e5da5Sopenharmony_ciOpFunctionEnd 1793fd4e5da5Sopenharmony_ci)"; 1794fd4e5da5Sopenharmony_ci 1795fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(predefs + nonEntryFuncs + before, 1796fd4e5da5Sopenharmony_ci predefs + nonEntryFuncs + after, 1797fd4e5da5Sopenharmony_ci false, true); 1798fd4e5da5Sopenharmony_ci} 1799fd4e5da5Sopenharmony_ci 1800fd4e5da5Sopenharmony_ciTEST_F(InlineTest, NonInlinableCalleeWithSingleReturn) { 1801fd4e5da5Sopenharmony_ci // The case from https://github.com/KhronosGroup/SPIRV-Tools/issues/2018 1802fd4e5da5Sopenharmony_ci // 1803fd4e5da5Sopenharmony_ci // The callee has a single return, but cannot be inlined because the 1804fd4e5da5Sopenharmony_ci // return is inside a loop. 1805fd4e5da5Sopenharmony_ci 1806fd4e5da5Sopenharmony_ci const std::string predefs = 1807fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1808fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1809fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1810fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %_GLF_color 1811fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1812fd4e5da5Sopenharmony_ciOpSource ESSL 310 1813fd4e5da5Sopenharmony_ciOpName %main "main" 1814fd4e5da5Sopenharmony_ciOpName %f_ "f(" 1815fd4e5da5Sopenharmony_ciOpName %i "i" 1816fd4e5da5Sopenharmony_ciOpName %_GLF_color "_GLF_color" 1817fd4e5da5Sopenharmony_ciOpDecorate %_GLF_color Location 0 1818fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1819fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 1820fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1821fd4e5da5Sopenharmony_ci%9 = OpTypeFunction %float 1822fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 1823fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1824fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1825fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1826fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 1827fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 1828fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1829fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1830fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1831fd4e5da5Sopenharmony_ci%_GLF_color = OpVariable %_ptr_Output_v4float Output 1832fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 1833fd4e5da5Sopenharmony_ci%20 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 1834fd4e5da5Sopenharmony_ci%21 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1 1835fd4e5da5Sopenharmony_ci)"; 1836fd4e5da5Sopenharmony_ci 1837fd4e5da5Sopenharmony_ci const std::string caller = 1838fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 1839fd4e5da5Sopenharmony_ci%22 = OpLabel 1840fd4e5da5Sopenharmony_ci%i = OpVariable %_ptr_Function_int Function 1841fd4e5da5Sopenharmony_ciOpStore %i %int_0 1842fd4e5da5Sopenharmony_ciOpBranch %23 1843fd4e5da5Sopenharmony_ci%23 = OpLabel 1844fd4e5da5Sopenharmony_ciOpLoopMerge %24 %25 None 1845fd4e5da5Sopenharmony_ciOpBranch %26 1846fd4e5da5Sopenharmony_ci%26 = OpLabel 1847fd4e5da5Sopenharmony_ci%27 = OpLoad %int %i 1848fd4e5da5Sopenharmony_ci%28 = OpSLessThan %bool %27 %int_1 1849fd4e5da5Sopenharmony_ciOpBranchConditional %28 %29 %24 1850fd4e5da5Sopenharmony_ci%29 = OpLabel 1851fd4e5da5Sopenharmony_ciOpStore %_GLF_color %20 1852fd4e5da5Sopenharmony_ci%30 = OpFunctionCall %float %f_ 1853fd4e5da5Sopenharmony_ciOpBranch %25 1854fd4e5da5Sopenharmony_ci%25 = OpLabel 1855fd4e5da5Sopenharmony_ci%31 = OpLoad %int %i 1856fd4e5da5Sopenharmony_ci%32 = OpIAdd %int %31 %int_1 1857fd4e5da5Sopenharmony_ciOpStore %i %32 1858fd4e5da5Sopenharmony_ciOpBranch %23 1859fd4e5da5Sopenharmony_ci%24 = OpLabel 1860fd4e5da5Sopenharmony_ciOpStore %_GLF_color %21 1861fd4e5da5Sopenharmony_ciOpReturn 1862fd4e5da5Sopenharmony_ciOpFunctionEnd 1863fd4e5da5Sopenharmony_ci)"; 1864fd4e5da5Sopenharmony_ci 1865fd4e5da5Sopenharmony_ci const std::string callee = 1866fd4e5da5Sopenharmony_ci R"(%f_ = OpFunction %float None %9 1867fd4e5da5Sopenharmony_ci%33 = OpLabel 1868fd4e5da5Sopenharmony_ciOpBranch %34 1869fd4e5da5Sopenharmony_ci%34 = OpLabel 1870fd4e5da5Sopenharmony_ciOpLoopMerge %35 %36 None 1871fd4e5da5Sopenharmony_ciOpBranch %37 1872fd4e5da5Sopenharmony_ci%37 = OpLabel 1873fd4e5da5Sopenharmony_ciOpReturnValue %float_1 1874fd4e5da5Sopenharmony_ci%36 = OpLabel 1875fd4e5da5Sopenharmony_ciOpBranch %34 1876fd4e5da5Sopenharmony_ci%35 = OpLabel 1877fd4e5da5Sopenharmony_ciOpUnreachable 1878fd4e5da5Sopenharmony_ciOpFunctionEnd 1879fd4e5da5Sopenharmony_ci)"; 1880fd4e5da5Sopenharmony_ci 1881fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>( 1882fd4e5da5Sopenharmony_ci predefs + caller + callee, predefs + caller + callee, false, true); 1883fd4e5da5Sopenharmony_ci} 1884fd4e5da5Sopenharmony_ci 1885fd4e5da5Sopenharmony_ciTEST_F(InlineTest, Decorated1) { 1886fd4e5da5Sopenharmony_ci // Same test as Simple with the difference 1887fd4e5da5Sopenharmony_ci // that OpFAdd in the outlined function is 1888fd4e5da5Sopenharmony_ci // decorated with RelaxedPrecision 1889fd4e5da5Sopenharmony_ci // Expected result is an equal decoration 1890fd4e5da5Sopenharmony_ci // of the corresponding inlined instruction 1891fd4e5da5Sopenharmony_ci // 1892fd4e5da5Sopenharmony_ci // #version 140 1893fd4e5da5Sopenharmony_ci // 1894fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 1895fd4e5da5Sopenharmony_ci // 1896fd4e5da5Sopenharmony_ci // float foo(vec4 bar) 1897fd4e5da5Sopenharmony_ci // { 1898fd4e5da5Sopenharmony_ci // return bar.x + bar.y; 1899fd4e5da5Sopenharmony_ci // } 1900fd4e5da5Sopenharmony_ci // 1901fd4e5da5Sopenharmony_ci // void main() 1902fd4e5da5Sopenharmony_ci // { 1903fd4e5da5Sopenharmony_ci // vec4 color = vec4(foo(BaseColor)); 1904fd4e5da5Sopenharmony_ci // gl_FragColor = color; 1905fd4e5da5Sopenharmony_ci // } 1906fd4e5da5Sopenharmony_ci 1907fd4e5da5Sopenharmony_ci const std::string predefs = 1908fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1909fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1910fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1911fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 1912fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1913fd4e5da5Sopenharmony_ciOpSource GLSL 140 1914fd4e5da5Sopenharmony_ciOpName %main "main" 1915fd4e5da5Sopenharmony_ciOpName %foo_vf4_ "foo(vf4;" 1916fd4e5da5Sopenharmony_ciOpName %bar "bar" 1917fd4e5da5Sopenharmony_ciOpName %color "color" 1918fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 1919fd4e5da5Sopenharmony_ciOpName %param "param" 1920fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 1921fd4e5da5Sopenharmony_ciOpDecorate %9 RelaxedPrecision 1922fd4e5da5Sopenharmony_ci)"; 1923fd4e5da5Sopenharmony_ci 1924fd4e5da5Sopenharmony_ci const std::string before = 1925fd4e5da5Sopenharmony_ci R"(%void = OpTypeVoid 1926fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void 1927fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1928fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1929fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1930fd4e5da5Sopenharmony_ci%15 = OpTypeFunction %float %_ptr_Function_v4float 1931fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1932fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1933fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 1934fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 1935fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 1936fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 1937fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1938fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 1939fd4e5da5Sopenharmony_ci%main = OpFunction %void None %11 1940fd4e5da5Sopenharmony_ci%22 = OpLabel 1941fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function 1942fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function 1943fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor 1944fd4e5da5Sopenharmony_ciOpStore %param %23 1945fd4e5da5Sopenharmony_ci%24 = OpFunctionCall %float %foo_vf4_ %param 1946fd4e5da5Sopenharmony_ci%25 = OpCompositeConstruct %v4float %24 %24 %24 %24 1947fd4e5da5Sopenharmony_ciOpStore %color %25 1948fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %color 1949fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %26 1950fd4e5da5Sopenharmony_ciOpReturn 1951fd4e5da5Sopenharmony_ciOpFunctionEnd 1952fd4e5da5Sopenharmony_ci)"; 1953fd4e5da5Sopenharmony_ci 1954fd4e5da5Sopenharmony_ci const std::string after = 1955fd4e5da5Sopenharmony_ci R"(OpDecorate %38 RelaxedPrecision 1956fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1957fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void 1958fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1959fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1960fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1961fd4e5da5Sopenharmony_ci%15 = OpTypeFunction %float %_ptr_Function_v4float 1962fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1963fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1964fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 1965fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 1966fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 1967fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 1968fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1969fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 1970fd4e5da5Sopenharmony_ci%main = OpFunction %void None %11 1971fd4e5da5Sopenharmony_ci%22 = OpLabel 1972fd4e5da5Sopenharmony_ci%32 = OpVariable %_ptr_Function_float Function 1973fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function 1974fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function 1975fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor 1976fd4e5da5Sopenharmony_ciOpStore %param %23 1977fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Function_float %param %uint_0 1978fd4e5da5Sopenharmony_ci%35 = OpLoad %float %34 1979fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_float %param %uint_1 1980fd4e5da5Sopenharmony_ci%37 = OpLoad %float %36 1981fd4e5da5Sopenharmony_ci%38 = OpFAdd %float %35 %37 1982fd4e5da5Sopenharmony_ciOpStore %32 %38 1983fd4e5da5Sopenharmony_ci%24 = OpLoad %float %32 1984fd4e5da5Sopenharmony_ci%25 = OpCompositeConstruct %v4float %24 %24 %24 %24 1985fd4e5da5Sopenharmony_ciOpStore %color %25 1986fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %color 1987fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %26 1988fd4e5da5Sopenharmony_ciOpReturn 1989fd4e5da5Sopenharmony_ciOpFunctionEnd 1990fd4e5da5Sopenharmony_ci)"; 1991fd4e5da5Sopenharmony_ci 1992fd4e5da5Sopenharmony_ci const std::string nonEntryFuncs = 1993fd4e5da5Sopenharmony_ci R"(%foo_vf4_ = OpFunction %float None %15 1994fd4e5da5Sopenharmony_ci%bar = OpFunctionParameter %_ptr_Function_v4float 1995fd4e5da5Sopenharmony_ci%27 = OpLabel 1996fd4e5da5Sopenharmony_ci%28 = OpAccessChain %_ptr_Function_float %bar %uint_0 1997fd4e5da5Sopenharmony_ci%29 = OpLoad %float %28 1998fd4e5da5Sopenharmony_ci%30 = OpAccessChain %_ptr_Function_float %bar %uint_1 1999fd4e5da5Sopenharmony_ci%31 = OpLoad %float %30 2000fd4e5da5Sopenharmony_ci%9 = OpFAdd %float %29 %31 2001fd4e5da5Sopenharmony_ciOpReturnValue %9 2002fd4e5da5Sopenharmony_ciOpFunctionEnd 2003fd4e5da5Sopenharmony_ci)"; 2004fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(predefs + before + nonEntryFuncs, 2005fd4e5da5Sopenharmony_ci predefs + after + nonEntryFuncs, 2006fd4e5da5Sopenharmony_ci false, true); 2007fd4e5da5Sopenharmony_ci} 2008fd4e5da5Sopenharmony_ci 2009fd4e5da5Sopenharmony_ciTEST_F(InlineTest, Decorated2) { 2010fd4e5da5Sopenharmony_ci // Same test as Simple with the difference 2011fd4e5da5Sopenharmony_ci // that the Result <id> of the outlined OpFunction 2012fd4e5da5Sopenharmony_ci // is decorated with RelaxedPrecision 2013fd4e5da5Sopenharmony_ci // Expected result is an equal decoration 2014fd4e5da5Sopenharmony_ci // of the created return variable 2015fd4e5da5Sopenharmony_ci // 2016fd4e5da5Sopenharmony_ci // #version 140 2017fd4e5da5Sopenharmony_ci // 2018fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 2019fd4e5da5Sopenharmony_ci // 2020fd4e5da5Sopenharmony_ci // float foo(vec4 bar) 2021fd4e5da5Sopenharmony_ci // { 2022fd4e5da5Sopenharmony_ci // return bar.x + bar.y; 2023fd4e5da5Sopenharmony_ci // } 2024fd4e5da5Sopenharmony_ci // 2025fd4e5da5Sopenharmony_ci // void main() 2026fd4e5da5Sopenharmony_ci // { 2027fd4e5da5Sopenharmony_ci // vec4 color = vec4(foo(BaseColor)); 2028fd4e5da5Sopenharmony_ci // gl_FragColor = color; 2029fd4e5da5Sopenharmony_ci // } 2030fd4e5da5Sopenharmony_ci 2031fd4e5da5Sopenharmony_ci const std::string predefs = 2032fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2033fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2034fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2035fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 2036fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2037fd4e5da5Sopenharmony_ciOpSource GLSL 140 2038fd4e5da5Sopenharmony_ciOpName %main "main" 2039fd4e5da5Sopenharmony_ciOpName %foo_vf4_ "foo(vf4;" 2040fd4e5da5Sopenharmony_ciOpName %bar "bar" 2041fd4e5da5Sopenharmony_ciOpName %color "color" 2042fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 2043fd4e5da5Sopenharmony_ciOpName %param "param" 2044fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 2045fd4e5da5Sopenharmony_ciOpDecorate %foo_vf4_ RelaxedPrecision 2046fd4e5da5Sopenharmony_ci)"; 2047fd4e5da5Sopenharmony_ci 2048fd4e5da5Sopenharmony_ci const std::string before = 2049fd4e5da5Sopenharmony_ci R"(%void = OpTypeVoid 2050fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void 2051fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 2052fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 2053fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 2054fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %float %_ptr_Function_v4float 2055fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 2056fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 2057fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 2058fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 2059fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 2060fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 2061fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 2062fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 2063fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10 2064fd4e5da5Sopenharmony_ci%21 = OpLabel 2065fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function 2066fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function 2067fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %BaseColor 2068fd4e5da5Sopenharmony_ciOpStore %param %22 2069fd4e5da5Sopenharmony_ci%23 = OpFunctionCall %float %foo_vf4_ %param 2070fd4e5da5Sopenharmony_ci%24 = OpCompositeConstruct %v4float %23 %23 %23 %23 2071fd4e5da5Sopenharmony_ciOpStore %color %24 2072fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %color 2073fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %25 2074fd4e5da5Sopenharmony_ciOpReturn 2075fd4e5da5Sopenharmony_ciOpFunctionEnd 2076fd4e5da5Sopenharmony_ci)"; 2077fd4e5da5Sopenharmony_ci 2078fd4e5da5Sopenharmony_ci const std::string after = 2079fd4e5da5Sopenharmony_ci R"(OpDecorate %32 RelaxedPrecision 2080fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2081fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void 2082fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 2083fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 2084fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 2085fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %float %_ptr_Function_v4float 2086fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 2087fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 2088fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 2089fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 2090fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 2091fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 2092fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 2093fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 2094fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10 2095fd4e5da5Sopenharmony_ci%21 = OpLabel 2096fd4e5da5Sopenharmony_ci%32 = OpVariable %_ptr_Function_float Function 2097fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function 2098fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function 2099fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %BaseColor 2100fd4e5da5Sopenharmony_ciOpStore %param %22 2101fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Function_float %param %uint_0 2102fd4e5da5Sopenharmony_ci%35 = OpLoad %float %34 2103fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_float %param %uint_1 2104fd4e5da5Sopenharmony_ci%37 = OpLoad %float %36 2105fd4e5da5Sopenharmony_ci%38 = OpFAdd %float %35 %37 2106fd4e5da5Sopenharmony_ciOpStore %32 %38 2107fd4e5da5Sopenharmony_ci%23 = OpLoad %float %32 2108fd4e5da5Sopenharmony_ci%24 = OpCompositeConstruct %v4float %23 %23 %23 %23 2109fd4e5da5Sopenharmony_ciOpStore %color %24 2110fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %color 2111fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %25 2112fd4e5da5Sopenharmony_ciOpReturn 2113fd4e5da5Sopenharmony_ciOpFunctionEnd 2114fd4e5da5Sopenharmony_ci)"; 2115fd4e5da5Sopenharmony_ci 2116fd4e5da5Sopenharmony_ci const std::string nonEntryFuncs = 2117fd4e5da5Sopenharmony_ci R"(%foo_vf4_ = OpFunction %float None %14 2118fd4e5da5Sopenharmony_ci%bar = OpFunctionParameter %_ptr_Function_v4float 2119fd4e5da5Sopenharmony_ci%26 = OpLabel 2120fd4e5da5Sopenharmony_ci%27 = OpAccessChain %_ptr_Function_float %bar %uint_0 2121fd4e5da5Sopenharmony_ci%28 = OpLoad %float %27 2122fd4e5da5Sopenharmony_ci%29 = OpAccessChain %_ptr_Function_float %bar %uint_1 2123fd4e5da5Sopenharmony_ci%30 = OpLoad %float %29 2124fd4e5da5Sopenharmony_ci%31 = OpFAdd %float %28 %30 2125fd4e5da5Sopenharmony_ciOpReturnValue %31 2126fd4e5da5Sopenharmony_ciOpFunctionEnd 2127fd4e5da5Sopenharmony_ci)"; 2128fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(predefs + before + nonEntryFuncs, 2129fd4e5da5Sopenharmony_ci predefs + after + nonEntryFuncs, 2130fd4e5da5Sopenharmony_ci false, true); 2131fd4e5da5Sopenharmony_ci} 2132fd4e5da5Sopenharmony_ci 2133fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DeleteName) { 2134fd4e5da5Sopenharmony_ci // Test that the name of the result id of the call is deleted. 2135fd4e5da5Sopenharmony_ci const std::string before = 2136fd4e5da5Sopenharmony_ci R"( 2137fd4e5da5Sopenharmony_ci OpCapability Shader 2138fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2139fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 2140fd4e5da5Sopenharmony_ci OpName %main "main" 2141fd4e5da5Sopenharmony_ci OpName %main_entry "main_entry" 2142fd4e5da5Sopenharmony_ci OpName %foo_result "foo_result" 2143fd4e5da5Sopenharmony_ci OpName %void_fn "void_fn" 2144fd4e5da5Sopenharmony_ci OpName %foo "foo" 2145fd4e5da5Sopenharmony_ci OpName %foo_entry "foo_entry" 2146fd4e5da5Sopenharmony_ci %void = OpTypeVoid 2147fd4e5da5Sopenharmony_ci %void_fn = OpTypeFunction %void 2148fd4e5da5Sopenharmony_ci %foo = OpFunction %void None %void_fn 2149fd4e5da5Sopenharmony_ci %foo_entry = OpLabel 2150fd4e5da5Sopenharmony_ci OpReturn 2151fd4e5da5Sopenharmony_ci OpFunctionEnd 2152fd4e5da5Sopenharmony_ci %main = OpFunction %void None %void_fn 2153fd4e5da5Sopenharmony_ci %main_entry = OpLabel 2154fd4e5da5Sopenharmony_ci %foo_result = OpFunctionCall %void %foo 2155fd4e5da5Sopenharmony_ci OpReturn 2156fd4e5da5Sopenharmony_ci OpFunctionEnd 2157fd4e5da5Sopenharmony_ci)"; 2158fd4e5da5Sopenharmony_ci 2159fd4e5da5Sopenharmony_ci const std::string after = 2160fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2161fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2162fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 2163fd4e5da5Sopenharmony_ciOpName %main "main" 2164fd4e5da5Sopenharmony_ciOpName %main_entry "main_entry" 2165fd4e5da5Sopenharmony_ciOpName %void_fn "void_fn" 2166fd4e5da5Sopenharmony_ciOpName %foo "foo" 2167fd4e5da5Sopenharmony_ciOpName %foo_entry "foo_entry" 2168fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2169fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 2170fd4e5da5Sopenharmony_ci%foo = OpFunction %void None %void_fn 2171fd4e5da5Sopenharmony_ci%foo_entry = OpLabel 2172fd4e5da5Sopenharmony_ciOpReturn 2173fd4e5da5Sopenharmony_ciOpFunctionEnd 2174fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 2175fd4e5da5Sopenharmony_ci%main_entry = OpLabel 2176fd4e5da5Sopenharmony_ciOpReturn 2177fd4e5da5Sopenharmony_ciOpFunctionEnd 2178fd4e5da5Sopenharmony_ci)"; 2179fd4e5da5Sopenharmony_ci 2180fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(before, after, false, true); 2181fd4e5da5Sopenharmony_ci} 2182fd4e5da5Sopenharmony_ci 2183fd4e5da5Sopenharmony_ciTEST_F(InlineTest, SetParent) { 2184fd4e5da5Sopenharmony_ci // Test that after inlining all basic blocks have the correct parent. 2185fd4e5da5Sopenharmony_ci const std::string text = 2186fd4e5da5Sopenharmony_ci R"( 2187fd4e5da5Sopenharmony_ci OpCapability Shader 2188fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2189fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 2190fd4e5da5Sopenharmony_ci OpName %main "main" 2191fd4e5da5Sopenharmony_ci OpName %main_entry "main_entry" 2192fd4e5da5Sopenharmony_ci OpName %foo_result "foo_result" 2193fd4e5da5Sopenharmony_ci OpName %void_fn "void_fn" 2194fd4e5da5Sopenharmony_ci OpName %foo "foo" 2195fd4e5da5Sopenharmony_ci OpName %foo_entry "foo_entry" 2196fd4e5da5Sopenharmony_ci %void = OpTypeVoid 2197fd4e5da5Sopenharmony_ci %void_fn = OpTypeFunction %void 2198fd4e5da5Sopenharmony_ci %foo = OpFunction %void None %void_fn 2199fd4e5da5Sopenharmony_ci %foo_entry = OpLabel 2200fd4e5da5Sopenharmony_ci OpReturn 2201fd4e5da5Sopenharmony_ci OpFunctionEnd 2202fd4e5da5Sopenharmony_ci %main = OpFunction %void None %void_fn 2203fd4e5da5Sopenharmony_ci %main_entry = OpLabel 2204fd4e5da5Sopenharmony_ci %foo_result = OpFunctionCall %void %foo 2205fd4e5da5Sopenharmony_ci OpReturn 2206fd4e5da5Sopenharmony_ci OpFunctionEnd 2207fd4e5da5Sopenharmony_ci)"; 2208fd4e5da5Sopenharmony_ci 2209fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> context = 2210fd4e5da5Sopenharmony_ci BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 2211fd4e5da5Sopenharmony_ci InlineExhaustivePass pass; 2212fd4e5da5Sopenharmony_ci pass.Run(context.get()); 2213fd4e5da5Sopenharmony_ci 2214fd4e5da5Sopenharmony_ci for (Function& func : *context->module()) { 2215fd4e5da5Sopenharmony_ci for (BasicBlock& bb : func) { 2216fd4e5da5Sopenharmony_ci EXPECT_TRUE(bb.GetParent() == &func); 2217fd4e5da5Sopenharmony_ci } 2218fd4e5da5Sopenharmony_ci } 2219fd4e5da5Sopenharmony_ci} 2220fd4e5da5Sopenharmony_ci 2221fd4e5da5Sopenharmony_ciTEST_F(InlineTest, OpVariableWithInit) { 2222fd4e5da5Sopenharmony_ci // Check that there is a store that corresponds to the initializer. This 2223fd4e5da5Sopenharmony_ci // test makes sure that is a store to the variable in the loop and before any 2224fd4e5da5Sopenharmony_ci // load. 2225fd4e5da5Sopenharmony_ci const std::string text = R"( 2226fd4e5da5Sopenharmony_ci; CHECK: OpFunction 2227fd4e5da5Sopenharmony_ci; CHECK-NOT: OpFunctionEnd 2228fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable %_ptr_Function_float Function %float_0 2229fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[outer_merge:%\w+]] 2230fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLoad %float [[var]] 2231fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var]] %float_0 2232fd4e5da5Sopenharmony_ci; CHECK: OpFunctionEnd 2233fd4e5da5Sopenharmony_ci OpCapability Shader 2234fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2235fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2236fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %o 2237fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 2238fd4e5da5Sopenharmony_ci OpSource GLSL 450 2239fd4e5da5Sopenharmony_ci OpDecorate %o Location 0 2240fd4e5da5Sopenharmony_ci %void = OpTypeVoid 2241fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %void 2242fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 2243fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %float 2244fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 2245fd4e5da5Sopenharmony_ci %float_0 = OpConstant %float 0 2246fd4e5da5Sopenharmony_ci %bool = OpTypeBool 2247fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 2248fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float 2249fd4e5da5Sopenharmony_ci %o = OpVariable %_ptr_Output_float Output 2250fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 2251fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 2252fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int 2253fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 2254fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 2255fd4e5da5Sopenharmony_ci %int_2 = OpConstant %int 2 2256fd4e5da5Sopenharmony_ci %main = OpFunction %void None %3 2257fd4e5da5Sopenharmony_ci %5 = OpLabel 2258fd4e5da5Sopenharmony_ci OpStore %o %float_0 2259fd4e5da5Sopenharmony_ci OpBranch %34 2260fd4e5da5Sopenharmony_ci %34 = OpLabel 2261fd4e5da5Sopenharmony_ci %39 = OpPhi %int %int_0 %5 %47 %37 2262fd4e5da5Sopenharmony_ci OpLoopMerge %36 %37 None 2263fd4e5da5Sopenharmony_ci OpBranch %38 2264fd4e5da5Sopenharmony_ci %38 = OpLabel 2265fd4e5da5Sopenharmony_ci %41 = OpSLessThan %bool %39 %int_2 2266fd4e5da5Sopenharmony_ci OpBranchConditional %41 %35 %36 2267fd4e5da5Sopenharmony_ci %35 = OpLabel 2268fd4e5da5Sopenharmony_ci %42 = OpFunctionCall %float %foo_ 2269fd4e5da5Sopenharmony_ci %43 = OpLoad %float %o 2270fd4e5da5Sopenharmony_ci %44 = OpFAdd %float %43 %42 2271fd4e5da5Sopenharmony_ci OpStore %o %44 2272fd4e5da5Sopenharmony_ci OpBranch %37 2273fd4e5da5Sopenharmony_ci %37 = OpLabel 2274fd4e5da5Sopenharmony_ci %47 = OpIAdd %int %39 %int_1 2275fd4e5da5Sopenharmony_ci OpBranch %34 2276fd4e5da5Sopenharmony_ci %36 = OpLabel 2277fd4e5da5Sopenharmony_ci OpReturn 2278fd4e5da5Sopenharmony_ci OpFunctionEnd 2279fd4e5da5Sopenharmony_ci %foo_ = OpFunction %float None %7 2280fd4e5da5Sopenharmony_ci %9 = OpLabel 2281fd4e5da5Sopenharmony_ci %n = OpVariable %_ptr_Function_float Function %float_0 2282fd4e5da5Sopenharmony_ci %13 = OpLoad %float %n 2283fd4e5da5Sopenharmony_ci %15 = OpFOrdEqual %bool %13 %float_0 2284fd4e5da5Sopenharmony_ci OpSelectionMerge %17 None 2285fd4e5da5Sopenharmony_ci OpBranchConditional %15 %16 %17 2286fd4e5da5Sopenharmony_ci %16 = OpLabel 2287fd4e5da5Sopenharmony_ci %19 = OpLoad %float %n 2288fd4e5da5Sopenharmony_ci %20 = OpFAdd %float %19 %float_1 2289fd4e5da5Sopenharmony_ci OpStore %n %20 2290fd4e5da5Sopenharmony_ci OpBranch %17 2291fd4e5da5Sopenharmony_ci %17 = OpLabel 2292fd4e5da5Sopenharmony_ci %21 = OpLoad %float %n 2293fd4e5da5Sopenharmony_ci OpReturnValue %21 2294fd4e5da5Sopenharmony_ci OpFunctionEnd 2295fd4e5da5Sopenharmony_ci)"; 2296fd4e5da5Sopenharmony_ci 2297fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 2298fd4e5da5Sopenharmony_ci} 2299fd4e5da5Sopenharmony_ci 2300fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DontInlineDirectlyRecursiveFunc) { 2301fd4e5da5Sopenharmony_ci // Test that the name of the result id of the call is deleted. 2302fd4e5da5Sopenharmony_ci const std::string test = 2303fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2304fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2305fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "main" 2306fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 2307fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2308fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 2309fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 2310fd4e5da5Sopenharmony_ci%_struct_6 = OpTypeStruct %float %float 2311fd4e5da5Sopenharmony_ci%15 = OpConstantNull %_struct_6 2312fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %_struct_6 2313fd4e5da5Sopenharmony_ci%1 = OpFunction %void Pure|Const %4 2314fd4e5da5Sopenharmony_ci%8 = OpLabel 2315fd4e5da5Sopenharmony_ci%2 = OpFunctionCall %_struct_6 %9 2316fd4e5da5Sopenharmony_ciOpKill 2317fd4e5da5Sopenharmony_ciOpFunctionEnd 2318fd4e5da5Sopenharmony_ci%9 = OpFunction %_struct_6 None %7 2319fd4e5da5Sopenharmony_ci%10 = OpLabel 2320fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %_struct_6 %9 2321fd4e5da5Sopenharmony_ciOpReturnValue %15 2322fd4e5da5Sopenharmony_ciOpFunctionEnd 2323fd4e5da5Sopenharmony_ci)"; 2324fd4e5da5Sopenharmony_ci 2325fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2326fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true); 2327fd4e5da5Sopenharmony_ci} 2328fd4e5da5Sopenharmony_ci 2329fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DontInlineInDirectlyRecursiveFunc) { 2330fd4e5da5Sopenharmony_ci // Test that the name of the result id of the call is deleted. 2331fd4e5da5Sopenharmony_ci const std::string test = 2332fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2333fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2334fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "main" 2335fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 2336fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2337fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 2338fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 2339fd4e5da5Sopenharmony_ci%_struct_6 = OpTypeStruct %float %float 2340fd4e5da5Sopenharmony_ci%15 = OpConstantNull %_struct_6 2341fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %_struct_6 2342fd4e5da5Sopenharmony_ci%1 = OpFunction %void Pure|Const %4 2343fd4e5da5Sopenharmony_ci%8 = OpLabel 2344fd4e5da5Sopenharmony_ci%2 = OpFunctionCall %_struct_6 %9 2345fd4e5da5Sopenharmony_ciOpKill 2346fd4e5da5Sopenharmony_ciOpFunctionEnd 2347fd4e5da5Sopenharmony_ci%9 = OpFunction %_struct_6 None %7 2348fd4e5da5Sopenharmony_ci%10 = OpLabel 2349fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %_struct_6 %12 2350fd4e5da5Sopenharmony_ciOpReturnValue %15 2351fd4e5da5Sopenharmony_ciOpFunctionEnd 2352fd4e5da5Sopenharmony_ci%12 = OpFunction %_struct_6 None %7 2353fd4e5da5Sopenharmony_ci%13 = OpLabel 2354fd4e5da5Sopenharmony_ci%14 = OpFunctionCall %_struct_6 %9 2355fd4e5da5Sopenharmony_ciOpReturnValue %15 2356fd4e5da5Sopenharmony_ciOpFunctionEnd 2357fd4e5da5Sopenharmony_ci)"; 2358fd4e5da5Sopenharmony_ci 2359fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2360fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true); 2361fd4e5da5Sopenharmony_ci} 2362fd4e5da5Sopenharmony_ci 2363fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DontInlineFuncWithOpKillInContinue) { 2364fd4e5da5Sopenharmony_ci const std::string test = 2365fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2366fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2367fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2368fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2369fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2370fd4e5da5Sopenharmony_ciOpSource GLSL 330 2371fd4e5da5Sopenharmony_ciOpName %main "main" 2372fd4e5da5Sopenharmony_ciOpName %kill_ "kill(" 2373fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2374fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 2375fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2376fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2377fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 2378fd4e5da5Sopenharmony_ci%5 = OpLabel 2379fd4e5da5Sopenharmony_ciOpBranch %9 2380fd4e5da5Sopenharmony_ci%9 = OpLabel 2381fd4e5da5Sopenharmony_ciOpLoopMerge %11 %12 None 2382fd4e5da5Sopenharmony_ciOpBranch %13 2383fd4e5da5Sopenharmony_ci%13 = OpLabel 2384fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %11 2385fd4e5da5Sopenharmony_ci%10 = OpLabel 2386fd4e5da5Sopenharmony_ciOpBranch %12 2387fd4e5da5Sopenharmony_ci%12 = OpLabel 2388fd4e5da5Sopenharmony_ci%16 = OpFunctionCall %void %kill_ 2389fd4e5da5Sopenharmony_ciOpBranch %9 2390fd4e5da5Sopenharmony_ci%11 = OpLabel 2391fd4e5da5Sopenharmony_ciOpReturn 2392fd4e5da5Sopenharmony_ciOpFunctionEnd 2393fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3 2394fd4e5da5Sopenharmony_ci%7 = OpLabel 2395fd4e5da5Sopenharmony_ciOpKill 2396fd4e5da5Sopenharmony_ciOpFunctionEnd 2397fd4e5da5Sopenharmony_ci)"; 2398fd4e5da5Sopenharmony_ci 2399fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2400fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true); 2401fd4e5da5Sopenharmony_ci} 2402fd4e5da5Sopenharmony_ci 2403fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DontInlineFuncWithDontInline) { 2404fd4e5da5Sopenharmony_ci // Check that the function with DontInline flag is not inlined. 2405fd4e5da5Sopenharmony_ci const std::string text = R"( 2406fd4e5da5Sopenharmony_ci; CHECK: %foo = OpFunction %int DontInline 2407fd4e5da5Sopenharmony_ci; CHECK: OpReturnValue %int_0 2408fd4e5da5Sopenharmony_ci 2409fd4e5da5Sopenharmony_ciOpCapability Shader 2410fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2411fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2412fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2413fd4e5da5Sopenharmony_ciOpSource HLSL 600 2414fd4e5da5Sopenharmony_ciOpName %main "main" 2415fd4e5da5Sopenharmony_ciOpName %foo "foo" 2416fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 2417fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 2418fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2419fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void 2420fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %int 2421fd4e5da5Sopenharmony_ci%main = OpFunction %void None %6 2422fd4e5da5Sopenharmony_ci%8 = OpLabel 2423fd4e5da5Sopenharmony_ci%9 = OpFunctionCall %int %foo 2424fd4e5da5Sopenharmony_ciOpReturn 2425fd4e5da5Sopenharmony_ciOpFunctionEnd 2426fd4e5da5Sopenharmony_ci%foo = OpFunction %int DontInline %7 2427fd4e5da5Sopenharmony_ci%10 = OpLabel 2428fd4e5da5Sopenharmony_ciOpReturnValue %int_0 2429fd4e5da5Sopenharmony_ciOpFunctionEnd 2430fd4e5da5Sopenharmony_ci)"; 2431fd4e5da5Sopenharmony_ci 2432fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 2433fd4e5da5Sopenharmony_ci} 2434fd4e5da5Sopenharmony_ci 2435fd4e5da5Sopenharmony_ciTEST_F(InlineTest, InlineFuncWithOpKillNotInContinue) { 2436fd4e5da5Sopenharmony_ci const std::string before = 2437fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2438fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2439fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2440fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2441fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2442fd4e5da5Sopenharmony_ciOpSource GLSL 330 2443fd4e5da5Sopenharmony_ciOpName %main "main" 2444fd4e5da5Sopenharmony_ciOpName %kill_ "kill(" 2445fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2446fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 2447fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2448fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2449fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 2450fd4e5da5Sopenharmony_ci%5 = OpLabel 2451fd4e5da5Sopenharmony_ci%16 = OpFunctionCall %void %kill_ 2452fd4e5da5Sopenharmony_ciOpReturn 2453fd4e5da5Sopenharmony_ciOpFunctionEnd 2454fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3 2455fd4e5da5Sopenharmony_ci%7 = OpLabel 2456fd4e5da5Sopenharmony_ciOpKill 2457fd4e5da5Sopenharmony_ciOpFunctionEnd 2458fd4e5da5Sopenharmony_ci)"; 2459fd4e5da5Sopenharmony_ci 2460fd4e5da5Sopenharmony_ci const std::string after = 2461fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2462fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2463fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2464fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2465fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2466fd4e5da5Sopenharmony_ciOpSource GLSL 330 2467fd4e5da5Sopenharmony_ciOpName %main "main" 2468fd4e5da5Sopenharmony_ciOpName %kill_ "kill(" 2469fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2470fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 2471fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2472fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2473fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 2474fd4e5da5Sopenharmony_ci%5 = OpLabel 2475fd4e5da5Sopenharmony_ciOpKill 2476fd4e5da5Sopenharmony_ci%18 = OpLabel 2477fd4e5da5Sopenharmony_ciOpReturn 2478fd4e5da5Sopenharmony_ciOpFunctionEnd 2479fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3 2480fd4e5da5Sopenharmony_ci%7 = OpLabel 2481fd4e5da5Sopenharmony_ciOpKill 2482fd4e5da5Sopenharmony_ciOpFunctionEnd 2483fd4e5da5Sopenharmony_ci)"; 2484fd4e5da5Sopenharmony_ci 2485fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2486fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(before, after, false, true); 2487fd4e5da5Sopenharmony_ci} 2488fd4e5da5Sopenharmony_ci 2489fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DontInlineFuncWithOpTerminateInvocationInContinue) { 2490fd4e5da5Sopenharmony_ci const std::string test = 2491fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2492fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_terminate_invocation" 2493fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2494fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2495fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2496fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2497fd4e5da5Sopenharmony_ciOpSource GLSL 330 2498fd4e5da5Sopenharmony_ciOpName %main "main" 2499fd4e5da5Sopenharmony_ciOpName %kill_ "kill(" 2500fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2501fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 2502fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2503fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2504fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 2505fd4e5da5Sopenharmony_ci%5 = OpLabel 2506fd4e5da5Sopenharmony_ciOpBranch %9 2507fd4e5da5Sopenharmony_ci%9 = OpLabel 2508fd4e5da5Sopenharmony_ciOpLoopMerge %11 %12 None 2509fd4e5da5Sopenharmony_ciOpBranch %13 2510fd4e5da5Sopenharmony_ci%13 = OpLabel 2511fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %11 2512fd4e5da5Sopenharmony_ci%10 = OpLabel 2513fd4e5da5Sopenharmony_ciOpBranch %12 2514fd4e5da5Sopenharmony_ci%12 = OpLabel 2515fd4e5da5Sopenharmony_ci%16 = OpFunctionCall %void %kill_ 2516fd4e5da5Sopenharmony_ciOpBranch %9 2517fd4e5da5Sopenharmony_ci%11 = OpLabel 2518fd4e5da5Sopenharmony_ciOpReturn 2519fd4e5da5Sopenharmony_ciOpFunctionEnd 2520fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3 2521fd4e5da5Sopenharmony_ci%7 = OpLabel 2522fd4e5da5Sopenharmony_ciOpTerminateInvocation 2523fd4e5da5Sopenharmony_ciOpFunctionEnd 2524fd4e5da5Sopenharmony_ci)"; 2525fd4e5da5Sopenharmony_ci 2526fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2527fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true); 2528fd4e5da5Sopenharmony_ci} 2529fd4e5da5Sopenharmony_ci 2530fd4e5da5Sopenharmony_ciTEST_F(InlineTest, InlineFuncWithOpTerminateInvocationNotInContinue) { 2531fd4e5da5Sopenharmony_ci const std::string before = 2532fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2533fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_terminate_invocation" 2534fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2535fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2536fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2537fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2538fd4e5da5Sopenharmony_ciOpSource GLSL 330 2539fd4e5da5Sopenharmony_ciOpName %main "main" 2540fd4e5da5Sopenharmony_ciOpName %kill_ "kill(" 2541fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2542fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 2543fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2544fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2545fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 2546fd4e5da5Sopenharmony_ci%5 = OpLabel 2547fd4e5da5Sopenharmony_ci%16 = OpFunctionCall %void %kill_ 2548fd4e5da5Sopenharmony_ciOpReturn 2549fd4e5da5Sopenharmony_ciOpFunctionEnd 2550fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3 2551fd4e5da5Sopenharmony_ci%7 = OpLabel 2552fd4e5da5Sopenharmony_ciOpTerminateInvocation 2553fd4e5da5Sopenharmony_ciOpFunctionEnd 2554fd4e5da5Sopenharmony_ci)"; 2555fd4e5da5Sopenharmony_ci 2556fd4e5da5Sopenharmony_ci const std::string after = 2557fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2558fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_terminate_invocation" 2559fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2560fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2561fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2562fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2563fd4e5da5Sopenharmony_ciOpSource GLSL 330 2564fd4e5da5Sopenharmony_ciOpName %main "main" 2565fd4e5da5Sopenharmony_ciOpName %kill_ "kill(" 2566fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2567fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 2568fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2569fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2570fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 2571fd4e5da5Sopenharmony_ci%5 = OpLabel 2572fd4e5da5Sopenharmony_ciOpTerminateInvocation 2573fd4e5da5Sopenharmony_ci%18 = OpLabel 2574fd4e5da5Sopenharmony_ciOpReturn 2575fd4e5da5Sopenharmony_ciOpFunctionEnd 2576fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3 2577fd4e5da5Sopenharmony_ci%7 = OpLabel 2578fd4e5da5Sopenharmony_ciOpTerminateInvocation 2579fd4e5da5Sopenharmony_ciOpFunctionEnd 2580fd4e5da5Sopenharmony_ci)"; 2581fd4e5da5Sopenharmony_ci 2582fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2583fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(before, after, false, true); 2584fd4e5da5Sopenharmony_ci} 2585fd4e5da5Sopenharmony_ci 2586fd4e5da5Sopenharmony_ciTEST_F(InlineTest, InlineForLinkage) { 2587fd4e5da5Sopenharmony_ci const std::string before = 2588fd4e5da5Sopenharmony_ci R"(OpCapability SampledBuffer 2589fd4e5da5Sopenharmony_ciOpCapability ImageBuffer 2590fd4e5da5Sopenharmony_ciOpCapability Shader 2591fd4e5da5Sopenharmony_ciOpCapability Linkage 2592fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2593fd4e5da5Sopenharmony_ciOpSource HLSL 630 2594fd4e5da5Sopenharmony_ciOpName %type_buffer_image "type.buffer.image" 2595fd4e5da5Sopenharmony_ciOpName %output "output" 2596fd4e5da5Sopenharmony_ciOpName %main "main" 2597fd4e5da5Sopenharmony_ciOpName %color "color" 2598fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry" 2599fd4e5da5Sopenharmony_ciOpName %param_var_color "param.var.color" 2600fd4e5da5Sopenharmony_ciOpName %fn "fn" 2601fd4e5da5Sopenharmony_ciOpName %color_0 "color" 2602fd4e5da5Sopenharmony_ciOpName %bb_entry_0 "bb.entry" 2603fd4e5da5Sopenharmony_ciOpName %v "v" 2604fd4e5da5Sopenharmony_ciOpDecorate %main LinkageAttributes "main" Export 2605fd4e5da5Sopenharmony_ciOpDecorate %output DescriptorSet 0 2606fd4e5da5Sopenharmony_ciOpDecorate %output Binding 1 2607fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 2608fd4e5da5Sopenharmony_ci%float_0_200000003 = OpConstant %float 0.200000003 2609fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 2610fd4e5da5Sopenharmony_ci%6 = OpConstantComposite %v4float %float_0_200000003 %float_0_200000003 %float_0_200000003 %float_0_200000003 2611fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 2612fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 2613fd4e5da5Sopenharmony_ci%type_buffer_image = OpTypeImage %float Buffer 2 0 0 2 Rgba32f 2614fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image 2615fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 2616fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %float %_ptr_Function_v4float 2617fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 2618fd4e5da5Sopenharmony_ci%output = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant 2619fd4e5da5Sopenharmony_ci%main = OpFunction %float None %11 2620fd4e5da5Sopenharmony_ci%color = OpFunctionParameter %_ptr_Function_v4float 2621fd4e5da5Sopenharmony_ci%bb_entry = OpLabel 2622fd4e5da5Sopenharmony_ci%param_var_color = OpVariable %_ptr_Function_v4float Function 2623fd4e5da5Sopenharmony_ci%16 = OpLoad %v4float %color 2624fd4e5da5Sopenharmony_ciOpStore %param_var_color %16 2625fd4e5da5Sopenharmony_ci%17 = OpFunctionCall %float %fn %param_var_color 2626fd4e5da5Sopenharmony_ciOpReturnValue %17 2627fd4e5da5Sopenharmony_ciOpFunctionEnd 2628fd4e5da5Sopenharmony_ci%fn = OpFunction %float None %11 2629fd4e5da5Sopenharmony_ci%color_0 = OpFunctionParameter %_ptr_Function_v4float 2630fd4e5da5Sopenharmony_ci%bb_entry_0 = OpLabel 2631fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 2632fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %color_0 2633fd4e5da5Sopenharmony_ciOpStore %v %22 2634fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 2635fd4e5da5Sopenharmony_ci%24 = OpFMul %v4float %23 %6 2636fd4e5da5Sopenharmony_ciOpStore %v %24 2637fd4e5da5Sopenharmony_ci%26 = OpAccessChain %_ptr_Function_float %v %int_0 2638fd4e5da5Sopenharmony_ci%27 = OpLoad %float %26 2639fd4e5da5Sopenharmony_ciOpReturnValue %27 2640fd4e5da5Sopenharmony_ciOpFunctionEnd 2641fd4e5da5Sopenharmony_ci )"; 2642fd4e5da5Sopenharmony_ci 2643fd4e5da5Sopenharmony_ci const std::string after = 2644fd4e5da5Sopenharmony_ci R"(OpCapability SampledBuffer 2645fd4e5da5Sopenharmony_ciOpCapability ImageBuffer 2646fd4e5da5Sopenharmony_ciOpCapability Shader 2647fd4e5da5Sopenharmony_ciOpCapability Linkage 2648fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2649fd4e5da5Sopenharmony_ciOpSource HLSL 630 2650fd4e5da5Sopenharmony_ciOpName %type_buffer_image "type.buffer.image" 2651fd4e5da5Sopenharmony_ciOpName %output "output" 2652fd4e5da5Sopenharmony_ciOpName %main "main" 2653fd4e5da5Sopenharmony_ciOpName %color "color" 2654fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry" 2655fd4e5da5Sopenharmony_ciOpName %param_var_color "param.var.color" 2656fd4e5da5Sopenharmony_ciOpName %fn "fn" 2657fd4e5da5Sopenharmony_ciOpName %color_0 "color" 2658fd4e5da5Sopenharmony_ciOpName %bb_entry_0 "bb.entry" 2659fd4e5da5Sopenharmony_ciOpName %v "v" 2660fd4e5da5Sopenharmony_ciOpDecorate %main LinkageAttributes "main" Export 2661fd4e5da5Sopenharmony_ciOpDecorate %output DescriptorSet 0 2662fd4e5da5Sopenharmony_ciOpDecorate %output Binding 1 2663fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 2664fd4e5da5Sopenharmony_ci%float_0_200000003 = OpConstant %float 0.200000003 2665fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 2666fd4e5da5Sopenharmony_ci%6 = OpConstantComposite %v4float %float_0_200000003 %float_0_200000003 %float_0_200000003 %float_0_200000003 2667fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 2668fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 2669fd4e5da5Sopenharmony_ci%type_buffer_image = OpTypeImage %float Buffer 2 0 0 2 Rgba32f 2670fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image 2671fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 2672fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %float %_ptr_Function_v4float 2673fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 2674fd4e5da5Sopenharmony_ci%output = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant 2675fd4e5da5Sopenharmony_ci%main = OpFunction %float None %11 2676fd4e5da5Sopenharmony_ci%color = OpFunctionParameter %_ptr_Function_v4float 2677fd4e5da5Sopenharmony_ci%bb_entry = OpLabel 2678fd4e5da5Sopenharmony_ci%28 = OpVariable %_ptr_Function_v4float Function 2679fd4e5da5Sopenharmony_ci%29 = OpVariable %_ptr_Function_float Function 2680fd4e5da5Sopenharmony_ci%param_var_color = OpVariable %_ptr_Function_v4float Function 2681fd4e5da5Sopenharmony_ci%16 = OpLoad %v4float %color 2682fd4e5da5Sopenharmony_ciOpStore %param_var_color %16 2683fd4e5da5Sopenharmony_ci%31 = OpLoad %v4float %param_var_color 2684fd4e5da5Sopenharmony_ciOpStore %28 %31 2685fd4e5da5Sopenharmony_ci%32 = OpLoad %v4float %28 2686fd4e5da5Sopenharmony_ci%33 = OpFMul %v4float %32 %6 2687fd4e5da5Sopenharmony_ciOpStore %28 %33 2688fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Function_float %28 %int_0 2689fd4e5da5Sopenharmony_ci%35 = OpLoad %float %34 2690fd4e5da5Sopenharmony_ciOpStore %29 %35 2691fd4e5da5Sopenharmony_ci%17 = OpLoad %float %29 2692fd4e5da5Sopenharmony_ciOpReturnValue %17 2693fd4e5da5Sopenharmony_ciOpFunctionEnd 2694fd4e5da5Sopenharmony_ci%fn = OpFunction %float None %11 2695fd4e5da5Sopenharmony_ci%color_0 = OpFunctionParameter %_ptr_Function_v4float 2696fd4e5da5Sopenharmony_ci%bb_entry_0 = OpLabel 2697fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 2698fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %color_0 2699fd4e5da5Sopenharmony_ciOpStore %v %22 2700fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 2701fd4e5da5Sopenharmony_ci%24 = OpFMul %v4float %23 %6 2702fd4e5da5Sopenharmony_ciOpStore %v %24 2703fd4e5da5Sopenharmony_ci%26 = OpAccessChain %_ptr_Function_float %v %int_0 2704fd4e5da5Sopenharmony_ci%27 = OpLoad %float %26 2705fd4e5da5Sopenharmony_ciOpReturnValue %27 2706fd4e5da5Sopenharmony_ciOpFunctionEnd 2707fd4e5da5Sopenharmony_ci)"; 2708fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2709fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<InlineExhaustivePass>(before, after, false, true); 2710fd4e5da5Sopenharmony_ci} 2711fd4e5da5Sopenharmony_ci 2712fd4e5da5Sopenharmony_ciTEST_F(InlineTest, InlineFuncWithOpTerminateRayNotInContinue) { 2713fd4e5da5Sopenharmony_ci const std::string text = 2714fd4e5da5Sopenharmony_ci R"( 2715fd4e5da5Sopenharmony_ci OpCapability RayTracingKHR 2716fd4e5da5Sopenharmony_ci OpExtension "SPV_KHR_ray_tracing" 2717fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2718fd4e5da5Sopenharmony_ci OpEntryPoint AnyHitKHR %MyAHitMain2 "MyAHitMain2" %a 2719fd4e5da5Sopenharmony_ci OpSource HLSL 630 2720fd4e5da5Sopenharmony_ci OpName %a "a" 2721fd4e5da5Sopenharmony_ci OpName %MyAHitMain2 "MyAHitMain2" 2722fd4e5da5Sopenharmony_ci OpName %param_var_a "param.var.a" 2723fd4e5da5Sopenharmony_ci OpName %src_MyAHitMain2 "src.MyAHitMain2" 2724fd4e5da5Sopenharmony_ci OpName %a_0 "a" 2725fd4e5da5Sopenharmony_ci OpName %bb_entry "bb.entry" 2726fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 2727fd4e5da5Sopenharmony_ci%_ptr_IncomingRayPayloadKHR_int = OpTypePointer IncomingRayPayloadKHR %int 2728fd4e5da5Sopenharmony_ci %void = OpTypeVoid 2729fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %void 2730fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 2731fd4e5da5Sopenharmony_ci %14 = OpTypeFunction %void %_ptr_Function_int 2732fd4e5da5Sopenharmony_ci %a = OpVariable %_ptr_IncomingRayPayloadKHR_int IncomingRayPayloadKHR 2733fd4e5da5Sopenharmony_ci%MyAHitMain2 = OpFunction %void None %6 2734fd4e5da5Sopenharmony_ci %7 = OpLabel 2735fd4e5da5Sopenharmony_ci%param_var_a = OpVariable %_ptr_Function_int Function 2736fd4e5da5Sopenharmony_ci %10 = OpLoad %int %a 2737fd4e5da5Sopenharmony_ci OpStore %param_var_a %10 2738fd4e5da5Sopenharmony_ci %11 = OpFunctionCall %void %src_MyAHitMain2 %param_var_a 2739fd4e5da5Sopenharmony_ci %13 = OpLoad %int %param_var_a 2740fd4e5da5Sopenharmony_ci OpStore %a %13 2741fd4e5da5Sopenharmony_ci OpReturn 2742fd4e5da5Sopenharmony_ci OpFunctionEnd 2743fd4e5da5Sopenharmony_ci%src_MyAHitMain2 = OpFunction %void None %14 2744fd4e5da5Sopenharmony_ci %a_0 = OpFunctionParameter %_ptr_Function_int 2745fd4e5da5Sopenharmony_ci %bb_entry = OpLabel 2746fd4e5da5Sopenharmony_ci %17 = OpLoad %int %a_0 2747fd4e5da5Sopenharmony_ci OpStore %a %17 2748fd4e5da5Sopenharmony_ci OpTerminateRayKHR 2749fd4e5da5Sopenharmony_ci OpFunctionEnd 2750fd4e5da5Sopenharmony_ci 2751fd4e5da5Sopenharmony_ci; CHECK: %MyAHitMain2 = OpFunction %void None 2752fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 2753fd4e5da5Sopenharmony_ci; CHECK-NEXT: %param_var_a = OpVariable %_ptr_Function_int Function 2754fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoad %int %a 2755fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpStore %param_var_a {{%\d+}} 2756fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoad %int %param_var_a 2757fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpStore %a {{%\d+}} 2758fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpTerminateRayKHR 2759fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 2760fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoad %int %param_var_a 2761fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpStore %a %16 2762fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2763fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpFunctionEnd 2764fd4e5da5Sopenharmony_ci)"; 2765fd4e5da5Sopenharmony_ci 2766fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, false); 2767fd4e5da5Sopenharmony_ci} 2768fd4e5da5Sopenharmony_ci 2769fd4e5da5Sopenharmony_ciTEST_F(InlineTest, EarlyReturnFunctionInlined) { 2770fd4e5da5Sopenharmony_ci // #version 140 2771fd4e5da5Sopenharmony_ci // 2772fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 2773fd4e5da5Sopenharmony_ci // 2774fd4e5da5Sopenharmony_ci // float foo(vec4 bar) 2775fd4e5da5Sopenharmony_ci // { 2776fd4e5da5Sopenharmony_ci // if (bar.x < 0.0) 2777fd4e5da5Sopenharmony_ci // return 0.0; 2778fd4e5da5Sopenharmony_ci // return bar.x; 2779fd4e5da5Sopenharmony_ci // } 2780fd4e5da5Sopenharmony_ci // 2781fd4e5da5Sopenharmony_ci // void main() 2782fd4e5da5Sopenharmony_ci // { 2783fd4e5da5Sopenharmony_ci // vec4 color = vec4(foo(BaseColor)); 2784fd4e5da5Sopenharmony_ci // gl_FragColor = color; 2785fd4e5da5Sopenharmony_ci // } 2786fd4e5da5Sopenharmony_ci 2787fd4e5da5Sopenharmony_ci const std::string predefs = 2788fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2789fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2790fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2791fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 2792fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2793fd4e5da5Sopenharmony_ciOpSource GLSL 140 2794fd4e5da5Sopenharmony_ciOpName %main "main" 2795fd4e5da5Sopenharmony_ciOpName %foo_vf4_ "foo(vf4;" 2796fd4e5da5Sopenharmony_ciOpName %bar "bar" 2797fd4e5da5Sopenharmony_ciOpName %color "color" 2798fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 2799fd4e5da5Sopenharmony_ciOpName %param "param" 2800fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 2801fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2802fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void 2803fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 2804fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 2805fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 2806fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %float %_ptr_Function_v4float 2807fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 2808fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 2809fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 2810fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 2811fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2812fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 2813fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 2814fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 2815fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 2816fd4e5da5Sopenharmony_ci)"; 2817fd4e5da5Sopenharmony_ci 2818fd4e5da5Sopenharmony_ci const std::string foo = 2819fd4e5da5Sopenharmony_ci R"(%foo_vf4_ = OpFunction %float None %14 2820fd4e5da5Sopenharmony_ci%bar = OpFunctionParameter %_ptr_Function_v4float 2821fd4e5da5Sopenharmony_ci%27 = OpLabel 2822fd4e5da5Sopenharmony_ci%28 = OpAccessChain %_ptr_Function_float %bar %uint_0 2823fd4e5da5Sopenharmony_ci%29 = OpLoad %float %28 2824fd4e5da5Sopenharmony_ci%30 = OpFOrdLessThan %bool %29 %float_0 2825fd4e5da5Sopenharmony_ciOpSelectionMerge %31 None 2826fd4e5da5Sopenharmony_ciOpBranchConditional %30 %32 %31 2827fd4e5da5Sopenharmony_ci%32 = OpLabel 2828fd4e5da5Sopenharmony_ciOpReturnValue %float_0 2829fd4e5da5Sopenharmony_ci%31 = OpLabel 2830fd4e5da5Sopenharmony_ci%33 = OpAccessChain %_ptr_Function_float %bar %uint_0 2831fd4e5da5Sopenharmony_ci%34 = OpLoad %float %33 2832fd4e5da5Sopenharmony_ciOpReturnValue %34 2833fd4e5da5Sopenharmony_ciOpFunctionEnd 2834fd4e5da5Sopenharmony_ci)"; 2835fd4e5da5Sopenharmony_ci 2836fd4e5da5Sopenharmony_ci const std::string fooMergeReturn = 2837fd4e5da5Sopenharmony_ci R"(%foo_vf4_ = OpFunction %float None %14 2838fd4e5da5Sopenharmony_ci%bar = OpFunctionParameter %_ptr_Function_v4float 2839fd4e5da5Sopenharmony_ci%27 = OpLabel 2840fd4e5da5Sopenharmony_ci%41 = OpVariable %_ptr_Function_bool Function %false 2841fd4e5da5Sopenharmony_ci%36 = OpVariable %_ptr_Function_float Function 2842fd4e5da5Sopenharmony_ciOpSelectionMerge %35 None 2843fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %38 2844fd4e5da5Sopenharmony_ci%38 = OpLabel 2845fd4e5da5Sopenharmony_ci%28 = OpAccessChain %_ptr_Function_float %bar %uint_0 2846fd4e5da5Sopenharmony_ci%29 = OpLoad %float %28 2847fd4e5da5Sopenharmony_ci%30 = OpFOrdLessThan %bool %29 %float_0 2848fd4e5da5Sopenharmony_ciOpSelectionMerge %31 None 2849fd4e5da5Sopenharmony_ciOpBranchConditional %30 %32 %31 2850fd4e5da5Sopenharmony_ci%32 = OpLabel 2851fd4e5da5Sopenharmony_ciOpStore %41 %true 2852fd4e5da5Sopenharmony_ciOpStore %36 %float_0 2853fd4e5da5Sopenharmony_ciOpBranch %35 2854fd4e5da5Sopenharmony_ci%31 = OpLabel 2855fd4e5da5Sopenharmony_ci%33 = OpAccessChain %_ptr_Function_float %bar %uint_0 2856fd4e5da5Sopenharmony_ci%34 = OpLoad %float %33 2857fd4e5da5Sopenharmony_ciOpStore %41 %true 2858fd4e5da5Sopenharmony_ciOpStore %36 %34 2859fd4e5da5Sopenharmony_ciOpBranch %35 2860fd4e5da5Sopenharmony_ci%35 = OpLabel 2861fd4e5da5Sopenharmony_ci%37 = OpLoad %float %36 2862fd4e5da5Sopenharmony_ciOpReturnValue %37 2863fd4e5da5Sopenharmony_ciOpFunctionEnd 2864fd4e5da5Sopenharmony_ci)"; 2865fd4e5da5Sopenharmony_ci 2866fd4e5da5Sopenharmony_ci const std::string before = 2867fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %10 2868fd4e5da5Sopenharmony_ci%22 = OpLabel 2869fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function 2870fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function 2871fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor 2872fd4e5da5Sopenharmony_ciOpStore %param %23 2873fd4e5da5Sopenharmony_ci%24 = OpFunctionCall %float %foo_vf4_ %param 2874fd4e5da5Sopenharmony_ci%25 = OpCompositeConstruct %v4float %24 %24 %24 %24 2875fd4e5da5Sopenharmony_ciOpStore %color %25 2876fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %color 2877fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %26 2878fd4e5da5Sopenharmony_ciOpReturn 2879fd4e5da5Sopenharmony_ciOpFunctionEnd 2880fd4e5da5Sopenharmony_ci)"; 2881fd4e5da5Sopenharmony_ci 2882fd4e5da5Sopenharmony_ci const std::string after = 2883fd4e5da5Sopenharmony_ci R"(%false = OpConstantFalse %bool 2884fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool 2885fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2886fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10 2887fd4e5da5Sopenharmony_ci%22 = OpLabel 2888fd4e5da5Sopenharmony_ci%43 = OpVariable %_ptr_Function_bool Function %false 2889fd4e5da5Sopenharmony_ci%44 = OpVariable %_ptr_Function_float Function 2890fd4e5da5Sopenharmony_ci%45 = OpVariable %_ptr_Function_float Function 2891fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function 2892fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function 2893fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor 2894fd4e5da5Sopenharmony_ciOpStore %param %23 2895fd4e5da5Sopenharmony_ciOpStore %43 %false 2896fd4e5da5Sopenharmony_ciOpSelectionMerge %55 None 2897fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %47 2898fd4e5da5Sopenharmony_ci%47 = OpLabel 2899fd4e5da5Sopenharmony_ci%48 = OpAccessChain %_ptr_Function_float %param %uint_0 2900fd4e5da5Sopenharmony_ci%49 = OpLoad %float %48 2901fd4e5da5Sopenharmony_ci%50 = OpFOrdLessThan %bool %49 %float_0 2902fd4e5da5Sopenharmony_ciOpSelectionMerge %52 None 2903fd4e5da5Sopenharmony_ciOpBranchConditional %50 %51 %52 2904fd4e5da5Sopenharmony_ci%51 = OpLabel 2905fd4e5da5Sopenharmony_ciOpStore %43 %true 2906fd4e5da5Sopenharmony_ciOpStore %44 %float_0 2907fd4e5da5Sopenharmony_ciOpBranch %55 2908fd4e5da5Sopenharmony_ci%52 = OpLabel 2909fd4e5da5Sopenharmony_ci%53 = OpAccessChain %_ptr_Function_float %param %uint_0 2910fd4e5da5Sopenharmony_ci%54 = OpLoad %float %53 2911fd4e5da5Sopenharmony_ciOpStore %43 %true 2912fd4e5da5Sopenharmony_ciOpStore %44 %54 2913fd4e5da5Sopenharmony_ciOpBranch %55 2914fd4e5da5Sopenharmony_ci%55 = OpLabel 2915fd4e5da5Sopenharmony_ci%56 = OpLoad %float %44 2916fd4e5da5Sopenharmony_ciOpStore %45 %56 2917fd4e5da5Sopenharmony_ci%24 = OpLoad %float %45 2918fd4e5da5Sopenharmony_ci%25 = OpCompositeConstruct %v4float %24 %24 %24 %24 2919fd4e5da5Sopenharmony_ciOpStore %color %25 2920fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %color 2921fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %26 2922fd4e5da5Sopenharmony_ciOpReturn 2923fd4e5da5Sopenharmony_ciOpFunctionEnd 2924fd4e5da5Sopenharmony_ci)"; 2925fd4e5da5Sopenharmony_ci 2926fd4e5da5Sopenharmony_ci // The early return case must be handled by merge-return first. 2927fd4e5da5Sopenharmony_ci AddPass<MergeReturnPass>(); 2928fd4e5da5Sopenharmony_ci AddPass<InlineExhaustivePass>(); 2929fd4e5da5Sopenharmony_ci RunAndCheck(predefs + before + foo, predefs + after + fooMergeReturn); 2930fd4e5da5Sopenharmony_ci} 2931fd4e5da5Sopenharmony_ci 2932fd4e5da5Sopenharmony_ciTEST_F(InlineTest, EarlyReturnNotAppearingLastInFunctionInlined) { 2933fd4e5da5Sopenharmony_ci // Example from https://github.com/KhronosGroup/SPIRV-Tools/issues/755 2934fd4e5da5Sopenharmony_ci // 2935fd4e5da5Sopenharmony_ci // Original example is derived from: 2936fd4e5da5Sopenharmony_ci // 2937fd4e5da5Sopenharmony_ci // #version 450 2938fd4e5da5Sopenharmony_ci // 2939fd4e5da5Sopenharmony_ci // float foo() { 2940fd4e5da5Sopenharmony_ci // if (true) { 2941fd4e5da5Sopenharmony_ci // } 2942fd4e5da5Sopenharmony_ci // } 2943fd4e5da5Sopenharmony_ci // 2944fd4e5da5Sopenharmony_ci // void main() { foo(); } 2945fd4e5da5Sopenharmony_ci // 2946fd4e5da5Sopenharmony_ci // But the order of basic blocks in foo is changed so that the return 2947fd4e5da5Sopenharmony_ci // block is listed second-last. There is only one return in the callee 2948fd4e5da5Sopenharmony_ci // but it does not appear last. 2949fd4e5da5Sopenharmony_ci 2950fd4e5da5Sopenharmony_ci const std::string predefs = 2951fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2952fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2953fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 2954fd4e5da5Sopenharmony_ciOpSource GLSL 450 2955fd4e5da5Sopenharmony_ciOpName %main "main" 2956fd4e5da5Sopenharmony_ciOpName %foo_ "foo(" 2957fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2958fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 2959fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2960fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2961fd4e5da5Sopenharmony_ci)"; 2962fd4e5da5Sopenharmony_ci 2963fd4e5da5Sopenharmony_ci const std::string foo = 2964fd4e5da5Sopenharmony_ci R"(%foo_ = OpFunction %void None %4 2965fd4e5da5Sopenharmony_ci%7 = OpLabel 2966fd4e5da5Sopenharmony_ciOpSelectionMerge %8 None 2967fd4e5da5Sopenharmony_ciOpBranchConditional %true %9 %8 2968fd4e5da5Sopenharmony_ci%8 = OpLabel 2969fd4e5da5Sopenharmony_ciOpReturn 2970fd4e5da5Sopenharmony_ci%9 = OpLabel 2971fd4e5da5Sopenharmony_ciOpBranch %8 2972fd4e5da5Sopenharmony_ciOpFunctionEnd 2973fd4e5da5Sopenharmony_ci)"; 2974fd4e5da5Sopenharmony_ci 2975fd4e5da5Sopenharmony_ci const std::string fooMergeReturn = 2976fd4e5da5Sopenharmony_ci R"(%uint = OpTypeInt 32 0 2977fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 2978fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 2979fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool 2980fd4e5da5Sopenharmony_ci%foo_ = OpFunction %void None %4 2981fd4e5da5Sopenharmony_ci%7 = OpLabel 2982fd4e5da5Sopenharmony_ci%18 = OpVariable %_ptr_Function_bool Function %false 2983fd4e5da5Sopenharmony_ciOpSelectionMerge %12 None 2984fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %13 2985fd4e5da5Sopenharmony_ci%13 = OpLabel 2986fd4e5da5Sopenharmony_ciOpSelectionMerge %8 None 2987fd4e5da5Sopenharmony_ciOpBranchConditional %true %9 %8 2988fd4e5da5Sopenharmony_ci%8 = OpLabel 2989fd4e5da5Sopenharmony_ciOpStore %18 %true 2990fd4e5da5Sopenharmony_ciOpBranch %12 2991fd4e5da5Sopenharmony_ci%9 = OpLabel 2992fd4e5da5Sopenharmony_ciOpBranch %8 2993fd4e5da5Sopenharmony_ci%12 = OpLabel 2994fd4e5da5Sopenharmony_ciOpReturn 2995fd4e5da5Sopenharmony_ciOpFunctionEnd 2996fd4e5da5Sopenharmony_ci)"; 2997fd4e5da5Sopenharmony_ci 2998fd4e5da5Sopenharmony_ci const std::string before = 2999fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %4 3000fd4e5da5Sopenharmony_ci%10 = OpLabel 3001fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %void %foo_ 3002fd4e5da5Sopenharmony_ciOpReturn 3003fd4e5da5Sopenharmony_ciOpFunctionEnd 3004fd4e5da5Sopenharmony_ci)"; 3005fd4e5da5Sopenharmony_ci 3006fd4e5da5Sopenharmony_ci const std::string after = 3007fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %4 3008fd4e5da5Sopenharmony_ci%10 = OpLabel 3009fd4e5da5Sopenharmony_ci%19 = OpVariable %_ptr_Function_bool Function %false 3010fd4e5da5Sopenharmony_ciOpStore %19 %false 3011fd4e5da5Sopenharmony_ciOpSelectionMerge %24 None 3012fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %21 3013fd4e5da5Sopenharmony_ci%21 = OpLabel 3014fd4e5da5Sopenharmony_ciOpSelectionMerge %22 None 3015fd4e5da5Sopenharmony_ciOpBranchConditional %true %23 %22 3016fd4e5da5Sopenharmony_ci%22 = OpLabel 3017fd4e5da5Sopenharmony_ciOpStore %19 %true 3018fd4e5da5Sopenharmony_ciOpBranch %24 3019fd4e5da5Sopenharmony_ci%23 = OpLabel 3020fd4e5da5Sopenharmony_ciOpBranch %22 3021fd4e5da5Sopenharmony_ci%24 = OpLabel 3022fd4e5da5Sopenharmony_ciOpReturn 3023fd4e5da5Sopenharmony_ciOpFunctionEnd 3024fd4e5da5Sopenharmony_ci)"; 3025fd4e5da5Sopenharmony_ci 3026fd4e5da5Sopenharmony_ci // The early return case must be handled by merge-return first. 3027fd4e5da5Sopenharmony_ci AddPass<MergeReturnPass>(); 3028fd4e5da5Sopenharmony_ci AddPass<InlineExhaustivePass>(); 3029fd4e5da5Sopenharmony_ci RunAndCheck(predefs + foo + before, predefs + fooMergeReturn + after); 3030fd4e5da5Sopenharmony_ci} 3031fd4e5da5Sopenharmony_ci 3032fd4e5da5Sopenharmony_ciTEST_F(InlineTest, CalleeWithSingleReturnNeedsSingleTripLoopWrapper) { 3033fd4e5da5Sopenharmony_ci // The case from https://github.com/KhronosGroup/SPIRV-Tools/issues/2018 3034fd4e5da5Sopenharmony_ci // 3035fd4e5da5Sopenharmony_ci // The callee has a single return, but needs single-trip loop wrapper 3036fd4e5da5Sopenharmony_ci // to be inlined because the return is in a selection structure. 3037fd4e5da5Sopenharmony_ci 3038fd4e5da5Sopenharmony_ci const std::string predefs = 3039fd4e5da5Sopenharmony_ci R"(OpCapability Shader 3040fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 3041fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 3042fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %_GLF_color 3043fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 3044fd4e5da5Sopenharmony_ciOpSource ESSL 310 3045fd4e5da5Sopenharmony_ciOpName %main "main" 3046fd4e5da5Sopenharmony_ciOpName %f_ "f(" 3047fd4e5da5Sopenharmony_ciOpName %i "i" 3048fd4e5da5Sopenharmony_ciOpName %_GLF_color "_GLF_color" 3049fd4e5da5Sopenharmony_ciOpDecorate %_GLF_color Location 0 3050fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3051fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 3052fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 3053fd4e5da5Sopenharmony_ci%9 = OpTypeFunction %float 3054fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 3055fd4e5da5Sopenharmony_ci%bool = OpTypeBool 3056fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 3057fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 3058fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 3059fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 3060fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 3061fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 3062fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 3063fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 3064fd4e5da5Sopenharmony_ci%_GLF_color = OpVariable %_ptr_Output_v4float Output 3065fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 3066fd4e5da5Sopenharmony_ci%21 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 3067fd4e5da5Sopenharmony_ci%22 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1 3068fd4e5da5Sopenharmony_ci)"; 3069fd4e5da5Sopenharmony_ci 3070fd4e5da5Sopenharmony_ci const std::string new_predefs = 3071fd4e5da5Sopenharmony_ci R"(%_ptr_Function_float = OpTypePointer Function %float 3072fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 3073fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 3074fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool 3075fd4e5da5Sopenharmony_ci)"; 3076fd4e5da5Sopenharmony_ci 3077fd4e5da5Sopenharmony_ci const std::string main_before = 3078fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 3079fd4e5da5Sopenharmony_ci%23 = OpLabel 3080fd4e5da5Sopenharmony_ci%i = OpVariable %_ptr_Function_int Function 3081fd4e5da5Sopenharmony_ciOpStore %i %int_0 3082fd4e5da5Sopenharmony_ciOpBranch %24 3083fd4e5da5Sopenharmony_ci%24 = OpLabel 3084fd4e5da5Sopenharmony_ciOpLoopMerge %25 %26 None 3085fd4e5da5Sopenharmony_ciOpBranch %27 3086fd4e5da5Sopenharmony_ci%27 = OpLabel 3087fd4e5da5Sopenharmony_ci%28 = OpLoad %int %i 3088fd4e5da5Sopenharmony_ci%29 = OpSLessThan %bool %28 %int_1 3089fd4e5da5Sopenharmony_ciOpBranchConditional %29 %30 %25 3090fd4e5da5Sopenharmony_ci%30 = OpLabel 3091fd4e5da5Sopenharmony_ciOpStore %_GLF_color %21 3092fd4e5da5Sopenharmony_ci%31 = OpFunctionCall %float %f_ 3093fd4e5da5Sopenharmony_ciOpBranch %26 3094fd4e5da5Sopenharmony_ci%26 = OpLabel 3095fd4e5da5Sopenharmony_ci%32 = OpLoad %int %i 3096fd4e5da5Sopenharmony_ci%33 = OpIAdd %int %32 %int_1 3097fd4e5da5Sopenharmony_ciOpStore %i %33 3098fd4e5da5Sopenharmony_ciOpBranch %24 3099fd4e5da5Sopenharmony_ci%25 = OpLabel 3100fd4e5da5Sopenharmony_ciOpStore %_GLF_color %22 3101fd4e5da5Sopenharmony_ciOpReturn 3102fd4e5da5Sopenharmony_ciOpFunctionEnd 3103fd4e5da5Sopenharmony_ci)"; 3104fd4e5da5Sopenharmony_ci 3105fd4e5da5Sopenharmony_ci const std::string main_after = 3106fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 3107fd4e5da5Sopenharmony_ci%23 = OpLabel 3108fd4e5da5Sopenharmony_ci%46 = OpVariable %_ptr_Function_bool Function %false 3109fd4e5da5Sopenharmony_ci%47 = OpVariable %_ptr_Function_float Function 3110fd4e5da5Sopenharmony_ci%48 = OpVariable %_ptr_Function_float Function 3111fd4e5da5Sopenharmony_ci%i = OpVariable %_ptr_Function_int Function 3112fd4e5da5Sopenharmony_ciOpStore %i %int_0 3113fd4e5da5Sopenharmony_ciOpBranch %24 3114fd4e5da5Sopenharmony_ci%24 = OpLabel 3115fd4e5da5Sopenharmony_ciOpLoopMerge %25 %26 None 3116fd4e5da5Sopenharmony_ciOpBranch %27 3117fd4e5da5Sopenharmony_ci%27 = OpLabel 3118fd4e5da5Sopenharmony_ci%28 = OpLoad %int %i 3119fd4e5da5Sopenharmony_ci%29 = OpSLessThan %bool %28 %int_1 3120fd4e5da5Sopenharmony_ciOpBranchConditional %29 %30 %25 3121fd4e5da5Sopenharmony_ci%30 = OpLabel 3122fd4e5da5Sopenharmony_ciOpStore %_GLF_color %21 3123fd4e5da5Sopenharmony_ciOpStore %46 %false 3124fd4e5da5Sopenharmony_ciOpSelectionMerge %53 None 3125fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %50 3126fd4e5da5Sopenharmony_ci%50 = OpLabel 3127fd4e5da5Sopenharmony_ciOpSelectionMerge %52 None 3128fd4e5da5Sopenharmony_ciOpBranchConditional %true %51 %52 3129fd4e5da5Sopenharmony_ci%51 = OpLabel 3130fd4e5da5Sopenharmony_ciOpStore %46 %true 3131fd4e5da5Sopenharmony_ciOpStore %47 %float_1 3132fd4e5da5Sopenharmony_ciOpBranch %53 3133fd4e5da5Sopenharmony_ci%52 = OpLabel 3134fd4e5da5Sopenharmony_ciOpStore %46 %true 3135fd4e5da5Sopenharmony_ciOpStore %47 %float_1 3136fd4e5da5Sopenharmony_ciOpBranch %53 3137fd4e5da5Sopenharmony_ci%53 = OpLabel 3138fd4e5da5Sopenharmony_ci%54 = OpLoad %float %47 3139fd4e5da5Sopenharmony_ciOpStore %48 %54 3140fd4e5da5Sopenharmony_ci%31 = OpLoad %float %48 3141fd4e5da5Sopenharmony_ciOpBranch %26 3142fd4e5da5Sopenharmony_ci%26 = OpLabel 3143fd4e5da5Sopenharmony_ci%32 = OpLoad %int %i 3144fd4e5da5Sopenharmony_ci%33 = OpIAdd %int %32 %int_1 3145fd4e5da5Sopenharmony_ciOpStore %i %33 3146fd4e5da5Sopenharmony_ciOpBranch %24 3147fd4e5da5Sopenharmony_ci%25 = OpLabel 3148fd4e5da5Sopenharmony_ciOpStore %_GLF_color %22 3149fd4e5da5Sopenharmony_ciOpReturn 3150fd4e5da5Sopenharmony_ciOpFunctionEnd 3151fd4e5da5Sopenharmony_ci)"; 3152fd4e5da5Sopenharmony_ci 3153fd4e5da5Sopenharmony_ci const std::string callee = 3154fd4e5da5Sopenharmony_ci R"(%f_ = OpFunction %float None %9 3155fd4e5da5Sopenharmony_ci%34 = OpLabel 3156fd4e5da5Sopenharmony_ciOpSelectionMerge %35 None 3157fd4e5da5Sopenharmony_ciOpBranchConditional %true %36 %35 3158fd4e5da5Sopenharmony_ci%36 = OpLabel 3159fd4e5da5Sopenharmony_ciOpReturnValue %float_1 3160fd4e5da5Sopenharmony_ci%35 = OpLabel 3161fd4e5da5Sopenharmony_ciOpReturnValue %float_1 3162fd4e5da5Sopenharmony_ciOpFunctionEnd 3163fd4e5da5Sopenharmony_ci)"; 3164fd4e5da5Sopenharmony_ci 3165fd4e5da5Sopenharmony_ci const std::string calleeMergeReturn = 3166fd4e5da5Sopenharmony_ci R"(%f_ = OpFunction %float None %9 3167fd4e5da5Sopenharmony_ci%34 = OpLabel 3168fd4e5da5Sopenharmony_ci%45 = OpVariable %_ptr_Function_bool Function %false 3169fd4e5da5Sopenharmony_ci%39 = OpVariable %_ptr_Function_float Function 3170fd4e5da5Sopenharmony_ciOpSelectionMerge %37 None 3171fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %41 3172fd4e5da5Sopenharmony_ci%41 = OpLabel 3173fd4e5da5Sopenharmony_ciOpSelectionMerge %35 None 3174fd4e5da5Sopenharmony_ciOpBranchConditional %true %36 %35 3175fd4e5da5Sopenharmony_ci%36 = OpLabel 3176fd4e5da5Sopenharmony_ciOpStore %45 %true 3177fd4e5da5Sopenharmony_ciOpStore %39 %float_1 3178fd4e5da5Sopenharmony_ciOpBranch %37 3179fd4e5da5Sopenharmony_ci%35 = OpLabel 3180fd4e5da5Sopenharmony_ciOpStore %45 %true 3181fd4e5da5Sopenharmony_ciOpStore %39 %float_1 3182fd4e5da5Sopenharmony_ciOpBranch %37 3183fd4e5da5Sopenharmony_ci%37 = OpLabel 3184fd4e5da5Sopenharmony_ci%40 = OpLoad %float %39 3185fd4e5da5Sopenharmony_ciOpReturnValue %40 3186fd4e5da5Sopenharmony_ciOpFunctionEnd 3187fd4e5da5Sopenharmony_ci)"; 3188fd4e5da5Sopenharmony_ci 3189fd4e5da5Sopenharmony_ci // The early return case must be handled by merge-return first. 3190fd4e5da5Sopenharmony_ci AddPass<MergeReturnPass>(); 3191fd4e5da5Sopenharmony_ci AddPass<InlineExhaustivePass>(); 3192fd4e5da5Sopenharmony_ci RunAndCheck(predefs + main_before + callee, 3193fd4e5da5Sopenharmony_ci predefs + new_predefs + main_after + calleeMergeReturn); 3194fd4e5da5Sopenharmony_ci} 3195fd4e5da5Sopenharmony_ci 3196fd4e5da5Sopenharmony_ciTEST_F(InlineTest, ForwardReferencesInPhiInlined) { 3197fd4e5da5Sopenharmony_ci // The basic structure of the test case is like this: 3198fd4e5da5Sopenharmony_ci // 3199fd4e5da5Sopenharmony_ci // int foo() { 3200fd4e5da5Sopenharmony_ci // int result = 1; 3201fd4e5da5Sopenharmony_ci // if (true) { 3202fd4e5da5Sopenharmony_ci // result = 1; 3203fd4e5da5Sopenharmony_ci // } 3204fd4e5da5Sopenharmony_ci // return result; 3205fd4e5da5Sopenharmony_ci // } 3206fd4e5da5Sopenharmony_ci // 3207fd4e5da5Sopenharmony_ci // void main() { 3208fd4e5da5Sopenharmony_ci // int x = foo(); 3209fd4e5da5Sopenharmony_ci // } 3210fd4e5da5Sopenharmony_ci // 3211fd4e5da5Sopenharmony_ci // but with modifications: Using Phi instead of load/store, and the 3212fd4e5da5Sopenharmony_ci // return block in foo appears before the "then" block. 3213fd4e5da5Sopenharmony_ci 3214fd4e5da5Sopenharmony_ci const std::string predefs = 3215fd4e5da5Sopenharmony_ci R"(OpCapability Shader 3216fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 3217fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 3218fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 3219fd4e5da5Sopenharmony_ciOpSource GLSL 450 3220fd4e5da5Sopenharmony_ciOpName %main "main" 3221fd4e5da5Sopenharmony_ciOpName %foo_ "foo(" 3222fd4e5da5Sopenharmony_ciOpName %x "x" 3223fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3224fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void 3225fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 3226fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %int 3227fd4e5da5Sopenharmony_ci%bool = OpTypeBool 3228fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 3229fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 3230fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 3231fd4e5da5Sopenharmony_ci)"; 3232fd4e5da5Sopenharmony_ci 3233fd4e5da5Sopenharmony_ci const std::string callee = 3234fd4e5da5Sopenharmony_ci R"(%foo_ = OpFunction %int None %8 3235fd4e5da5Sopenharmony_ci%13 = OpLabel 3236fd4e5da5Sopenharmony_ci%14 = OpCopyObject %int %int_0 3237fd4e5da5Sopenharmony_ciOpSelectionMerge %15 None 3238fd4e5da5Sopenharmony_ciOpBranchConditional %true %16 %15 3239fd4e5da5Sopenharmony_ci%15 = OpLabel 3240fd4e5da5Sopenharmony_ci%17 = OpPhi %int %14 %13 %18 %16 3241fd4e5da5Sopenharmony_ciOpReturnValue %17 3242fd4e5da5Sopenharmony_ci%16 = OpLabel 3243fd4e5da5Sopenharmony_ci%18 = OpCopyObject %int %int_0 3244fd4e5da5Sopenharmony_ciOpBranch %15 3245fd4e5da5Sopenharmony_ciOpFunctionEnd 3246fd4e5da5Sopenharmony_ci)"; 3247fd4e5da5Sopenharmony_ci 3248fd4e5da5Sopenharmony_ci const std::string calleeMergeReturn = 3249fd4e5da5Sopenharmony_ci R"(%uint = OpTypeInt 32 0 3250fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 3251fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 3252fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool 3253fd4e5da5Sopenharmony_ci%foo_ = OpFunction %int None %8 3254fd4e5da5Sopenharmony_ci%13 = OpLabel 3255fd4e5da5Sopenharmony_ci%29 = OpVariable %_ptr_Function_bool Function %false 3256fd4e5da5Sopenharmony_ci%22 = OpVariable %_ptr_Function_int Function 3257fd4e5da5Sopenharmony_ciOpSelectionMerge %21 None 3258fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %24 3259fd4e5da5Sopenharmony_ci%24 = OpLabel 3260fd4e5da5Sopenharmony_ci%14 = OpCopyObject %int %int_0 3261fd4e5da5Sopenharmony_ciOpSelectionMerge %15 None 3262fd4e5da5Sopenharmony_ciOpBranchConditional %true %16 %15 3263fd4e5da5Sopenharmony_ci%15 = OpLabel 3264fd4e5da5Sopenharmony_ci%17 = OpPhi %int %14 %24 %18 %16 3265fd4e5da5Sopenharmony_ciOpStore %29 %true 3266fd4e5da5Sopenharmony_ciOpStore %22 %17 3267fd4e5da5Sopenharmony_ciOpBranch %21 3268fd4e5da5Sopenharmony_ci%16 = OpLabel 3269fd4e5da5Sopenharmony_ci%18 = OpCopyObject %int %int_0 3270fd4e5da5Sopenharmony_ciOpBranch %15 3271fd4e5da5Sopenharmony_ci%21 = OpLabel 3272fd4e5da5Sopenharmony_ci%23 = OpLoad %int %22 3273fd4e5da5Sopenharmony_ciOpReturnValue %23 3274fd4e5da5Sopenharmony_ciOpFunctionEnd 3275fd4e5da5Sopenharmony_ci)"; 3276fd4e5da5Sopenharmony_ci 3277fd4e5da5Sopenharmony_ci const std::string before = 3278fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %6 3279fd4e5da5Sopenharmony_ci%19 = OpLabel 3280fd4e5da5Sopenharmony_ci%x = OpVariable %_ptr_Function_int Function 3281fd4e5da5Sopenharmony_ci%20 = OpFunctionCall %int %foo_ 3282fd4e5da5Sopenharmony_ciOpStore %x %20 3283fd4e5da5Sopenharmony_ciOpReturn 3284fd4e5da5Sopenharmony_ciOpFunctionEnd 3285fd4e5da5Sopenharmony_ci)"; 3286fd4e5da5Sopenharmony_ci 3287fd4e5da5Sopenharmony_ci const std::string after = 3288fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %6 3289fd4e5da5Sopenharmony_ci%19 = OpLabel 3290fd4e5da5Sopenharmony_ci%30 = OpVariable %_ptr_Function_bool Function %false 3291fd4e5da5Sopenharmony_ci%31 = OpVariable %_ptr_Function_int Function 3292fd4e5da5Sopenharmony_ci%32 = OpVariable %_ptr_Function_int Function 3293fd4e5da5Sopenharmony_ci%x = OpVariable %_ptr_Function_int Function 3294fd4e5da5Sopenharmony_ciOpStore %30 %false 3295fd4e5da5Sopenharmony_ciOpSelectionMerge %40 None 3296fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %34 3297fd4e5da5Sopenharmony_ci%34 = OpLabel 3298fd4e5da5Sopenharmony_ci%35 = OpCopyObject %int %int_0 3299fd4e5da5Sopenharmony_ciOpSelectionMerge %36 None 3300fd4e5da5Sopenharmony_ciOpBranchConditional %true %38 %36 3301fd4e5da5Sopenharmony_ci%36 = OpLabel 3302fd4e5da5Sopenharmony_ci%37 = OpPhi %int %35 %34 %39 %38 3303fd4e5da5Sopenharmony_ciOpStore %30 %true 3304fd4e5da5Sopenharmony_ciOpStore %31 %37 3305fd4e5da5Sopenharmony_ciOpBranch %40 3306fd4e5da5Sopenharmony_ci%38 = OpLabel 3307fd4e5da5Sopenharmony_ci%39 = OpCopyObject %int %int_0 3308fd4e5da5Sopenharmony_ciOpBranch %36 3309fd4e5da5Sopenharmony_ci%40 = OpLabel 3310fd4e5da5Sopenharmony_ci%41 = OpLoad %int %31 3311fd4e5da5Sopenharmony_ciOpStore %32 %41 3312fd4e5da5Sopenharmony_ci%20 = OpLoad %int %32 3313fd4e5da5Sopenharmony_ciOpStore %x %20 3314fd4e5da5Sopenharmony_ciOpReturn 3315fd4e5da5Sopenharmony_ciOpFunctionEnd 3316fd4e5da5Sopenharmony_ci)"; 3317fd4e5da5Sopenharmony_ci 3318fd4e5da5Sopenharmony_ci AddPass<MergeReturnPass>(); 3319fd4e5da5Sopenharmony_ci AddPass<InlineExhaustivePass>(); 3320fd4e5da5Sopenharmony_ci RunAndCheck(predefs + callee + before, predefs + calleeMergeReturn + after); 3321fd4e5da5Sopenharmony_ci} 3322fd4e5da5Sopenharmony_ci 3323fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugSimple) { 3324fd4e5da5Sopenharmony_ci // Check that it correctly generates DebugInlinedAt and maps it to DebugScope 3325fd4e5da5Sopenharmony_ci // for the inlined function foo(). 3326fd4e5da5Sopenharmony_ci const std::string text = R"( 3327fd4e5da5Sopenharmony_ci; CHECK: [[main_name:%\d+]] = OpString "main" 3328fd4e5da5Sopenharmony_ci; CHECK: [[foo_name:%\d+]] = OpString "foo" 3329fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void {{%\d+}} DebugFunction [[main_name]] {{%\d+}} {{%\d+}} 4 1 {{%\d+}} [[main_name]] FlagIsProtected|FlagIsPrivate 4 [[main:%\d+]] 3330fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\d+]] = OpExtInst %void {{%\d+}} DebugFunction [[foo_name]] {{%\d+}} {{%\d+}} 1 1 {{%\d+}} [[foo_name]] FlagIsProtected|FlagIsPrivate 1 [[foo:%\d+]] 3331fd4e5da5Sopenharmony_ci; CHECK: [[foo_bb:%\d+]] = OpExtInst %void {{%\d+}} DebugLexicalBlock {{%\d+}} 1 14 [[dbg_foo]] 3332fd4e5da5Sopenharmony_ci; CHECK: [[inlined_at:%\d+]] = OpExtInst %void {{%\d+}} DebugInlinedAt 4 [[dbg_main]] 3333fd4e5da5Sopenharmony_ci; CHECK: [[main]] = OpFunction %void None 3334fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void {{%\d+}} DebugScope [[foo_bb]] [[inlined_at]] 3335fd4e5da5Sopenharmony_ci; CHECK: [[foo]] = OpFunction %v4float None 3336fd4e5da5Sopenharmony_ci OpCapability Shader 3337fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "OpenCL.DebugInfo.100" 3338fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3339fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %3 %4 3340fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 3341fd4e5da5Sopenharmony_ci %5 = OpString "ps.hlsl" 3342fd4e5da5Sopenharmony_ci OpSource HLSL 600 %5 3343fd4e5da5Sopenharmony_ci %6 = OpString "float" 3344fd4e5da5Sopenharmony_ci %main_name = OpString "main" 3345fd4e5da5Sopenharmony_ci %foo_name = OpString "foo" 3346fd4e5da5Sopenharmony_ci OpDecorate %3 Location 0 3347fd4e5da5Sopenharmony_ci OpDecorate %4 Location 0 3348fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 3349fd4e5da5Sopenharmony_ci %uint_32 = OpConstant %uint 32 3350fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 3351fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 3352fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 3353fd4e5da5Sopenharmony_ci %14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 3354fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 3355fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 3356fd4e5da5Sopenharmony_ci %void = OpTypeVoid 3357fd4e5da5Sopenharmony_ci %18 = OpTypeFunction %void 3358fd4e5da5Sopenharmony_ci %19 = OpTypeFunction %v4float 3359fd4e5da5Sopenharmony_ci %3 = OpVariable %_ptr_Input_v4float Input 3360fd4e5da5Sopenharmony_ci %4 = OpVariable %_ptr_Output_v4float Output 3361fd4e5da5Sopenharmony_ci %20 = OpExtInst %void %1 DebugSource %5 3362fd4e5da5Sopenharmony_ci %21 = OpExtInst %void %1 DebugCompilationUnit 1 4 %20 HLSL 3363fd4e5da5Sopenharmony_ci %22 = OpExtInst %void %1 DebugTypeBasic %6 %uint_32 Float 3364fd4e5da5Sopenharmony_ci %23 = OpExtInst %void %1 DebugTypeVector %22 4 3365fd4e5da5Sopenharmony_ci %24 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %23 %23 3366fd4e5da5Sopenharmony_ci %25 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %23 3367fd4e5da5Sopenharmony_ci %dbg_main = OpExtInst %void %1 DebugFunction %main_name %24 %20 4 1 %21 %main_name FlagIsProtected|FlagIsPrivate 4 %main 3368fd4e5da5Sopenharmony_ci %dbg_foo = OpExtInst %void %1 DebugFunction %foo_name %25 %20 1 1 %21 %foo_name FlagIsProtected|FlagIsPrivate 1 %foo 3369fd4e5da5Sopenharmony_ci %29 = OpExtInst %void %1 DebugLexicalBlock %20 1 14 %dbg_foo 3370fd4e5da5Sopenharmony_ci %main = OpFunction %void None %18 3371fd4e5da5Sopenharmony_ci %30 = OpLabel 3372fd4e5da5Sopenharmony_ci %31 = OpExtInst %void %1 DebugScope %dbg_main 3373fd4e5da5Sopenharmony_ci %32 = OpFunctionCall %v4float %foo 3374fd4e5da5Sopenharmony_ci %33 = OpLoad %v4float %3 3375fd4e5da5Sopenharmony_ci %34 = OpFAdd %v4float %32 %33 3376fd4e5da5Sopenharmony_ci OpStore %4 %34 3377fd4e5da5Sopenharmony_ci OpReturn 3378fd4e5da5Sopenharmony_ci OpFunctionEnd 3379fd4e5da5Sopenharmony_ci %foo = OpFunction %v4float None %19 3380fd4e5da5Sopenharmony_ci %35 = OpExtInst %void %1 DebugScope %dbg_foo 3381fd4e5da5Sopenharmony_ci %36 = OpLabel 3382fd4e5da5Sopenharmony_ci %37 = OpExtInst %void %1 DebugScope %29 3383fd4e5da5Sopenharmony_ci OpReturnValue %14 3384fd4e5da5Sopenharmony_ci OpFunctionEnd 3385fd4e5da5Sopenharmony_ci)"; 3386fd4e5da5Sopenharmony_ci 3387fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 3388fd4e5da5Sopenharmony_ci} 3389fd4e5da5Sopenharmony_ci 3390fd4e5da5Sopenharmony_ciTEST_F(InlineTest, ShaderDebugSimple) { 3391fd4e5da5Sopenharmony_ci // Same as DebugSimple but for NonSemantic.Shader.DebugInfo.100. 3392fd4e5da5Sopenharmony_ci const std::string text = R"( 3393fd4e5da5Sopenharmony_ci; CHECK: [[main_name:%\d+]] = OpString "main" 3394fd4e5da5Sopenharmony_ci; CHECK: [[foo_name:%\d+]] = OpString "foo" 3395fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void {{%\d+}} DebugFunction [[main_name]] {{%\d+}} {{%\d+}} %uint_4 %uint_1 {{%\d+}} [[main_name]] %uint_3 %uint_4 3396fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\d+]] = OpExtInst %void {{%\d+}} DebugFunction [[foo_name]] {{%\d+}} {{%\d+}} %uint_1 %uint_1 {{%\d+}} [[foo_name]] %uint_3 %uint_1 3397fd4e5da5Sopenharmony_ci; CHECK: [[foo_bb:%\d+]] = OpExtInst %void {{%\d+}} DebugLexicalBlock {{%\d+}} %uint_1 %uint_14 [[dbg_foo]] 3398fd4e5da5Sopenharmony_ci; CHECK: [[inlined_at:%\d+]] = OpExtInst %void {{%\d+}} DebugInlinedAt %uint_4 [[dbg_main]] 3399fd4e5da5Sopenharmony_ci; CHECK: [[main:%\d+]] = OpFunction %void None 3400fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void {{%\d+}} DebugScope [[foo_bb]] [[inlined_at]] 3401fd4e5da5Sopenharmony_ci; CHECK: [[foo:%\d+]] = OpFunction %v4float None 3402fd4e5da5Sopenharmony_ci OpCapability Shader 3403fd4e5da5Sopenharmony_ci OpExtension "SPV_KHR_non_semantic_info" 3404fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" 3405fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3406fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %3 %4 3407fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 3408fd4e5da5Sopenharmony_ci %5 = OpString "ps.hlsl" 3409fd4e5da5Sopenharmony_ci OpSource HLSL 600 %5 3410fd4e5da5Sopenharmony_ci %6 = OpString "float" 3411fd4e5da5Sopenharmony_ci %main_name = OpString "main" 3412fd4e5da5Sopenharmony_ci %foo_name = OpString "foo" 3413fd4e5da5Sopenharmony_ci OpDecorate %3 Location 0 3414fd4e5da5Sopenharmony_ci OpDecorate %4 Location 0 3415fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 3416fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 3417fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 3418fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 3419fd4e5da5Sopenharmony_ci %uint_3 = OpConstant %uint 3 3420fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 3421fd4e5da5Sopenharmony_ci %uint_5 = OpConstant %uint 5 3422fd4e5da5Sopenharmony_ci %uint_14 = OpConstant %uint 14 3423fd4e5da5Sopenharmony_ci %uint_32 = OpConstant %uint 32 3424fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 3425fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 3426fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 3427fd4e5da5Sopenharmony_ci %14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 3428fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 3429fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 3430fd4e5da5Sopenharmony_ci %void = OpTypeVoid 3431fd4e5da5Sopenharmony_ci %18 = OpTypeFunction %void 3432fd4e5da5Sopenharmony_ci %19 = OpTypeFunction %v4float 3433fd4e5da5Sopenharmony_ci %3 = OpVariable %_ptr_Input_v4float Input 3434fd4e5da5Sopenharmony_ci %4 = OpVariable %_ptr_Output_v4float Output 3435fd4e5da5Sopenharmony_ci %20 = OpExtInst %void %1 DebugSource %5 3436fd4e5da5Sopenharmony_ci %21 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %20 %uint_5 3437fd4e5da5Sopenharmony_ci %22 = OpExtInst %void %1 DebugTypeBasic %6 %uint_32 %uint_3 %uint_0 3438fd4e5da5Sopenharmony_ci %23 = OpExtInst %void %1 DebugTypeVector %22 %uint_4 3439fd4e5da5Sopenharmony_ci %24 = OpExtInst %void %1 DebugTypeFunction %uint_3 %23 %23 3440fd4e5da5Sopenharmony_ci %25 = OpExtInst %void %1 DebugTypeFunction %uint_3 %23 3441fd4e5da5Sopenharmony_ci %dbg_main = OpExtInst %void %1 DebugFunction %main_name %24 %20 %uint_4 %uint_1 %21 %main_name %uint_3 %uint_4 3442fd4e5da5Sopenharmony_ci %dbg_foo = OpExtInst %void %1 DebugFunction %foo_name %25 %20 %uint_1 %uint_1 %21 %foo_name %uint_3 %uint_1 3443fd4e5da5Sopenharmony_ci %29 = OpExtInst %void %1 DebugLexicalBlock %20 %uint_1 %uint_14 %dbg_foo 3444fd4e5da5Sopenharmony_ci %main = OpFunction %void None %18 3445fd4e5da5Sopenharmony_ci %30 = OpLabel 3446fd4e5da5Sopenharmony_ci%dbg_main_def = OpExtInst %void %1 DebugFunctionDefinition %dbg_main %main 3447fd4e5da5Sopenharmony_ci %31 = OpExtInst %void %1 DebugScope %dbg_main 3448fd4e5da5Sopenharmony_ci %32 = OpFunctionCall %v4float %foo 3449fd4e5da5Sopenharmony_ci %33 = OpLoad %v4float %3 3450fd4e5da5Sopenharmony_ci %34 = OpFAdd %v4float %32 %33 3451fd4e5da5Sopenharmony_ci OpStore %4 %34 3452fd4e5da5Sopenharmony_ci OpReturn 3453fd4e5da5Sopenharmony_ci OpFunctionEnd 3454fd4e5da5Sopenharmony_ci %foo = OpFunction %v4float None %19 3455fd4e5da5Sopenharmony_ci %36 = OpLabel 3456fd4e5da5Sopenharmony_ci%dbg_foo_def = OpExtInst %void %1 DebugFunctionDefinition %dbg_foo %foo 3457fd4e5da5Sopenharmony_ci %35 = OpExtInst %void %1 DebugScope %dbg_foo 3458fd4e5da5Sopenharmony_ci %37 = OpExtInst %void %1 DebugScope %29 3459fd4e5da5Sopenharmony_ci OpReturnValue %14 3460fd4e5da5Sopenharmony_ci OpFunctionEnd 3461fd4e5da5Sopenharmony_ci)"; 3462fd4e5da5Sopenharmony_ci 3463fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 3464fd4e5da5Sopenharmony_ci} 3465fd4e5da5Sopenharmony_ci 3466fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugNested) { 3467fd4e5da5Sopenharmony_ci // When function main() calls function zoo() and function zoo() calls 3468fd4e5da5Sopenharmony_ci // function bar() and function bar() calls function foo(), check that 3469fd4e5da5Sopenharmony_ci // the inline pass correctly generates DebugInlinedAt instructions 3470fd4e5da5Sopenharmony_ci // for the nested function calls. 3471fd4e5da5Sopenharmony_ci const std::string text = R"( 3472fd4e5da5Sopenharmony_ci; CHECK: [[v4f1:%\d+]] = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 3473fd4e5da5Sopenharmony_ci; CHECK: [[v4f2:%\d+]] = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 3474fd4e5da5Sopenharmony_ci; CHECK: [[v4f3:%\d+]] = OpConstantComposite %v4float %float_3 %float_3 %float_3 %float_3 3475fd4e5da5Sopenharmony_ci; CHECK: [[color:%\d+]] = OpVariable %_ptr_Input_v4float Input 3476fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} 10 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 10 [[main:%\d+]] 3477fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\d+]] = OpExtInst %void [[ext]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} 1 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 1 [[foo:%\d+]] 3478fd4e5da5Sopenharmony_ci; CHECK: [[dbg_bar:%\d+]] = OpExtInst %void [[ext]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} 4 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 4 [[bar:%\d+]] 3479fd4e5da5Sopenharmony_ci; CHECK: [[dbg_zoo:%\d+]] = OpExtInst %void [[ext]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} 7 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 7 [[zoo:%\d+]] 3480fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_main:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 600 [[dbg_main]] 3481fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_zoo:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 700 [[dbg_zoo]] [[inlined_to_main]] 3482fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_bar:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 300 [[dbg_bar]] [[inlined_to_zoo]] 3483fd4e5da5Sopenharmony_ci; CHECK: [[main]] = OpFunction %void None 3484fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_foo]] [[inlined_to_bar]] 3485fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\d+}} 100 0 3486fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpStore {{%\d+}} [[v4f1]] 3487fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_bar]] [[inlined_to_zoo]] 3488fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\d+}} 300 0 3489fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[foo_ret:%\d+]] = OpLoad %v4float 3490fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\d+}} 400 0 3491fd4e5da5Sopenharmony_ci; CHECK-NEXT: {{%\d+}} = OpFAdd %v4float [[foo_ret]] [[v4f2]] 3492fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_zoo]] [[inlined_to_main]] 3493fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\d+}} 700 0 3494fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[bar_ret:%\d+]] = OpLoad %v4float 3495fd4e5da5Sopenharmony_ci; CHECK-NEXT: {{%\d+}} = OpFAdd %v4float [[bar_ret]] [[v4f3]] 3496fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_main]] 3497fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\d+}} 600 0 3498fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[zoo_ret:%\d+]] = OpLoad %v4float 3499fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[color_val:%\d+]] = OpLoad %v4float [[color]] 3500fd4e5da5Sopenharmony_ci; CHECK-NEXT: {{%\d+}} = OpFAdd %v4float [[zoo_ret]] [[color_val]] 3501fd4e5da5Sopenharmony_ci; CHECK: [[foo]] = OpFunction %v4float None 3502fd4e5da5Sopenharmony_ci; CHECK: [[bar]] = OpFunction %v4float None 3503fd4e5da5Sopenharmony_ci; CHECK: [[zoo]] = OpFunction %v4float None 3504fd4e5da5Sopenharmony_ci OpCapability Shader 3505fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "OpenCL.DebugInfo.100" 3506fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3507fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %3 %4 3508fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 3509fd4e5da5Sopenharmony_ci %5 = OpString "ps.hlsl" 3510fd4e5da5Sopenharmony_ci OpSource HLSL 600 %5 3511fd4e5da5Sopenharmony_ci %6 = OpString "float" 3512fd4e5da5Sopenharmony_ci %7 = OpString "main" 3513fd4e5da5Sopenharmony_ci %8 = OpString "foo" 3514fd4e5da5Sopenharmony_ci %9 = OpString "bar" 3515fd4e5da5Sopenharmony_ci %10 = OpString "zoo" 3516fd4e5da5Sopenharmony_ci OpDecorate %3 Location 0 3517fd4e5da5Sopenharmony_ci OpDecorate %4 Location 0 3518fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 3519fd4e5da5Sopenharmony_ci %uint_32 = OpConstant %uint 32 3520fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 3521fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 3522fd4e5da5Sopenharmony_ci %float_2 = OpConstant %float 2 3523fd4e5da5Sopenharmony_ci %float_3 = OpConstant %float 3 3524fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 3525fd4e5da5Sopenharmony_ci %18 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 3526fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 3527fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %v4float %float_3 %float_3 %float_3 %float_3 3528fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 3529fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 3530fd4e5da5Sopenharmony_ci %void = OpTypeVoid 3531fd4e5da5Sopenharmony_ci %24 = OpTypeFunction %void 3532fd4e5da5Sopenharmony_ci %25 = OpTypeFunction %v4float 3533fd4e5da5Sopenharmony_ci %3 = OpVariable %_ptr_Input_v4float Input 3534fd4e5da5Sopenharmony_ci %4 = OpVariable %_ptr_Output_v4float Output 3535fd4e5da5Sopenharmony_ci %26 = OpExtInst %void %1 DebugSource %5 3536fd4e5da5Sopenharmony_ci %27 = OpExtInst %void %1 DebugCompilationUnit 1 4 %26 HLSL 3537fd4e5da5Sopenharmony_ci %28 = OpExtInst %void %1 DebugTypeBasic %6 %uint_32 Float 3538fd4e5da5Sopenharmony_ci %29 = OpExtInst %void %1 DebugTypeVector %28 4 3539fd4e5da5Sopenharmony_ci %30 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %29 %29 3540fd4e5da5Sopenharmony_ci %31 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %29 3541fd4e5da5Sopenharmony_ci %32 = OpExtInst %void %1 DebugFunction %7 %30 %26 10 1 %27 %7 FlagIsProtected|FlagIsPrivate 10 %main 3542fd4e5da5Sopenharmony_ci %33 = OpExtInst %void %1 DebugFunction %8 %31 %26 1 1 %27 %8 FlagIsProtected|FlagIsPrivate 1 %foo 3543fd4e5da5Sopenharmony_ci %35 = OpExtInst %void %1 DebugFunction %9 %31 %26 4 1 %27 %9 FlagIsProtected|FlagIsPrivate 4 %bar 3544fd4e5da5Sopenharmony_ci %37 = OpExtInst %void %1 DebugFunction %10 %31 %26 7 1 %27 %10 FlagIsProtected|FlagIsPrivate 7 %zoo 3545fd4e5da5Sopenharmony_ci %main = OpFunction %void None %24 3546fd4e5da5Sopenharmony_ci %39 = OpLabel 3547fd4e5da5Sopenharmony_ci %40 = OpExtInst %void %1 DebugScope %32 3548fd4e5da5Sopenharmony_ci OpLine %5 600 0 3549fd4e5da5Sopenharmony_ci %41 = OpFunctionCall %v4float %zoo 3550fd4e5da5Sopenharmony_ci %42 = OpLoad %v4float %3 3551fd4e5da5Sopenharmony_ci %43 = OpFAdd %v4float %41 %42 3552fd4e5da5Sopenharmony_ci OpStore %4 %43 3553fd4e5da5Sopenharmony_ci OpReturn 3554fd4e5da5Sopenharmony_ci OpFunctionEnd 3555fd4e5da5Sopenharmony_ci %foo = OpFunction %v4float None %25 3556fd4e5da5Sopenharmony_ci %44 = OpExtInst %void %1 DebugScope %33 3557fd4e5da5Sopenharmony_ci %45 = OpLabel 3558fd4e5da5Sopenharmony_ci OpLine %5 100 0 3559fd4e5da5Sopenharmony_ci OpReturnValue %18 3560fd4e5da5Sopenharmony_ci OpFunctionEnd 3561fd4e5da5Sopenharmony_ci OpLine %5 200 0 3562fd4e5da5Sopenharmony_ci %bar = OpFunction %v4float None %25 3563fd4e5da5Sopenharmony_ci %46 = OpExtInst %void %1 DebugScope %35 3564fd4e5da5Sopenharmony_ci %47 = OpLabel 3565fd4e5da5Sopenharmony_ci OpLine %5 300 0 3566fd4e5da5Sopenharmony_ci %48 = OpFunctionCall %v4float %foo 3567fd4e5da5Sopenharmony_ci OpLine %5 400 0 3568fd4e5da5Sopenharmony_ci %49 = OpFAdd %v4float %48 %19 3569fd4e5da5Sopenharmony_ci OpLine %5 500 0 3570fd4e5da5Sopenharmony_ci OpReturnValue %49 3571fd4e5da5Sopenharmony_ci OpFunctionEnd 3572fd4e5da5Sopenharmony_ci %zoo = OpFunction %v4float None %25 3573fd4e5da5Sopenharmony_ci %50 = OpExtInst %void %1 DebugScope %37 3574fd4e5da5Sopenharmony_ci %51 = OpLabel 3575fd4e5da5Sopenharmony_ci OpLine %5 700 0 3576fd4e5da5Sopenharmony_ci %52 = OpFunctionCall %v4float %bar 3577fd4e5da5Sopenharmony_ci %53 = OpFAdd %v4float %52 %20 3578fd4e5da5Sopenharmony_ci OpReturnValue %53 3579fd4e5da5Sopenharmony_ci OpFunctionEnd 3580fd4e5da5Sopenharmony_ci)"; 3581fd4e5da5Sopenharmony_ci 3582fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 3583fd4e5da5Sopenharmony_ci} 3584fd4e5da5Sopenharmony_ci 3585fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugSimpleHLSLPixelShader) { 3586fd4e5da5Sopenharmony_ci const std::string text = R"( 3587fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} 1 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 1 %src_main 3588fd4e5da5Sopenharmony_ci; CHECK: [[lex_blk:%\d+]] = OpExtInst %void [[ext]] DebugLexicalBlock {{%\d+}} 1 47 [[dbg_main]] 3589fd4e5da5Sopenharmony_ci; CHECK: %main = OpFunction %void None 3590fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_main]] 3591fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare {{%\d+}} %param_var_color 3592fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[lex_blk]] 3593fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\d+}} 2 10 3594fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpLoad %v4float %param_var_color 3595fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\d+}} 2 3 3596fd4e5da5Sopenharmony_ci; CHECK: OpFunctionEnd 3597fd4e5da5Sopenharmony_ci; CHECK: %src_main = OpFunction %v4float None 3598fd4e5da5Sopenharmony_ci OpCapability Shader 3599fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "OpenCL.DebugInfo.100" 3600fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3601fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET 3602fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 3603fd4e5da5Sopenharmony_ci %5 = OpString "ps.hlsl" 3604fd4e5da5Sopenharmony_ci OpSource HLSL 600 %5 3605fd4e5da5Sopenharmony_ci %14 = OpString "#line 1 \"ps.hlsl\" 3606fd4e5da5Sopenharmony_cifloat4 main(float4 color : COLOR) : SV_TARGET { 3607fd4e5da5Sopenharmony_ci return color; 3608fd4e5da5Sopenharmony_ci} 3609fd4e5da5Sopenharmony_ci" 3610fd4e5da5Sopenharmony_ci %17 = OpString "float" 3611fd4e5da5Sopenharmony_ci %21 = OpString "src.main" 3612fd4e5da5Sopenharmony_ci %24 = OpString "color" 3613fd4e5da5Sopenharmony_ci OpName %in_var_COLOR "in.var.COLOR" 3614fd4e5da5Sopenharmony_ci OpName %out_var_SV_TARGET "out.var.SV_TARGET" 3615fd4e5da5Sopenharmony_ci OpName %main "main" 3616fd4e5da5Sopenharmony_ci OpName %param_var_color "param.var.color" 3617fd4e5da5Sopenharmony_ci OpName %src_main "src.main" 3618fd4e5da5Sopenharmony_ci OpName %color "color" 3619fd4e5da5Sopenharmony_ci OpName %bb_entry "bb.entry" 3620fd4e5da5Sopenharmony_ci OpDecorate %in_var_COLOR Location 0 3621fd4e5da5Sopenharmony_ci OpDecorate %out_var_SV_TARGET Location 0 3622fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 3623fd4e5da5Sopenharmony_ci %uint_32 = OpConstant %uint 32 3624fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 3625fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 3626fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 3627fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 3628fd4e5da5Sopenharmony_ci %void = OpTypeVoid 3629fd4e5da5Sopenharmony_ci %27 = OpTypeFunction %void 3630fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 3631fd4e5da5Sopenharmony_ci %33 = OpTypeFunction %v4float %_ptr_Function_v4float 3632fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input 3633fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output 3634fd4e5da5Sopenharmony_ci %13 = OpExtInst %void %1 DebugExpression 3635fd4e5da5Sopenharmony_ci %15 = OpExtInst %void %1 DebugSource %5 %14 3636fd4e5da5Sopenharmony_ci %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL 3637fd4e5da5Sopenharmony_ci %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float 3638fd4e5da5Sopenharmony_ci %19 = OpExtInst %void %1 DebugTypeVector %18 4 3639fd4e5da5Sopenharmony_ci %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %19 %19 3640fd4e5da5Sopenharmony_ci %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %src_main 3641fd4e5da5Sopenharmony_ci %25 = OpExtInst %void %1 DebugLocalVariable %24 %19 %15 1 20 %22 FlagIsLocal 0 3642fd4e5da5Sopenharmony_ci %26 = OpExtInst %void %1 DebugLexicalBlock %15 1 47 %22 3643fd4e5da5Sopenharmony_ci %main = OpFunction %void None %27 3644fd4e5da5Sopenharmony_ci %28 = OpLabel 3645fd4e5da5Sopenharmony_ci%param_var_color = OpVariable %_ptr_Function_v4float Function 3646fd4e5da5Sopenharmony_ci %31 = OpLoad %v4float %in_var_COLOR 3647fd4e5da5Sopenharmony_ci OpStore %param_var_color %31 3648fd4e5da5Sopenharmony_ci %32 = OpFunctionCall %v4float %src_main %param_var_color 3649fd4e5da5Sopenharmony_ci OpStore %out_var_SV_TARGET %32 3650fd4e5da5Sopenharmony_ci OpReturn 3651fd4e5da5Sopenharmony_ci OpFunctionEnd 3652fd4e5da5Sopenharmony_ci OpLine %5 1 1 3653fd4e5da5Sopenharmony_ci %src_main = OpFunction %v4float None %33 3654fd4e5da5Sopenharmony_ci %34 = OpExtInst %void %1 DebugScope %22 3655fd4e5da5Sopenharmony_ci %color = OpFunctionParameter %_ptr_Function_v4float 3656fd4e5da5Sopenharmony_ci %36 = OpExtInst %void %1 DebugDeclare %25 %color %13 3657fd4e5da5Sopenharmony_ci %bb_entry = OpLabel 3658fd4e5da5Sopenharmony_ci %38 = OpExtInst %void %1 DebugScope %26 3659fd4e5da5Sopenharmony_ci OpLine %5 2 10 3660fd4e5da5Sopenharmony_ci %39 = OpLoad %v4float %color 3661fd4e5da5Sopenharmony_ci OpLine %5 2 3 3662fd4e5da5Sopenharmony_ci OpReturnValue %39 3663fd4e5da5Sopenharmony_ci OpFunctionEnd 3664fd4e5da5Sopenharmony_ci)"; 3665fd4e5da5Sopenharmony_ci 3666fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 3667fd4e5da5Sopenharmony_ci} 3668fd4e5da5Sopenharmony_ci 3669fd4e5da5Sopenharmony_ciTEST_F(InlineTest, ShaderDebugSimpleHLSLPixelShader) { 3670fd4e5da5Sopenharmony_ci // Same as DebugSimpleHLSLPixelShader but for 3671fd4e5da5Sopenharmony_ci // NonSemantic.Shader.DebugInfo.100. 3672fd4e5da5Sopenharmony_ci const std::string text = R"( 3673fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} %uint_1 %uint_1 {{%\d+}} {{%\d+}} %uint_3 %uint_1 3674fd4e5da5Sopenharmony_ci; CHECK: [[lex_blk:%\d+]] = OpExtInst %void [[ext]] DebugLexicalBlock {{%\d+}} %uint_1 %uint_47 [[dbg_main]] 3675fd4e5da5Sopenharmony_ci; CHECK: %main = OpFunction %void None 3676fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_main]] 3677fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare {{%\d+}} %param_var_color 3678fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[lex_blk]] 3679fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void %1 DebugLine {{%\d+}} %uint_2 %uint_2 %uint_10 %uint_10 3680fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpLoad %v4float %param_var_color 3681fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void %1 DebugLine {{%\d+}} %uint_2 %uint_2 %uint_3 %uint_3 3682fd4e5da5Sopenharmony_ci; CHECK: OpFunctionEnd 3683fd4e5da5Sopenharmony_ci; CHECK: %src_main = OpFunction %v4float None 3684fd4e5da5Sopenharmony_ci OpCapability Shader 3685fd4e5da5Sopenharmony_ci OpExtension "SPV_KHR_non_semantic_info" 3686fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" 3687fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3688fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET 3689fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 3690fd4e5da5Sopenharmony_ci %5 = OpString "ps.hlsl" 3691fd4e5da5Sopenharmony_ci OpSource HLSL 600 %5 3692fd4e5da5Sopenharmony_ci %14 = OpString "#line 1 \"ps.hlsl\" 3693fd4e5da5Sopenharmony_cifloat4 main(float4 color : COLOR) : SV_TARGET { 3694fd4e5da5Sopenharmony_ci return color; 3695fd4e5da5Sopenharmony_ci} 3696fd4e5da5Sopenharmony_ci" 3697fd4e5da5Sopenharmony_ci %17 = OpString "float" 3698fd4e5da5Sopenharmony_ci %21 = OpString "src.main" 3699fd4e5da5Sopenharmony_ci %24 = OpString "color" 3700fd4e5da5Sopenharmony_ci OpName %in_var_COLOR "in.var.COLOR" 3701fd4e5da5Sopenharmony_ci OpName %out_var_SV_TARGET "out.var.SV_TARGET" 3702fd4e5da5Sopenharmony_ci OpName %main "main" 3703fd4e5da5Sopenharmony_ci OpName %param_var_color "param.var.color" 3704fd4e5da5Sopenharmony_ci OpName %src_main "src.main" 3705fd4e5da5Sopenharmony_ci OpName %color "color" 3706fd4e5da5Sopenharmony_ci OpName %bb_entry "bb.entry" 3707fd4e5da5Sopenharmony_ci OpDecorate %in_var_COLOR Location 0 3708fd4e5da5Sopenharmony_ci OpDecorate %out_var_SV_TARGET Location 0 3709fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 3710fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 3711fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 3712fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 3713fd4e5da5Sopenharmony_ci %uint_3 = OpConstant %uint 3 3714fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 3715fd4e5da5Sopenharmony_ci %uint_5 = OpConstant %uint 5 3716fd4e5da5Sopenharmony_ci %uint_10 = OpConstant %uint 10 3717fd4e5da5Sopenharmony_ci %uint_20 = OpConstant %uint 20 3718fd4e5da5Sopenharmony_ci %uint_32 = OpConstant %uint 32 3719fd4e5da5Sopenharmony_ci %uint_47 = OpConstant %uint 47 3720fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 3721fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 3722fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 3723fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 3724fd4e5da5Sopenharmony_ci %void = OpTypeVoid 3725fd4e5da5Sopenharmony_ci %27 = OpTypeFunction %void 3726fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 3727fd4e5da5Sopenharmony_ci %33 = OpTypeFunction %v4float %_ptr_Function_v4float 3728fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input 3729fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output 3730fd4e5da5Sopenharmony_ci %13 = OpExtInst %void %1 DebugExpression 3731fd4e5da5Sopenharmony_ci %15 = OpExtInst %void %1 DebugSource %5 %14 3732fd4e5da5Sopenharmony_ci %16 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %15 %uint_5 3733fd4e5da5Sopenharmony_ci %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 %uint_3 %uint_0 3734fd4e5da5Sopenharmony_ci %19 = OpExtInst %void %1 DebugTypeVector %18 %uint_4 3735fd4e5da5Sopenharmony_ci %20 = OpExtInst %void %1 DebugTypeFunction %uint_3 %19 %19 3736fd4e5da5Sopenharmony_ci %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 %uint_1 %uint_1 %16 %21 %uint_3 %uint_1 3737fd4e5da5Sopenharmony_ci %25 = OpExtInst %void %1 DebugLocalVariable %24 %19 %15 %uint_1 %uint_20 %22 %uint_4 %uint_0 3738fd4e5da5Sopenharmony_ci %26 = OpExtInst %void %1 DebugLexicalBlock %15 %uint_1 %uint_47 %22 3739fd4e5da5Sopenharmony_ci %main = OpFunction %void None %27 3740fd4e5da5Sopenharmony_ci %28 = OpLabel 3741fd4e5da5Sopenharmony_ci%param_var_color = OpVariable %_ptr_Function_v4float Function 3742fd4e5da5Sopenharmony_ci %31 = OpLoad %v4float %in_var_COLOR 3743fd4e5da5Sopenharmony_ci OpStore %param_var_color %31 3744fd4e5da5Sopenharmony_ci %32 = OpFunctionCall %v4float %src_main %param_var_color 3745fd4e5da5Sopenharmony_ci OpStore %out_var_SV_TARGET %32 3746fd4e5da5Sopenharmony_ci OpReturn 3747fd4e5da5Sopenharmony_ci OpFunctionEnd 3748fd4e5da5Sopenharmony_ci %src_main = OpFunction %v4float None %33 3749fd4e5da5Sopenharmony_ci %color = OpFunctionParameter %_ptr_Function_v4float 3750fd4e5da5Sopenharmony_ci %bb_entry = OpLabel 3751fd4e5da5Sopenharmony_ci %140 = OpExtInst %void %1 DebugFunctionDefinition %22 %src_main 3752fd4e5da5Sopenharmony_ci %141 = OpExtInst %void %1 DebugLine %5 %uint_1 %uint_1 %uint_1 %uint_1 3753fd4e5da5Sopenharmony_ci %34 = OpExtInst %void %1 DebugScope %22 3754fd4e5da5Sopenharmony_ci %36 = OpExtInst %void %1 DebugDeclare %25 %color %13 3755fd4e5da5Sopenharmony_ci %38 = OpExtInst %void %1 DebugScope %26 3756fd4e5da5Sopenharmony_ci %142 = OpExtInst %void %1 DebugLine %5 %uint_2 %uint_2 %uint_10 %uint_10 3757fd4e5da5Sopenharmony_ci %39 = OpLoad %v4float %color 3758fd4e5da5Sopenharmony_ci %143 = OpExtInst %void %1 DebugLine %5 %uint_2 %uint_2 %uint_3 %uint_3 3759fd4e5da5Sopenharmony_ci OpReturnValue %39 3760fd4e5da5Sopenharmony_ci OpFunctionEnd 3761fd4e5da5Sopenharmony_ci)"; 3762fd4e5da5Sopenharmony_ci 3763fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 3764fd4e5da5Sopenharmony_ci} 3765fd4e5da5Sopenharmony_ci 3766fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugDeclareForCalleeFunctionParam) { 3767fd4e5da5Sopenharmony_ci // Check that InlinePass correctly generates DebugDeclare instructions 3768fd4e5da5Sopenharmony_ci // for callee function's parameters and maps them to corresponding 3769fd4e5da5Sopenharmony_ci // local variables of caller function. 3770fd4e5da5Sopenharmony_ci const std::string text = R"( 3771fd4e5da5Sopenharmony_ci; CHECK: [[add:%\d+]] = OpString "add" 3772fd4e5da5Sopenharmony_ci; CHECK: [[a:%\d+]] = OpString "a" 3773fd4e5da5Sopenharmony_ci; CHECK: [[b:%\d+]] = OpString "b" 3774fd4e5da5Sopenharmony_ci; CHECK: [[dbg_add:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[add]] 3775fd4e5da5Sopenharmony_ci; CHECK: [[dbg_a:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[a]] 3776fd4e5da5Sopenharmony_ci; CHECK: [[dbg_b:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[b]] 3777fd4e5da5Sopenharmony_ci; CHECK: [[inlinedat:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 5 3778fd4e5da5Sopenharmony_ci; CHECK: OpStore [[param_a:%\d+]] 3779fd4e5da5Sopenharmony_ci; CHECK: OpStore [[param_b:%\d+]] 3780fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_add]] [[inlinedat]] 3781fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare [[dbg_a]] [[param_a]] 3782fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare [[dbg_b]] [[param_b]] 3783fd4e5da5Sopenharmony_ci 3784fd4e5da5Sopenharmony_ciOpCapability Shader 3785fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 3786fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 3787fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET 3788fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 3789fd4e5da5Sopenharmony_ci%file_name = OpString "ps.hlsl" 3790fd4e5da5Sopenharmony_ciOpSource HLSL 600 %file_name 3791fd4e5da5Sopenharmony_ci%float_name = OpString "float" 3792fd4e5da5Sopenharmony_ci%main_name = OpString "main" 3793fd4e5da5Sopenharmony_ci%add_name = OpString "add" 3794fd4e5da5Sopenharmony_ci%a_name = OpString "a" 3795fd4e5da5Sopenharmony_ci%b_name = OpString "b" 3796fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0 3797fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0 3798fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 3799fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 3800fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 3801fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 3802fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2 3803fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 3804fd4e5da5Sopenharmony_ci%v4f1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 3805fd4e5da5Sopenharmony_ci%v4f2 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 3806fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 3807fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 3808fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 3809fd4e5da5Sopenharmony_ci%add_fn_type = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float 3810fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3811fd4e5da5Sopenharmony_ci%void_fn_type = OpTypeFunction %void 3812fd4e5da5Sopenharmony_ci%v4f_fn_type = OpTypeFunction %v4float 3813fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input 3814fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output 3815fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression 3816fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name 3817fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL 3818fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float 3819fd4e5da5Sopenharmony_ci%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_f 4 3820fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f 3821fd4e5da5Sopenharmony_ci%add_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f %dbg_v4f 3822fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 5 1 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main 3823fd4e5da5Sopenharmony_ci%dbg_add = OpExtInst %void %ext DebugFunction %add_name %add_ty %src 1 1 %cu %add_name FlagIsProtected|FlagIsPrivate 1 %add 3824fd4e5da5Sopenharmony_ci%dbg_a = OpExtInst %void %ext DebugLocalVariable %a_name %dbg_v4f %src 1 13 %dbg_add FlagIsLocal 0 3825fd4e5da5Sopenharmony_ci%dbg_b = OpExtInst %void %ext DebugLocalVariable %b_name %dbg_v4f %src 1 20 %dbg_add FlagIsLocal 1 3826fd4e5da5Sopenharmony_ci%add_lb = OpExtInst %void %ext DebugLexicalBlock %src 1 23 %dbg_add 3827fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn_type 3828fd4e5da5Sopenharmony_ci%main_bb = OpLabel 3829fd4e5da5Sopenharmony_ci%param_a = OpVariable %_ptr_Function_v4float Function 3830fd4e5da5Sopenharmony_ci%param_b = OpVariable %_ptr_Function_v4float Function 3831fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main 3832fd4e5da5Sopenharmony_ciOpStore %param_a %v4f1 3833fd4e5da5Sopenharmony_ciOpStore %param_b %v4f2 3834fd4e5da5Sopenharmony_ci%result = OpFunctionCall %v4float %add %param_a %param_b 3835fd4e5da5Sopenharmony_ciOpStore %out_var_SV_TARGET %result 3836fd4e5da5Sopenharmony_ciOpReturn 3837fd4e5da5Sopenharmony_ciOpFunctionEnd 3838fd4e5da5Sopenharmony_ci%add = OpFunction %v4float None %add_fn_type 3839fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %dbg_add 3840fd4e5da5Sopenharmony_ci%a = OpFunctionParameter %_ptr_Function_v4float 3841fd4e5da5Sopenharmony_ci%b = OpFunctionParameter %_ptr_Function_v4float 3842fd4e5da5Sopenharmony_ci%decl0 = OpExtInst %void %ext DebugDeclare %dbg_a %a %null_expr 3843fd4e5da5Sopenharmony_ci%decl1 = OpExtInst %void %ext DebugDeclare %dbg_b %b %null_expr 3844fd4e5da5Sopenharmony_ci%add_bb = OpLabel 3845fd4e5da5Sopenharmony_ci%scope2 = OpExtInst %void %ext DebugScope %add_lb 3846fd4e5da5Sopenharmony_ci%a_val = OpLoad %v4float %a 3847fd4e5da5Sopenharmony_ci%b_val = OpLoad %v4float %b 3848fd4e5da5Sopenharmony_ci%res = OpFAdd %v4float %a_val %b_val 3849fd4e5da5Sopenharmony_ciOpReturnValue %res 3850fd4e5da5Sopenharmony_ciOpFunctionEnd 3851fd4e5da5Sopenharmony_ci)"; 3852fd4e5da5Sopenharmony_ci 3853fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 3854fd4e5da5Sopenharmony_ci} 3855fd4e5da5Sopenharmony_ci 3856fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugDeclareForCalleeLocalVar) { 3857fd4e5da5Sopenharmony_ci // Check that InlinePass correctly generates DebugDeclare instructions 3858fd4e5da5Sopenharmony_ci // for callee function's local variables and maps them to corresponding 3859fd4e5da5Sopenharmony_ci // local variables of caller function. 3860fd4e5da5Sopenharmony_ci const std::string text = R"( 3861fd4e5da5Sopenharmony_ci; CHECK: [[add:%\d+]] = OpString "add" 3862fd4e5da5Sopenharmony_ci; CHECK: [[foo:%\d+]] = OpString "foo" 3863fd4e5da5Sopenharmony_ci; CHECK: [[dbg_add:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[add]] 3864fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[foo]] {{%\d+}} {{%\d+}} 2 2 [[dbg_add]] 3865fd4e5da5Sopenharmony_ci; CHECK: [[inlinedat:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 5 3866fd4e5da5Sopenharmony_ci 3867fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_add]] [[inlinedat]] 3868fd4e5da5Sopenharmony_ci; CHECK: [[new_foo:%\d+]] = OpVariable %_ptr_Function_v4float Function 3869fd4e5da5Sopenharmony_ci 3870fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_add]] [[inlinedat]] 3871fd4e5da5Sopenharmony_ci; CHECK: [[a_val:%\d+]] = OpLoad %v4float 3872fd4e5da5Sopenharmony_ci; CHECK: [[b_val:%\d+]] = OpLoad %v4float 3873fd4e5da5Sopenharmony_ci; CHECK: [[res:%\d+]] = OpFAdd %v4float [[a_val]] [[b_val]] 3874fd4e5da5Sopenharmony_ci; CHECK: OpStore [[new_foo]] [[res]] 3875fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare [[dbg_foo]] [[new_foo]] 3876fd4e5da5Sopenharmony_ci 3877fd4e5da5Sopenharmony_ciOpCapability Shader 3878fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 3879fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 3880fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET 3881fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 3882fd4e5da5Sopenharmony_ci%file_name = OpString "ps.hlsl" 3883fd4e5da5Sopenharmony_ciOpSource HLSL 600 %file_name 3884fd4e5da5Sopenharmony_ci%float_name = OpString "float" 3885fd4e5da5Sopenharmony_ci%main_name = OpString "main" 3886fd4e5da5Sopenharmony_ci%add_name = OpString "add" 3887fd4e5da5Sopenharmony_ci%foo_name = OpString "foo" 3888fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0 3889fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0 3890fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 3891fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 3892fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 3893fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 3894fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2 3895fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 3896fd4e5da5Sopenharmony_ci%v4f1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 3897fd4e5da5Sopenharmony_ci%v4f2 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 3898fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 3899fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 3900fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 3901fd4e5da5Sopenharmony_ci%add_fn_type = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float 3902fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3903fd4e5da5Sopenharmony_ci%void_fn_type = OpTypeFunction %void 3904fd4e5da5Sopenharmony_ci%v4f_fn_type = OpTypeFunction %v4float 3905fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input 3906fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output 3907fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression 3908fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name 3909fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL 3910fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float 3911fd4e5da5Sopenharmony_ci%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_f 4 3912fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f 3913fd4e5da5Sopenharmony_ci%add_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f %dbg_v4f 3914fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 5 1 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main 3915fd4e5da5Sopenharmony_ci%dbg_add = OpExtInst %void %ext DebugFunction %add_name %add_ty %src 1 1 %cu %add_name FlagIsProtected|FlagIsPrivate 1 %add 3916fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %void %ext DebugLocalVariable %foo_name %dbg_v4f %src 2 2 %dbg_add FlagIsLocal 3917fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn_type 3918fd4e5da5Sopenharmony_ci%main_bb = OpLabel 3919fd4e5da5Sopenharmony_ci%param_a = OpVariable %_ptr_Function_v4float Function 3920fd4e5da5Sopenharmony_ci%param_b = OpVariable %_ptr_Function_v4float Function 3921fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main 3922fd4e5da5Sopenharmony_ciOpStore %param_a %v4f1 3923fd4e5da5Sopenharmony_ciOpStore %param_b %v4f2 3924fd4e5da5Sopenharmony_ci%result = OpFunctionCall %v4float %add %param_a %param_b 3925fd4e5da5Sopenharmony_ciOpStore %out_var_SV_TARGET %result 3926fd4e5da5Sopenharmony_ciOpReturn 3927fd4e5da5Sopenharmony_ciOpFunctionEnd 3928fd4e5da5Sopenharmony_ci%add = OpFunction %v4float None %add_fn_type 3929fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %dbg_add 3930fd4e5da5Sopenharmony_ci%a = OpFunctionParameter %_ptr_Function_v4float 3931fd4e5da5Sopenharmony_ci%b = OpFunctionParameter %_ptr_Function_v4float 3932fd4e5da5Sopenharmony_ci%add_bb = OpLabel 3933fd4e5da5Sopenharmony_ci%foo = OpVariable %_ptr_Function_v4float Function 3934fd4e5da5Sopenharmony_ci%a_val = OpLoad %v4float %a 3935fd4e5da5Sopenharmony_ci%b_val = OpLoad %v4float %b 3936fd4e5da5Sopenharmony_ci%res = OpFAdd %v4float %a_val %b_val 3937fd4e5da5Sopenharmony_ciOpStore %foo %res 3938fd4e5da5Sopenharmony_ci%decl = OpExtInst %void %ext DebugDeclare %dbg_foo %foo %null_expr 3939fd4e5da5Sopenharmony_ci%foo_val = OpLoad %v4float %foo 3940fd4e5da5Sopenharmony_ciOpReturnValue %foo_val 3941fd4e5da5Sopenharmony_ciOpFunctionEnd 3942fd4e5da5Sopenharmony_ci)"; 3943fd4e5da5Sopenharmony_ci 3944fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 3945fd4e5da5Sopenharmony_ci} 3946fd4e5da5Sopenharmony_ci 3947fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugDeclareMultiple) { 3948fd4e5da5Sopenharmony_ci // Check that InlinePass correctly generates DebugDeclare instructions 3949fd4e5da5Sopenharmony_ci // for callee function's parameters and maps them to corresponding 3950fd4e5da5Sopenharmony_ci // local variables of caller function. 3951fd4e5da5Sopenharmony_ci const std::string text = R"( 3952fd4e5da5Sopenharmony_ci; CHECK: [[add:%\d+]] = OpString "add" 3953fd4e5da5Sopenharmony_ci; CHECK: [[a:%\d+]] = OpString "a" 3954fd4e5da5Sopenharmony_ci; CHECK: [[b:%\d+]] = OpString "b" 3955fd4e5da5Sopenharmony_ci; CHECK: [[dbg_add:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[add]] 3956fd4e5da5Sopenharmony_ci; CHECK: [[dbg_a:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[a]] 3957fd4e5da5Sopenharmony_ci; CHECK: [[dbg_b:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[b]] 3958fd4e5da5Sopenharmony_ci; CHECK: OpFunction 3959fd4e5da5Sopenharmony_ci; CHECK-NOT: OpFunctionEnd 3960fd4e5da5Sopenharmony_ci; CHECK: OpStore [[param_a:%\d+]] 3961fd4e5da5Sopenharmony_ci; CHECK: OpStore [[param_b:%\d+]] 3962fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_add]] 3963fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare [[dbg_a]] [[param_a]] 3964fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare [[dbg_b]] [[param_b]] 3965fd4e5da5Sopenharmony_ci; CHECK: [[a_val:%\d+]] = OpLoad %v4float [[param_a]] 3966fd4e5da5Sopenharmony_ci; CHECK: OpStore [[foo:%\d+]] [[a_val]] 3967fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugValue [[dbg_a]] [[foo]] 3968fd4e5da5Sopenharmony_ci 3969fd4e5da5Sopenharmony_ciOpCapability Shader 3970fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 3971fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 3972fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET 3973fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 3974fd4e5da5Sopenharmony_ci%file_name = OpString "ps.hlsl" 3975fd4e5da5Sopenharmony_ciOpSource HLSL 600 %file_name 3976fd4e5da5Sopenharmony_ci%float_name = OpString "float" 3977fd4e5da5Sopenharmony_ci%main_name = OpString "main" 3978fd4e5da5Sopenharmony_ci%add_name = OpString "add" 3979fd4e5da5Sopenharmony_ci%a_name = OpString "a" 3980fd4e5da5Sopenharmony_ci%b_name = OpString "b" 3981fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0 3982fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0 3983fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 3984fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 3985fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 3986fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 3987fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2 3988fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 3989fd4e5da5Sopenharmony_ci%v4f1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 3990fd4e5da5Sopenharmony_ci%v4f2 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 3991fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 3992fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 3993fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 3994fd4e5da5Sopenharmony_ci%add_fn_type = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float 3995fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3996fd4e5da5Sopenharmony_ci%void_fn_type = OpTypeFunction %void 3997fd4e5da5Sopenharmony_ci%v4f_fn_type = OpTypeFunction %v4float 3998fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input 3999fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output 4000fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression 4001fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name 4002fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL 4003fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float 4004fd4e5da5Sopenharmony_ci%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_f 4 4005fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f 4006fd4e5da5Sopenharmony_ci%add_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f %dbg_v4f 4007fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 5 1 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main 4008fd4e5da5Sopenharmony_ci%dbg_add = OpExtInst %void %ext DebugFunction %add_name %add_ty %src 1 1 %cu %add_name FlagIsProtected|FlagIsPrivate 1 %add 4009fd4e5da5Sopenharmony_ci%dbg_a = OpExtInst %void %ext DebugLocalVariable %a_name %dbg_v4f %src 1 13 %dbg_add FlagIsLocal 0 4010fd4e5da5Sopenharmony_ci%dbg_b = OpExtInst %void %ext DebugLocalVariable %b_name %dbg_v4f %src 1 20 %dbg_add FlagIsLocal 1 4011fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn_type 4012fd4e5da5Sopenharmony_ci%main_bb = OpLabel 4013fd4e5da5Sopenharmony_ci%param_a = OpVariable %_ptr_Function_v4float Function 4014fd4e5da5Sopenharmony_ci%param_b = OpVariable %_ptr_Function_v4float Function 4015fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main 4016fd4e5da5Sopenharmony_ciOpStore %param_a %v4f1 4017fd4e5da5Sopenharmony_ciOpStore %param_b %v4f2 4018fd4e5da5Sopenharmony_ci%result = OpFunctionCall %v4float %add %param_a %param_b 4019fd4e5da5Sopenharmony_ciOpStore %out_var_SV_TARGET %result 4020fd4e5da5Sopenharmony_ciOpReturn 4021fd4e5da5Sopenharmony_ciOpFunctionEnd 4022fd4e5da5Sopenharmony_ci%add = OpFunction %v4float None %add_fn_type 4023fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %dbg_add 4024fd4e5da5Sopenharmony_ci%a = OpFunctionParameter %_ptr_Function_v4float 4025fd4e5da5Sopenharmony_ci%b = OpFunctionParameter %_ptr_Function_v4float 4026fd4e5da5Sopenharmony_ci%decl0 = OpExtInst %void %ext DebugDeclare %dbg_a %a %null_expr 4027fd4e5da5Sopenharmony_ci%add_bb = OpLabel 4028fd4e5da5Sopenharmony_ci%decl1 = OpExtInst %void %ext DebugDeclare %dbg_b %b %null_expr 4029fd4e5da5Sopenharmony_ci%foo = OpVariable %_ptr_Function_v4float Function 4030fd4e5da5Sopenharmony_ci%a_val = OpLoad %v4float %a 4031fd4e5da5Sopenharmony_ciOpStore %foo %a_val 4032fd4e5da5Sopenharmony_ci%dbg_val = OpExtInst %void %ext DebugValue %dbg_a %foo %null_expr 4033fd4e5da5Sopenharmony_ci%b_val = OpLoad %v4float %b 4034fd4e5da5Sopenharmony_ci%res = OpFAdd %v4float %a_val %b_val 4035fd4e5da5Sopenharmony_ciOpReturnValue %res 4036fd4e5da5Sopenharmony_ciOpFunctionEnd 4037fd4e5da5Sopenharmony_ci)"; 4038fd4e5da5Sopenharmony_ci 4039fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 4040fd4e5da5Sopenharmony_ci} 4041fd4e5da5Sopenharmony_ci 4042fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugValueForFunctionCallReturn) { 4043fd4e5da5Sopenharmony_ci // Check that InlinePass correctly generates DebugValue instruction 4044fd4e5da5Sopenharmony_ci // for function call's return value and maps it to a corresponding 4045fd4e5da5Sopenharmony_ci // value in the caller function. 4046fd4e5da5Sopenharmony_ci const std::string text = R"( 4047fd4e5da5Sopenharmony_ci; CHECK: [[main:%\d+]] = OpString "main" 4048fd4e5da5Sopenharmony_ci; CHECK: [[add:%\d+]] = OpString "add" 4049fd4e5da5Sopenharmony_ci; CHECK: [[result:%\d+]] = OpString "result" 4050fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[main]] 4051fd4e5da5Sopenharmony_ci; CHECK: [[dbg_add:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[add]] 4052fd4e5da5Sopenharmony_ci; CHECK: [[dbg_result:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[result]] {{%\d+}} {{%\d+}} 6 2 [[dbg_main]] 4053fd4e5da5Sopenharmony_ci; CHECK: [[inlinedat:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 5 4054fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_add]] [[inlinedat]] 4055fd4e5da5Sopenharmony_ci; CHECK: [[a_val:%\d+]] = OpLoad %v4float 4056fd4e5da5Sopenharmony_ci; CHECK: [[b_val:%\d+]] = OpLoad %v4float 4057fd4e5da5Sopenharmony_ci; CHECK: [[res:%\d+]] = OpFAdd %v4float [[a_val]] [[b_val]] 4058fd4e5da5Sopenharmony_ci; CHECK: OpStore [[new_result:%\d+]] [[res]] 4059fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_main]] 4060fd4e5da5Sopenharmony_ci; CHECK: [[result_val:%\d+]] = OpLoad %v4float [[new_result]] 4061fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugValue [[dbg_result]] [[result_val]] 4062fd4e5da5Sopenharmony_ci 4063fd4e5da5Sopenharmony_ciOpCapability Shader 4064fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 4065fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 4066fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET 4067fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 4068fd4e5da5Sopenharmony_ci%file_name = OpString "ps.hlsl" 4069fd4e5da5Sopenharmony_ciOpSource HLSL 600 %file_name 4070fd4e5da5Sopenharmony_ci%float_name = OpString "float" 4071fd4e5da5Sopenharmony_ci%main_name = OpString "main" 4072fd4e5da5Sopenharmony_ci%add_name = OpString "add" 4073fd4e5da5Sopenharmony_ci%result_name = OpString "result" 4074fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0 4075fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0 4076fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 4077fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 4078fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 4079fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 4080fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2 4081fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 4082fd4e5da5Sopenharmony_ci%v4f1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 4083fd4e5da5Sopenharmony_ci%v4f2 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 4084fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 4085fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 4086fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 4087fd4e5da5Sopenharmony_ci%add_fn_type = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float 4088fd4e5da5Sopenharmony_ci%void = OpTypeVoid 4089fd4e5da5Sopenharmony_ci%void_fn_type = OpTypeFunction %void 4090fd4e5da5Sopenharmony_ci%v4f_fn_type = OpTypeFunction %v4float 4091fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input 4092fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output 4093fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression 4094fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name 4095fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL 4096fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float 4097fd4e5da5Sopenharmony_ci%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_f 4 4098fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f 4099fd4e5da5Sopenharmony_ci%add_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f %dbg_v4f 4100fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 5 1 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main 4101fd4e5da5Sopenharmony_ci%dbg_add = OpExtInst %void %ext DebugFunction %add_name %add_ty %src 1 1 %cu %add_name FlagIsProtected|FlagIsPrivate 1 %add 4102fd4e5da5Sopenharmony_ci%dbg_result = OpExtInst %void %ext DebugLocalVariable %result_name %dbg_v4f %src 6 2 %dbg_main FlagIsLocal 4103fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn_type 4104fd4e5da5Sopenharmony_ci%main_bb = OpLabel 4105fd4e5da5Sopenharmony_ci%param_a = OpVariable %_ptr_Function_v4float Function 4106fd4e5da5Sopenharmony_ci%param_b = OpVariable %_ptr_Function_v4float Function 4107fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main 4108fd4e5da5Sopenharmony_ciOpStore %param_a %v4f1 4109fd4e5da5Sopenharmony_ciOpStore %param_b %v4f2 4110fd4e5da5Sopenharmony_ci%result = OpFunctionCall %v4float %add %param_a %param_b 4111fd4e5da5Sopenharmony_ci%value = OpExtInst %void %ext DebugValue %dbg_result %result %null_expr 4112fd4e5da5Sopenharmony_ciOpStore %out_var_SV_TARGET %result 4113fd4e5da5Sopenharmony_ciOpReturn 4114fd4e5da5Sopenharmony_ciOpFunctionEnd 4115fd4e5da5Sopenharmony_ci%add = OpFunction %v4float None %add_fn_type 4116fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %dbg_add 4117fd4e5da5Sopenharmony_ci%a = OpFunctionParameter %_ptr_Function_v4float 4118fd4e5da5Sopenharmony_ci%b = OpFunctionParameter %_ptr_Function_v4float 4119fd4e5da5Sopenharmony_ci%add_bb = OpLabel 4120fd4e5da5Sopenharmony_ci%a_val = OpLoad %v4float %a 4121fd4e5da5Sopenharmony_ci%b_val = OpLoad %v4float %b 4122fd4e5da5Sopenharmony_ci%res = OpFAdd %v4float %a_val %b_val 4123fd4e5da5Sopenharmony_ciOpReturnValue %res 4124fd4e5da5Sopenharmony_ciOpFunctionEnd 4125fd4e5da5Sopenharmony_ci)"; 4126fd4e5da5Sopenharmony_ci 4127fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 4128fd4e5da5Sopenharmony_ci} 4129fd4e5da5Sopenharmony_ci 4130fd4e5da5Sopenharmony_ciTEST_F(InlineTest, NestedWithAnExistingDebugInlinedAt) { 4131fd4e5da5Sopenharmony_ci // When a DebugScope instruction in a callee function already has a 4132fd4e5da5Sopenharmony_ci // DebugInlinedAt information, we have to create a recursive 4133fd4e5da5Sopenharmony_ci // DebugInlinedAt chain. See inlined_to_zoo and inlined_to_bar in 4134fd4e5da5Sopenharmony_ci // the following code. 4135fd4e5da5Sopenharmony_ci const std::string text = R"( 4136fd4e5da5Sopenharmony_ci; CHECK: [[main:%\d+]] = OpString "main" 4137fd4e5da5Sopenharmony_ci; CHECK: [[foo:%\d+]] = OpString "foo" 4138fd4e5da5Sopenharmony_ci; CHECK: [[bar:%\d+]] = OpString "bar" 4139fd4e5da5Sopenharmony_ci; CHECK: [[zoo:%\d+]] = OpString "zoo" 4140fd4e5da5Sopenharmony_ci; CHECK: [[v4f1:%\d+]] = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 4141fd4e5da5Sopenharmony_ci; CHECK: [[v4f2:%\d+]] = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 4142fd4e5da5Sopenharmony_ci; CHECK: [[v4f3:%\d+]] = OpConstantComposite %v4float %float_3 %float_3 %float_3 %float_3 4143fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[main]] 4144fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\d+]] = OpExtInst %void [[ext]] DebugFunction [[foo]] 4145fd4e5da5Sopenharmony_ci; CHECK: [[dbg_bar:%\d+]] = OpExtInst %void [[ext]] DebugFunction [[bar]] 4146fd4e5da5Sopenharmony_ci; CHECK: [[dbg_zoo:%\d+]] = OpExtInst %void [[ext]] DebugFunction [[zoo]] 4147fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_main:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 10 [[dbg_main]] 4148fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_zoo:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 7 [[dbg_zoo]] [[inlined_to_main]] 4149fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_main:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 10 [[dbg_main]] 4150fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_bar:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 4 [[dbg_bar]] [[inlined_to_zoo]] 4151fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_foo]] [[inlined_to_bar]] 4152fd4e5da5Sopenharmony_ci; CHECK: OpStore [[foo_ret:%\d+]] [[v4f1]] 4153fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_bar]] [[inlined_to_zoo]] 4154fd4e5da5Sopenharmony_ci; CHECK: [[foo_ret_val:%\d+]] = OpLoad %v4float [[foo_ret]] 4155fd4e5da5Sopenharmony_ci; CHECK: [[bar_ret:%\d+]] = OpFAdd %v4float [[foo_ret_val]] [[v4f2]] 4156fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_zoo]] [[inlined_to_main]] 4157fd4e5da5Sopenharmony_ci; CHECK: [[zoo_result:%\d+]] = OpFAdd %v4float [[bar_ret]] [[v4f3]] 4158fd4e5da5Sopenharmony_ci; CHECK: OpStore [[zoo_ret:%\d+]] [[zoo_result]] 4159fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_main]] 4160fd4e5da5Sopenharmony_ci; CHECK: [[zoo_ret_val:%\d+]] = OpLoad %v4float [[zoo_ret]] 4161fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpFAdd %v4float [[zoo_ret_val]] {{%\d+}} 4162fd4e5da5Sopenharmony_ci 4163fd4e5da5Sopenharmony_ciOpCapability Shader 4164fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 4165fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 4166fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET 4167fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 4168fd4e5da5Sopenharmony_ci%file_name = OpString "ps.hlsl" 4169fd4e5da5Sopenharmony_ciOpSource HLSL 600 %file_name 4170fd4e5da5Sopenharmony_ci%float_name = OpString "float" 4171fd4e5da5Sopenharmony_ci%main_name = OpString "main" 4172fd4e5da5Sopenharmony_ci%foo_name = OpString "foo" 4173fd4e5da5Sopenharmony_ci%bar_name = OpString "bar" 4174fd4e5da5Sopenharmony_ci%zoo_name = OpString "zoo" 4175fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0 4176fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0 4177fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 4178fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 4179fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 4180fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 4181fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2 4182fd4e5da5Sopenharmony_ci%float_3 = OpConstant %float 3 4183fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 4184fd4e5da5Sopenharmony_ci%v4f1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 4185fd4e5da5Sopenharmony_ci%v4f2 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 4186fd4e5da5Sopenharmony_ci%v4f3 = OpConstantComposite %v4float %float_3 %float_3 %float_3 %float_3 4187fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 4188fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 4189fd4e5da5Sopenharmony_ci%void = OpTypeVoid 4190fd4e5da5Sopenharmony_ci%void_fn_type = OpTypeFunction %void 4191fd4e5da5Sopenharmony_ci%v4f_fn_type = OpTypeFunction %v4float 4192fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input 4193fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output 4194fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name 4195fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL 4196fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float 4197fd4e5da5Sopenharmony_ci%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_f 4 4198fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f 4199fd4e5da5Sopenharmony_ci%foo_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f 4200fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 10 1 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main 4201fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %void %ext DebugFunction %foo_name %foo_ty %src 1 1 %cu %foo_name FlagIsProtected|FlagIsPrivate 1 %foo 4202fd4e5da5Sopenharmony_ci%dbg_bar = OpExtInst %void %ext DebugFunction %bar_name %foo_ty %src 4 1 %cu %bar_name FlagIsProtected|FlagIsPrivate 4 %bar 4203fd4e5da5Sopenharmony_ci%dbg_zoo = OpExtInst %void %ext DebugFunction %zoo_name %foo_ty %src 7 1 %cu %zoo_name FlagIsProtected|FlagIsPrivate 7 %zoo 4204fd4e5da5Sopenharmony_ci%inlined_to_zoo = OpExtInst %void %ext DebugInlinedAt 7 %dbg_zoo 4205fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn_type 4206fd4e5da5Sopenharmony_ci%main_bb = OpLabel 4207fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main 4208fd4e5da5Sopenharmony_ci%zoo_val = OpFunctionCall %v4float %zoo 4209fd4e5da5Sopenharmony_ci%color = OpLoad %v4float %in_var_COLOR 4210fd4e5da5Sopenharmony_ci%result = OpFAdd %v4float %zoo_val %color 4211fd4e5da5Sopenharmony_ciOpStore %out_var_SV_TARGET %result 4212fd4e5da5Sopenharmony_ciOpReturn 4213fd4e5da5Sopenharmony_ciOpFunctionEnd 4214fd4e5da5Sopenharmony_ci%foo = OpFunction %v4float None %v4f_fn_type 4215fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %dbg_foo 4216fd4e5da5Sopenharmony_ci%foo_bb = OpLabel 4217fd4e5da5Sopenharmony_ciOpReturnValue %v4f1 4218fd4e5da5Sopenharmony_ciOpFunctionEnd 4219fd4e5da5Sopenharmony_ci%zoo = OpFunction %v4float None %v4f_fn_type 4220fd4e5da5Sopenharmony_ci%scope3 = OpExtInst %void %ext DebugScope %dbg_zoo 4221fd4e5da5Sopenharmony_ci%zoo_bb = OpLabel 4222fd4e5da5Sopenharmony_ci%scope2 = OpExtInst %void %ext DebugScope %dbg_bar %inlined_to_zoo 4223fd4e5da5Sopenharmony_ci%foo_val = OpFunctionCall %v4float %foo 4224fd4e5da5Sopenharmony_ci%bar_val = OpFAdd %v4float %foo_val %v4f2 4225fd4e5da5Sopenharmony_ci%scope4 = OpExtInst %void %ext DebugScope %dbg_zoo 4226fd4e5da5Sopenharmony_ci%zoo_ret = OpFAdd %v4float %bar_val %v4f3 4227fd4e5da5Sopenharmony_ciOpReturnValue %zoo_ret 4228fd4e5da5Sopenharmony_ciOpFunctionEnd 4229fd4e5da5Sopenharmony_ci%bar = OpFunction %v4float None %v4f_fn_type 4230fd4e5da5Sopenharmony_ci%scope5 = OpExtInst %void %ext DebugScope %dbg_bar 4231fd4e5da5Sopenharmony_ci%bar_bb = OpLabel 4232fd4e5da5Sopenharmony_ci%foo_val0 = OpFunctionCall %v4float %foo 4233fd4e5da5Sopenharmony_ci%bar_ret = OpFAdd %v4float %foo_val0 %v4f2 4234fd4e5da5Sopenharmony_ciOpReturnValue %bar_ret 4235fd4e5da5Sopenharmony_ciOpFunctionEnd 4236fd4e5da5Sopenharmony_ci)"; 4237fd4e5da5Sopenharmony_ci 4238fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 4239fd4e5da5Sopenharmony_ci} 4240fd4e5da5Sopenharmony_ci 4241fd4e5da5Sopenharmony_ciTEST_F(InlineTest, CreateConstantForInlinedAt) { 4242fd4e5da5Sopenharmony_ci // This shader causes CreateDebugInlinedAt to generate a constant. 4243fd4e5da5Sopenharmony_ci // Using the Constant manager would attempt to build the invalidated 4244fd4e5da5Sopenharmony_ci // DefUse manager during inlining which could cause an assert because 4245fd4e5da5Sopenharmony_ci // the function is in an inconsistent state. This test verifies that 4246fd4e5da5Sopenharmony_ci // CreateDebugInlinedAt detects that the DefUse manager is disabled 4247fd4e5da5Sopenharmony_ci // and creates a duplicate constant safely without the Constant manager. 4248fd4e5da5Sopenharmony_ci // 4249fd4e5da5Sopenharmony_ci // int function1() { 4250fd4e5da5Sopenharmony_ci // return 1; 4251fd4e5da5Sopenharmony_ci // } 4252fd4e5da5Sopenharmony_ci // 4253fd4e5da5Sopenharmony_ci // void main() { 4254fd4e5da5Sopenharmony_ci // function1(); 4255fd4e5da5Sopenharmony_ci // } 4256fd4e5da5Sopenharmony_ci 4257fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 4258fd4e5da5Sopenharmony_ci; CHECK: %uint_7 = OpConstant %uint 7 4259fd4e5da5Sopenharmony_ci; CHECK: %uint_7_0 = OpConstant %uint 7 4260fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void %1 DebugInlinedAt %uint_7_0 4261fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 4262fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" 4263fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 4264fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 4265fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 4266fd4e5da5Sopenharmony_ci%3 = OpString "parent3.hlsl" 4267fd4e5da5Sopenharmony_ci%8 = OpString "int" 4268fd4e5da5Sopenharmony_ci%19 = OpString "function1" 4269fd4e5da5Sopenharmony_ci%20 = OpString "" 4270fd4e5da5Sopenharmony_ci%26 = OpString "main" 4271fd4e5da5Sopenharmony_ciOpName %main "main" 4272fd4e5da5Sopenharmony_ciOpName %src_main "src.main" 4273fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry" 4274fd4e5da5Sopenharmony_ciOpName %function1 "function1" 4275fd4e5da5Sopenharmony_ciOpName %bb_entry_0 "bb.entry" 4276fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 4277fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 4278fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 4279fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 4280fd4e5da5Sopenharmony_ci%void = OpTypeVoid 4281fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4 4282fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 4283fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3 4284fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 4285fd4e5da5Sopenharmony_ci%uint_5 = OpConstant %uint 5 4286fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2 4287fd4e5da5Sopenharmony_ci%uint_17 = OpConstant %uint 17 4288fd4e5da5Sopenharmony_ci%uint_6 = OpConstant %uint 6 4289fd4e5da5Sopenharmony_ci%uint_13 = OpConstant %uint 13 4290fd4e5da5Sopenharmony_ci%uint_7 = OpConstant %uint 7 4291fd4e5da5Sopenharmony_ci%31 = OpTypeFunction %void 4292fd4e5da5Sopenharmony_ci%42 = OpTypeFunction %int 4293fd4e5da5Sopenharmony_ci%10 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 %uint_4 %uint_0 4294fd4e5da5Sopenharmony_ci%13 = OpExtInst %void %1 DebugTypeFunction %uint_3 %10 4295fd4e5da5Sopenharmony_ci%15 = OpExtInst %void %1 DebugSource %3 4296fd4e5da5Sopenharmony_ci%16 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %15 %uint_5 4297fd4e5da5Sopenharmony_ci%21 = OpExtInst %void %1 DebugFunction %19 %13 %15 %uint_2 %uint_1 %16 %20 %uint_3 %uint_2 4298fd4e5da5Sopenharmony_ci%23 = OpExtInst %void %1 DebugLexicalBlock %15 %uint_2 %uint_17 %21 4299fd4e5da5Sopenharmony_ci%25 = OpExtInst %void %1 DebugTypeFunction %uint_3 %void 4300fd4e5da5Sopenharmony_ci%27 = OpExtInst %void %1 DebugFunction %26 %25 %15 %uint_6 %uint_1 %16 %20 %uint_3 %uint_6 4301fd4e5da5Sopenharmony_ci%29 = OpExtInst %void %1 DebugLexicalBlock %15 %uint_6 %uint_13 %27 4302fd4e5da5Sopenharmony_ci%main = OpFunction %void None %31 4303fd4e5da5Sopenharmony_ci%32 = OpLabel 4304fd4e5da5Sopenharmony_ci%33 = OpFunctionCall %void %src_main 4305fd4e5da5Sopenharmony_ciOpLine %3 8 1 4306fd4e5da5Sopenharmony_ciOpReturn 4307fd4e5da5Sopenharmony_ciOpFunctionEnd 4308fd4e5da5Sopenharmony_ciOpLine %3 6 1 4309fd4e5da5Sopenharmony_ci%src_main = OpFunction %void None %31 4310fd4e5da5Sopenharmony_ciOpNoLine 4311fd4e5da5Sopenharmony_ci%bb_entry = OpLabel 4312fd4e5da5Sopenharmony_ci%47 = OpExtInst %void %1 DebugScope %27 4313fd4e5da5Sopenharmony_ci%37 = OpExtInst %void %1 DebugFunctionDefinition %27 %src_main 4314fd4e5da5Sopenharmony_ci%48 = OpExtInst %void %1 DebugScope %29 4315fd4e5da5Sopenharmony_ciOpLine %3 7 3 4316fd4e5da5Sopenharmony_ci%39 = OpFunctionCall %int %function1 4317fd4e5da5Sopenharmony_ci%49 = OpExtInst %void %1 DebugScope %27 4318fd4e5da5Sopenharmony_ciOpLine %3 8 1 4319fd4e5da5Sopenharmony_ciOpReturn 4320fd4e5da5Sopenharmony_ci%50 = OpExtInst %void %1 DebugNoScope 4321fd4e5da5Sopenharmony_ciOpFunctionEnd 4322fd4e5da5Sopenharmony_ciOpLine %3 2 1 4323fd4e5da5Sopenharmony_ci%function1 = OpFunction %int None %42 4324fd4e5da5Sopenharmony_ciOpNoLine 4325fd4e5da5Sopenharmony_ci%bb_entry_0 = OpLabel 4326fd4e5da5Sopenharmony_ci%51 = OpExtInst %void %1 DebugScope %21 4327fd4e5da5Sopenharmony_ci%45 = OpExtInst %void %1 DebugFunctionDefinition %21 %function1 4328fd4e5da5Sopenharmony_ci%52 = OpExtInst %void %1 DebugScope %23 4329fd4e5da5Sopenharmony_ciOpLine %3 3 3 4330fd4e5da5Sopenharmony_ciOpReturnValue %int_1 4331fd4e5da5Sopenharmony_ci%53 = OpExtInst %void %1 DebugNoScope 4332fd4e5da5Sopenharmony_ciOpFunctionEnd 4333fd4e5da5Sopenharmony_ci)"; 4334fd4e5da5Sopenharmony_ci 4335fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_VULKAN_1_2); 4336fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 4337fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 4338fd4e5da5Sopenharmony_ci} 4339fd4e5da5Sopenharmony_ci 4340fd4e5da5Sopenharmony_ciTEST_F(InlineTest, CreateDebugInlinedAtFromDebugLine) { 4341fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 4342fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void %1 DebugInlinedAt %uint_6 4343fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 4344fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" 4345fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 4346fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 4347fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 4348fd4e5da5Sopenharmony_ci%3 = OpString "debuginlinedat.frag" 4349fd4e5da5Sopenharmony_ci%8 = OpString "int" 4350fd4e5da5Sopenharmony_ci%15 = OpString "int function1() { 4351fd4e5da5Sopenharmony_ci return 1; 4352fd4e5da5Sopenharmony_ci} 4353fd4e5da5Sopenharmony_ci 4354fd4e5da5Sopenharmony_civoid main() { 4355fd4e5da5Sopenharmony_ci function1(); 4356fd4e5da5Sopenharmony_ci} 4357fd4e5da5Sopenharmony_ci" 4358fd4e5da5Sopenharmony_ci%20 = OpString "function1" 4359fd4e5da5Sopenharmony_ci%21 = OpString "" 4360fd4e5da5Sopenharmony_ci%26 = OpString "main" 4361fd4e5da5Sopenharmony_ciOpName %main "main" 4362fd4e5da5Sopenharmony_ciOpName %src_main "src.main" 4363fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry" 4364fd4e5da5Sopenharmony_ciOpName %function1 "function1" 4365fd4e5da5Sopenharmony_ciOpName %bb_entry_0 "bb.entry" 4366fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 4367fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 4368fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 4369fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 4370fd4e5da5Sopenharmony_ci%void = OpTypeVoid 4371fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4 4372fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 4373fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3 4374fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 4375fd4e5da5Sopenharmony_ci%uint_5 = OpConstant %uint 5 4376fd4e5da5Sopenharmony_ci%uint_17 = OpConstant %uint 17 4377fd4e5da5Sopenharmony_ci%uint_13 = OpConstant %uint 13 4378fd4e5da5Sopenharmony_ci%30 = OpTypeFunction %void 4379fd4e5da5Sopenharmony_ci%uint_7 = OpConstant %uint 7 4380fd4e5da5Sopenharmony_ci%uint_6 = OpConstant %uint 6 4381fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2 4382fd4e5da5Sopenharmony_ci%uint_12 = OpConstant %uint 12 4383fd4e5da5Sopenharmony_ci%48 = OpTypeFunction %int 4384fd4e5da5Sopenharmony_ci%uint_9 = OpConstant %uint 9 4385fd4e5da5Sopenharmony_ci%10 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 %uint_4 %uint_0 4386fd4e5da5Sopenharmony_ci%13 = OpExtInst %void %1 DebugTypeFunction %uint_3 %10 4387fd4e5da5Sopenharmony_ci%16 = OpExtInst %void %1 DebugSource %3 %15 4388fd4e5da5Sopenharmony_ci%17 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %16 %uint_5 4389fd4e5da5Sopenharmony_ci%22 = OpExtInst %void %1 DebugFunction %20 %13 %16 %uint_1 %uint_1 %17 %21 %uint_3 %uint_1 4390fd4e5da5Sopenharmony_ci%23 = OpExtInst %void %1 DebugLexicalBlock %16 %uint_1 %uint_17 %22 4391fd4e5da5Sopenharmony_ci%25 = OpExtInst %void %1 DebugTypeFunction %uint_3 %void 4392fd4e5da5Sopenharmony_ci%27 = OpExtInst %void %1 DebugFunction %26 %25 %16 %uint_5 %uint_1 %17 %21 %uint_3 %uint_5 4393fd4e5da5Sopenharmony_ci%28 = OpExtInst %void %1 DebugLexicalBlock %16 %uint_5 %uint_13 %27 4394fd4e5da5Sopenharmony_ci%main = OpFunction %void None %30 4395fd4e5da5Sopenharmony_ci%31 = OpLabel 4396fd4e5da5Sopenharmony_ci%32 = OpFunctionCall %void %src_main 4397fd4e5da5Sopenharmony_ci%34 = OpExtInst %void %1 DebugLine %16 %uint_7 %uint_7 %uint_1 %uint_1 4398fd4e5da5Sopenharmony_ciOpReturn 4399fd4e5da5Sopenharmony_ciOpFunctionEnd 4400fd4e5da5Sopenharmony_ci%src_main = OpFunction %void None %30 4401fd4e5da5Sopenharmony_ci%bb_entry = OpLabel 4402fd4e5da5Sopenharmony_ci%37 = OpExtInst %void %1 DebugScope %27 4403fd4e5da5Sopenharmony_ci%38 = OpExtInst %void %1 DebugFunctionDefinition %27 %src_main 4404fd4e5da5Sopenharmony_ci%39 = OpExtInst %void %1 DebugScope %28 4405fd4e5da5Sopenharmony_ci%40 = OpExtInst %void %1 DebugLine %16 %uint_6 %uint_6 %uint_2 %uint_12 4406fd4e5da5Sopenharmony_ci%44 = OpFunctionCall %int %function1 4407fd4e5da5Sopenharmony_ci%46 = OpExtInst %void %1 DebugScope %27 4408fd4e5da5Sopenharmony_ci%47 = OpExtInst %void %1 DebugLine %16 %uint_7 %uint_7 %uint_1 %uint_1 4409fd4e5da5Sopenharmony_ciOpReturn 4410fd4e5da5Sopenharmony_ciOpFunctionEnd 4411fd4e5da5Sopenharmony_ci%function1 = OpFunction %int None %48 4412fd4e5da5Sopenharmony_ci%bb_entry_0 = OpLabel 4413fd4e5da5Sopenharmony_ci%50 = OpExtInst %void %1 DebugScope %22 4414fd4e5da5Sopenharmony_ci%51 = OpExtInst %void %1 DebugFunctionDefinition %22 %function1 4415fd4e5da5Sopenharmony_ci%52 = OpExtInst %void %1 DebugScope %23 4416fd4e5da5Sopenharmony_ci%53 = OpExtInst %void %1 DebugLine %16 %uint_2 %uint_2 %uint_2 %uint_9 4417fd4e5da5Sopenharmony_ciOpReturnValue %int_1 4418fd4e5da5Sopenharmony_ciOpFunctionEnd 4419fd4e5da5Sopenharmony_ci)"; 4420fd4e5da5Sopenharmony_ci 4421fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_VULKAN_1_2); 4422fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InlineExhaustivePass>(text, true); 4423fd4e5da5Sopenharmony_ci} 4424fd4e5da5Sopenharmony_ci 4425fd4e5da5Sopenharmony_ci// TODO(greg-lunarg): Add tests to verify handling of these cases: 4426fd4e5da5Sopenharmony_ci// 4427fd4e5da5Sopenharmony_ci// Empty modules 4428fd4e5da5Sopenharmony_ci// Modules without function definitions 4429fd4e5da5Sopenharmony_ci// Modules in which all functions do not call other functions 4430fd4e5da5Sopenharmony_ci// Caller and callee both accessing the same global variable 4431fd4e5da5Sopenharmony_ci// Functions with OpLine & OpNoLine 4432fd4e5da5Sopenharmony_ci// Others? 4433fd4e5da5Sopenharmony_ci 4434fd4e5da5Sopenharmony_ci// TODO(dneto): Test suggestions from code review 4435fd4e5da5Sopenharmony_ci// https://github.com/KhronosGroup/SPIRV-Tools/pull/534 4436fd4e5da5Sopenharmony_ci// 4437fd4e5da5Sopenharmony_ci// Callee function returns a value generated outside the callee, 4438fd4e5da5Sopenharmony_ci// e.g. a constant value. This might exercise some logic not yet 4439fd4e5da5Sopenharmony_ci// exercised by the current tests: the false branch in the "if" 4440fd4e5da5Sopenharmony_ci// inside the spv::Op::OpReturnValue case in InlinePass::GenInlineCode? 4441fd4e5da5Sopenharmony_ci// SampledImage before function call, but callee is only single block. 4442fd4e5da5Sopenharmony_ci// Then the SampledImage instruction is not cloned. Documents existing 4443fd4e5da5Sopenharmony_ci// behaviour. 4444fd4e5da5Sopenharmony_ci// SampledImage after function call. It is not cloned or changed. 4445fd4e5da5Sopenharmony_ci 4446fd4e5da5Sopenharmony_ci} // namespace 4447fd4e5da5Sopenharmony_ci} // namespace opt 4448fd4e5da5Sopenharmony_ci} // namespace spvtools 4449