1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include <string> 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "test/opt/assembly_builder.h" 18fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 19fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_cinamespace spvtools { 22fd4e5da5Sopenharmony_cinamespace opt { 23fd4e5da5Sopenharmony_cinamespace { 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_ciusing CodeSinkTest = PassTest<::testing::Test>; 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, MoveToNextBlock) { 28fd4e5da5Sopenharmony_ci const std::string text = R"( 29fd4e5da5Sopenharmony_ci;CHECK: OpFunction 30fd4e5da5Sopenharmony_ci;CHECK: OpLabel 31fd4e5da5Sopenharmony_ci;CHECK: OpLabel 32fd4e5da5Sopenharmony_ci;CHECK: [[ac:%\w+]] = OpAccessChain 33fd4e5da5Sopenharmony_ci;CHECK: [[ld:%\w+]] = OpLoad %uint [[ac]] 34fd4e5da5Sopenharmony_ci;CHECK: OpCopyObject %uint [[ld]] 35fd4e5da5Sopenharmony_ci OpCapability Shader 36fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 37fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 38fd4e5da5Sopenharmony_ci %void = OpTypeVoid 39fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 40fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 41fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 42fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 43fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 44fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 45fd4e5da5Sopenharmony_ci %9 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 46fd4e5da5Sopenharmony_ci %10 = OpTypeFunction %void 47fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %10 48fd4e5da5Sopenharmony_ci %11 = OpLabel 49fd4e5da5Sopenharmony_ci %12 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 50fd4e5da5Sopenharmony_ci %13 = OpLoad %uint %12 51fd4e5da5Sopenharmony_ci OpBranch %14 52fd4e5da5Sopenharmony_ci %14 = OpLabel 53fd4e5da5Sopenharmony_ci %15 = OpCopyObject %uint %13 54fd4e5da5Sopenharmony_ci OpReturn 55fd4e5da5Sopenharmony_ci OpFunctionEnd 56fd4e5da5Sopenharmony_ci)"; 57fd4e5da5Sopenharmony_ci 58fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<CodeSinkingPass>(text, true); 59fd4e5da5Sopenharmony_ci} 60fd4e5da5Sopenharmony_ci 61fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, MovePastSelection) { 62fd4e5da5Sopenharmony_ci const std::string text = R"( 63fd4e5da5Sopenharmony_ci;CHECK: OpFunction 64fd4e5da5Sopenharmony_ci;CHECK: OpLabel 65fd4e5da5Sopenharmony_ci;CHECK: OpSelectionMerge [[merge_bb:%\w+]] 66fd4e5da5Sopenharmony_ci;CHECK: [[merge_bb]] = OpLabel 67fd4e5da5Sopenharmony_ci;CHECK: [[ac:%\w+]] = OpAccessChain 68fd4e5da5Sopenharmony_ci;CHECK: [[ld:%\w+]] = OpLoad %uint [[ac]] 69fd4e5da5Sopenharmony_ci;CHECK: OpCopyObject %uint [[ld]] 70fd4e5da5Sopenharmony_ci OpCapability Shader 71fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 72fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 73fd4e5da5Sopenharmony_ci %void = OpTypeVoid 74fd4e5da5Sopenharmony_ci %bool = OpTypeBool 75fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 76fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 77fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 78fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 79fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 80fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 81fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 82fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 83fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 84fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 85fd4e5da5Sopenharmony_ci %13 = OpLabel 86fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 87fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 88fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 89fd4e5da5Sopenharmony_ci OpBranchConditional %true %17 %16 90fd4e5da5Sopenharmony_ci %17 = OpLabel 91fd4e5da5Sopenharmony_ci OpBranch %16 92fd4e5da5Sopenharmony_ci %16 = OpLabel 93fd4e5da5Sopenharmony_ci %18 = OpCopyObject %uint %15 94fd4e5da5Sopenharmony_ci OpReturn 95fd4e5da5Sopenharmony_ci OpFunctionEnd 96fd4e5da5Sopenharmony_ci)"; 97fd4e5da5Sopenharmony_ci 98fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<CodeSinkingPass>(text, true); 99fd4e5da5Sopenharmony_ci} 100fd4e5da5Sopenharmony_ci 101fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, MoveIntoSelection) { 102fd4e5da5Sopenharmony_ci const std::string text = R"( 103fd4e5da5Sopenharmony_ci;CHECK: OpFunction 104fd4e5da5Sopenharmony_ci;CHECK: OpLabel 105fd4e5da5Sopenharmony_ci;CHECK: OpSelectionMerge [[merge_bb:%\w+]] 106fd4e5da5Sopenharmony_ci;CHECK-NEXT: OpBranchConditional %true [[bb:%\w+]] [[merge_bb]] 107fd4e5da5Sopenharmony_ci;CHECK: [[bb]] = OpLabel 108fd4e5da5Sopenharmony_ci;CHECK-NEXT: [[ac:%\w+]] = OpAccessChain 109fd4e5da5Sopenharmony_ci;CHECK-NEXT: [[ld:%\w+]] = OpLoad %uint [[ac]] 110fd4e5da5Sopenharmony_ci;CHECK-NEXT: OpCopyObject %uint [[ld]] 111fd4e5da5Sopenharmony_ci OpCapability Shader 112fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 113fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 114fd4e5da5Sopenharmony_ci %void = OpTypeVoid 115fd4e5da5Sopenharmony_ci %bool = OpTypeBool 116fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 117fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 118fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 119fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 120fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 121fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 122fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 123fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 124fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 125fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 126fd4e5da5Sopenharmony_ci %13 = OpLabel 127fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 128fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 129fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 130fd4e5da5Sopenharmony_ci OpBranchConditional %true %17 %16 131fd4e5da5Sopenharmony_ci %17 = OpLabel 132fd4e5da5Sopenharmony_ci %18 = OpCopyObject %uint %15 133fd4e5da5Sopenharmony_ci OpBranch %16 134fd4e5da5Sopenharmony_ci %16 = OpLabel 135fd4e5da5Sopenharmony_ci OpReturn 136fd4e5da5Sopenharmony_ci OpFunctionEnd 137fd4e5da5Sopenharmony_ci)"; 138fd4e5da5Sopenharmony_ci 139fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<CodeSinkingPass>(text, true); 140fd4e5da5Sopenharmony_ci} 141fd4e5da5Sopenharmony_ci 142fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, LeaveBeforeSelection) { 143fd4e5da5Sopenharmony_ci const std::string text = R"( 144fd4e5da5Sopenharmony_ci OpCapability Shader 145fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 146fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 147fd4e5da5Sopenharmony_ci %void = OpTypeVoid 148fd4e5da5Sopenharmony_ci %bool = OpTypeBool 149fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 150fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 151fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 152fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 153fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 154fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 155fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 156fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 157fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 158fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 159fd4e5da5Sopenharmony_ci %13 = OpLabel 160fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 161fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 162fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 163fd4e5da5Sopenharmony_ci OpBranchConditional %true %17 %20 164fd4e5da5Sopenharmony_ci %20 = OpLabel 165fd4e5da5Sopenharmony_ci OpBranch %16 166fd4e5da5Sopenharmony_ci %17 = OpLabel 167fd4e5da5Sopenharmony_ci %18 = OpCopyObject %uint %15 168fd4e5da5Sopenharmony_ci OpBranch %16 169fd4e5da5Sopenharmony_ci %16 = OpLabel 170fd4e5da5Sopenharmony_ci %19 = OpCopyObject %uint %15 171fd4e5da5Sopenharmony_ci OpReturn 172fd4e5da5Sopenharmony_ci OpFunctionEnd 173fd4e5da5Sopenharmony_ci)"; 174fd4e5da5Sopenharmony_ci 175fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 176fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 177fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 178fd4e5da5Sopenharmony_ci} 179fd4e5da5Sopenharmony_ci 180fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, LeaveAloneUseInSameBlock) { 181fd4e5da5Sopenharmony_ci const std::string text = R"( 182fd4e5da5Sopenharmony_ci OpCapability Shader 183fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 184fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 185fd4e5da5Sopenharmony_ci %void = OpTypeVoid 186fd4e5da5Sopenharmony_ci %bool = OpTypeBool 187fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 188fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 189fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 190fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 191fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 192fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 193fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 194fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 195fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 196fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 197fd4e5da5Sopenharmony_ci %13 = OpLabel 198fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 199fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 200fd4e5da5Sopenharmony_ci %cond = OpIEqual %bool %15 %uint_0 201fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 202fd4e5da5Sopenharmony_ci OpBranchConditional %cond %17 %16 203fd4e5da5Sopenharmony_ci %17 = OpLabel 204fd4e5da5Sopenharmony_ci OpBranch %16 205fd4e5da5Sopenharmony_ci %16 = OpLabel 206fd4e5da5Sopenharmony_ci %19 = OpCopyObject %uint %15 207fd4e5da5Sopenharmony_ci OpReturn 208fd4e5da5Sopenharmony_ci OpFunctionEnd 209fd4e5da5Sopenharmony_ci)"; 210fd4e5da5Sopenharmony_ci 211fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 212fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 213fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 214fd4e5da5Sopenharmony_ci} 215fd4e5da5Sopenharmony_ci 216fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, DontMoveIntoLoop) { 217fd4e5da5Sopenharmony_ci const std::string text = R"( 218fd4e5da5Sopenharmony_ci OpCapability Shader 219fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 220fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 221fd4e5da5Sopenharmony_ci %void = OpTypeVoid 222fd4e5da5Sopenharmony_ci %bool = OpTypeBool 223fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 224fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 225fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 226fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 227fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 228fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 229fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 230fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 231fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 232fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 233fd4e5da5Sopenharmony_ci %13 = OpLabel 234fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 235fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 236fd4e5da5Sopenharmony_ci OpBranch %17 237fd4e5da5Sopenharmony_ci %17 = OpLabel 238fd4e5da5Sopenharmony_ci OpLoopMerge %merge %cont None 239fd4e5da5Sopenharmony_ci OpBranch %cont 240fd4e5da5Sopenharmony_ci %cont = OpLabel 241fd4e5da5Sopenharmony_ci %cond = OpIEqual %bool %15 %uint_0 242fd4e5da5Sopenharmony_ci OpBranchConditional %cond %merge %17 243fd4e5da5Sopenharmony_ci %merge = OpLabel 244fd4e5da5Sopenharmony_ci OpReturn 245fd4e5da5Sopenharmony_ci OpFunctionEnd 246fd4e5da5Sopenharmony_ci)"; 247fd4e5da5Sopenharmony_ci 248fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 249fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 250fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 251fd4e5da5Sopenharmony_ci} 252fd4e5da5Sopenharmony_ci 253fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, DontMoveIntoLoop2) { 254fd4e5da5Sopenharmony_ci const std::string text = R"( 255fd4e5da5Sopenharmony_ci OpCapability Shader 256fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 257fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 258fd4e5da5Sopenharmony_ci %void = OpTypeVoid 259fd4e5da5Sopenharmony_ci %bool = OpTypeBool 260fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 261fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 262fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 263fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 264fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 265fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 266fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 267fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 268fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 269fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 270fd4e5da5Sopenharmony_ci %13 = OpLabel 271fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 272fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 273fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 274fd4e5da5Sopenharmony_ci OpBranchConditional %true %17 %16 275fd4e5da5Sopenharmony_ci %17 = OpLabel 276fd4e5da5Sopenharmony_ci OpLoopMerge %merge %cont None 277fd4e5da5Sopenharmony_ci OpBranch %cont 278fd4e5da5Sopenharmony_ci %cont = OpLabel 279fd4e5da5Sopenharmony_ci %cond = OpIEqual %bool %15 %uint_0 280fd4e5da5Sopenharmony_ci OpBranchConditional %cond %merge %17 281fd4e5da5Sopenharmony_ci %merge = OpLabel 282fd4e5da5Sopenharmony_ci OpBranch %16 283fd4e5da5Sopenharmony_ci %16 = OpLabel 284fd4e5da5Sopenharmony_ci OpReturn 285fd4e5da5Sopenharmony_ci OpFunctionEnd 286fd4e5da5Sopenharmony_ci)"; 287fd4e5da5Sopenharmony_ci 288fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 289fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 290fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 291fd4e5da5Sopenharmony_ci} 292fd4e5da5Sopenharmony_ci 293fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, DontMoveSelectionUsedInBothSides) { 294fd4e5da5Sopenharmony_ci const std::string text = R"( 295fd4e5da5Sopenharmony_ci OpCapability Shader 296fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 297fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 298fd4e5da5Sopenharmony_ci %void = OpTypeVoid 299fd4e5da5Sopenharmony_ci %bool = OpTypeBool 300fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 301fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 302fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 303fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 304fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 305fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 306fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 307fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 308fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 309fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 310fd4e5da5Sopenharmony_ci %13 = OpLabel 311fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 312fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 313fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 314fd4e5da5Sopenharmony_ci OpBranchConditional %true %17 %20 315fd4e5da5Sopenharmony_ci %20 = OpLabel 316fd4e5da5Sopenharmony_ci %19 = OpCopyObject %uint %15 317fd4e5da5Sopenharmony_ci OpBranch %16 318fd4e5da5Sopenharmony_ci %17 = OpLabel 319fd4e5da5Sopenharmony_ci %18 = OpCopyObject %uint %15 320fd4e5da5Sopenharmony_ci OpBranch %16 321fd4e5da5Sopenharmony_ci %16 = OpLabel 322fd4e5da5Sopenharmony_ci OpReturn 323fd4e5da5Sopenharmony_ci OpFunctionEnd 324fd4e5da5Sopenharmony_ci)"; 325fd4e5da5Sopenharmony_ci 326fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 327fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 328fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 329fd4e5da5Sopenharmony_ci} 330fd4e5da5Sopenharmony_ci 331fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, DontMoveBecauseOfStore) { 332fd4e5da5Sopenharmony_ci const std::string text = R"( 333fd4e5da5Sopenharmony_ci OpCapability Shader 334fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 335fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 336fd4e5da5Sopenharmony_ci %void = OpTypeVoid 337fd4e5da5Sopenharmony_ci %bool = OpTypeBool 338fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 339fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 340fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 341fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 342fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 343fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 344fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 345fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 346fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 347fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 348fd4e5da5Sopenharmony_ci %13 = OpLabel 349fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 350fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 351fd4e5da5Sopenharmony_ci OpStore %14 %15 352fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 353fd4e5da5Sopenharmony_ci OpBranchConditional %true %17 %20 354fd4e5da5Sopenharmony_ci %20 = OpLabel 355fd4e5da5Sopenharmony_ci OpBranch %16 356fd4e5da5Sopenharmony_ci %17 = OpLabel 357fd4e5da5Sopenharmony_ci %18 = OpCopyObject %uint %15 358fd4e5da5Sopenharmony_ci OpBranch %16 359fd4e5da5Sopenharmony_ci %16 = OpLabel 360fd4e5da5Sopenharmony_ci OpReturn 361fd4e5da5Sopenharmony_ci OpFunctionEnd 362fd4e5da5Sopenharmony_ci)"; 363fd4e5da5Sopenharmony_ci 364fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 365fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 366fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 367fd4e5da5Sopenharmony_ci} 368fd4e5da5Sopenharmony_ci 369fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, MoveReadOnlyLoadWithSync) { 370fd4e5da5Sopenharmony_ci const std::string text = R"( 371fd4e5da5Sopenharmony_ci OpCapability Shader 372fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 373fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 374fd4e5da5Sopenharmony_ci %void = OpTypeVoid 375fd4e5da5Sopenharmony_ci %bool = OpTypeBool 376fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 377fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 378fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 379fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 380fd4e5da5Sopenharmony_ci%mem_semantics = OpConstant %uint 0x42 ; Uniform memory arquire 381fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 382fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 383fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 384fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 385fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 386fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 387fd4e5da5Sopenharmony_ci %13 = OpLabel 388fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 389fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 390fd4e5da5Sopenharmony_ci OpMemoryBarrier %uint_4 %mem_semantics 391fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 392fd4e5da5Sopenharmony_ci OpBranchConditional %true %17 %20 393fd4e5da5Sopenharmony_ci %20 = OpLabel 394fd4e5da5Sopenharmony_ci OpBranch %16 395fd4e5da5Sopenharmony_ci %17 = OpLabel 396fd4e5da5Sopenharmony_ci %18 = OpCopyObject %uint %15 397fd4e5da5Sopenharmony_ci OpBranch %16 398fd4e5da5Sopenharmony_ci %16 = OpLabel 399fd4e5da5Sopenharmony_ci OpReturn 400fd4e5da5Sopenharmony_ci OpFunctionEnd 401fd4e5da5Sopenharmony_ci)"; 402fd4e5da5Sopenharmony_ci 403fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 404fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 405fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result)); 406fd4e5da5Sopenharmony_ci} 407fd4e5da5Sopenharmony_ci 408fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, DontMoveBecauseOfSync) { 409fd4e5da5Sopenharmony_ci const std::string text = R"( 410fd4e5da5Sopenharmony_ci OpCapability Shader 411fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 412fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 413fd4e5da5Sopenharmony_ci OpDecorate %_arr_uint_uint_4 BufferBlock 414fd4e5da5Sopenharmony_ci OpMemberDecorate %_arr_uint_uint_4 0 Offset 0 415fd4e5da5Sopenharmony_ci %void = OpTypeVoid 416fd4e5da5Sopenharmony_ci %bool = OpTypeBool 417fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 418fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 419fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 420fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 421fd4e5da5Sopenharmony_ci%mem_semantics = OpConstant %uint 0x42 ; Uniform memory arquire 422fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeStruct %uint 423fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 424fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 425fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 426fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 427fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 428fd4e5da5Sopenharmony_ci %13 = OpLabel 429fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 430fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 431fd4e5da5Sopenharmony_ci OpMemoryBarrier %uint_4 %mem_semantics 432fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 433fd4e5da5Sopenharmony_ci OpBranchConditional %true %17 %20 434fd4e5da5Sopenharmony_ci %20 = OpLabel 435fd4e5da5Sopenharmony_ci OpBranch %16 436fd4e5da5Sopenharmony_ci %17 = OpLabel 437fd4e5da5Sopenharmony_ci %18 = OpCopyObject %uint %15 438fd4e5da5Sopenharmony_ci OpBranch %16 439fd4e5da5Sopenharmony_ci %16 = OpLabel 440fd4e5da5Sopenharmony_ci OpReturn 441fd4e5da5Sopenharmony_ci OpFunctionEnd 442fd4e5da5Sopenharmony_ci)"; 443fd4e5da5Sopenharmony_ci 444fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 445fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 446fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 447fd4e5da5Sopenharmony_ci} 448fd4e5da5Sopenharmony_ci 449fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, DontMoveBecauseOfAtomicWithSync) { 450fd4e5da5Sopenharmony_ci const std::string text = R"( 451fd4e5da5Sopenharmony_ci OpCapability Shader 452fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 453fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 454fd4e5da5Sopenharmony_ci OpDecorate %_arr_uint_uint_4 BufferBlock 455fd4e5da5Sopenharmony_ci OpMemberDecorate %_arr_uint_uint_4 0 Offset 0 456fd4e5da5Sopenharmony_ci %void = OpTypeVoid 457fd4e5da5Sopenharmony_ci %bool = OpTypeBool 458fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 459fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 460fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 461fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 462fd4e5da5Sopenharmony_ci%mem_semantics = OpConstant %uint 0x42 ; Uniform memory arquire 463fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeStruct %uint 464fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 465fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 466fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 467fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 468fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 469fd4e5da5Sopenharmony_ci %13 = OpLabel 470fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 471fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 472fd4e5da5Sopenharmony_ci %al = OpAtomicLoad %uint %14 %uint_4 %mem_semantics 473fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 474fd4e5da5Sopenharmony_ci OpBranchConditional %true %17 %20 475fd4e5da5Sopenharmony_ci %20 = OpLabel 476fd4e5da5Sopenharmony_ci OpBranch %16 477fd4e5da5Sopenharmony_ci %17 = OpLabel 478fd4e5da5Sopenharmony_ci %18 = OpCopyObject %uint %15 479fd4e5da5Sopenharmony_ci OpBranch %16 480fd4e5da5Sopenharmony_ci %16 = OpLabel 481fd4e5da5Sopenharmony_ci OpReturn 482fd4e5da5Sopenharmony_ci OpFunctionEnd 483fd4e5da5Sopenharmony_ci)"; 484fd4e5da5Sopenharmony_ci 485fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 486fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 487fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 488fd4e5da5Sopenharmony_ci} 489fd4e5da5Sopenharmony_ci 490fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, MoveWithAtomicWithoutSync) { 491fd4e5da5Sopenharmony_ci const std::string text = R"( 492fd4e5da5Sopenharmony_ci OpCapability Shader 493fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 494fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" 495fd4e5da5Sopenharmony_ci OpDecorate %_arr_uint_uint_4 BufferBlock 496fd4e5da5Sopenharmony_ci OpMemberDecorate %_arr_uint_uint_4 0 Offset 0 497fd4e5da5Sopenharmony_ci %void = OpTypeVoid 498fd4e5da5Sopenharmony_ci %bool = OpTypeBool 499fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 500fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 501fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 502fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 503fd4e5da5Sopenharmony_ci%_arr_uint_uint_4 = OpTypeStruct %uint 504fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 505fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4 506fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform 507fd4e5da5Sopenharmony_ci %12 = OpTypeFunction %void 508fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %12 509fd4e5da5Sopenharmony_ci %13 = OpLabel 510fd4e5da5Sopenharmony_ci %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 511fd4e5da5Sopenharmony_ci %15 = OpLoad %uint %14 512fd4e5da5Sopenharmony_ci %al = OpAtomicLoad %uint %14 %uint_4 %uint_0 513fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 514fd4e5da5Sopenharmony_ci OpBranchConditional %true %17 %20 515fd4e5da5Sopenharmony_ci %20 = OpLabel 516fd4e5da5Sopenharmony_ci OpBranch %16 517fd4e5da5Sopenharmony_ci %17 = OpLabel 518fd4e5da5Sopenharmony_ci %18 = OpCopyObject %uint %15 519fd4e5da5Sopenharmony_ci OpBranch %16 520fd4e5da5Sopenharmony_ci %16 = OpLabel 521fd4e5da5Sopenharmony_ci OpReturn 522fd4e5da5Sopenharmony_ci OpFunctionEnd 523fd4e5da5Sopenharmony_ci)"; 524fd4e5da5Sopenharmony_ci 525fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 526fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 527fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result)); 528fd4e5da5Sopenharmony_ci} 529fd4e5da5Sopenharmony_ci 530fd4e5da5Sopenharmony_ciTEST_F(CodeSinkTest, DecorationOnLoad) { 531fd4e5da5Sopenharmony_ci const std::string text = R"( 532fd4e5da5Sopenharmony_ci OpCapability Shader 533fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 534fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %1 "main" %2 535fd4e5da5Sopenharmony_ci OpDecorate %3 RelaxedPrecision 536fd4e5da5Sopenharmony_ci %void = OpTypeVoid 537fd4e5da5Sopenharmony_ci %5 = OpTypeFunction %void 538fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 539fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float 540fd4e5da5Sopenharmony_ci %2 = OpVariable %_ptr_Input_float Input 541fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %5 542fd4e5da5Sopenharmony_ci %8 = OpLabel 543fd4e5da5Sopenharmony_ci %3 = OpLoad %float %2 544fd4e5da5Sopenharmony_ci OpReturn 545fd4e5da5Sopenharmony_ci OpFunctionEnd 546fd4e5da5Sopenharmony_ci)"; 547fd4e5da5Sopenharmony_ci 548fd4e5da5Sopenharmony_ci // We just want to make sure the code does not crash. 549fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<CodeSinkingPass>( 550fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 551fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 552fd4e5da5Sopenharmony_ci} 553fd4e5da5Sopenharmony_ci 554fd4e5da5Sopenharmony_ci} // namespace 555fd4e5da5Sopenharmony_ci} // namespace opt 556fd4e5da5Sopenharmony_ci} // namespace spvtools 557