1fd4e5da5Sopenharmony_ci// Copyright (c) 2018 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 "gmock/gmock.h" 18fd4e5da5Sopenharmony_ci#include "source/opt/simplification_pass.h" 19fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_cinamespace spvtools { 22fd4e5da5Sopenharmony_cinamespace opt { 23fd4e5da5Sopenharmony_cinamespace { 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_ciusing SimplificationTest = PassTest<::testing::Test>; 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciTEST_F(SimplificationTest, StraightLineTest) { 28fd4e5da5Sopenharmony_ci // Testing that folding rules are combined in simple straight line code. 29fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 30fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 31fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 32fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %i %o 33fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 34fd4e5da5Sopenharmony_ci OpSource GLSL 430 35fd4e5da5Sopenharmony_ci OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 36fd4e5da5Sopenharmony_ci OpSourceExtension "GL_GOOGLE_include_directive" 37fd4e5da5Sopenharmony_ci OpName %main "main" 38fd4e5da5Sopenharmony_ci OpName %i "i" 39fd4e5da5Sopenharmony_ci OpName %o "o" 40fd4e5da5Sopenharmony_ci OpDecorate %i Flat 41fd4e5da5Sopenharmony_ci OpDecorate %i Location 0 42fd4e5da5Sopenharmony_ci OpDecorate %o Location 0 43fd4e5da5Sopenharmony_ci %void = OpTypeVoid 44fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %void 45fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 46fd4e5da5Sopenharmony_ci %v4int = OpTypeVector %int 4 47fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 48fd4e5da5Sopenharmony_ci %13 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0 49fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 50fd4e5da5Sopenharmony_ci%_ptr_Input_v4int = OpTypePointer Input %v4int 51fd4e5da5Sopenharmony_ci %i = OpVariable %_ptr_Input_v4int Input 52fd4e5da5Sopenharmony_ci%_ptr_Output_int = OpTypePointer Output %int 53fd4e5da5Sopenharmony_ci %o = OpVariable %_ptr_Output_int Output 54fd4e5da5Sopenharmony_ci %main = OpFunction %void None %8 55fd4e5da5Sopenharmony_ci %21 = OpLabel 56fd4e5da5Sopenharmony_ci %31 = OpCompositeInsert %v4int %int_1 %13 0 57fd4e5da5Sopenharmony_ci; CHECK: [[load:%[a-zA-Z_\d]+]] = OpLoad 58fd4e5da5Sopenharmony_ci %23 = OpLoad %v4int %i 59fd4e5da5Sopenharmony_ci %33 = OpCompositeInsert %v4int %int_0 %23 0 60fd4e5da5Sopenharmony_ci %35 = OpCompositeExtract %int %31 0 61fd4e5da5Sopenharmony_ci; CHECK: [[extract:%[a-zA-Z_\d]+]] = OpCompositeExtract %int [[load]] 1 62fd4e5da5Sopenharmony_ci %37 = OpCompositeExtract %int %33 1 63fd4e5da5Sopenharmony_ci; CHECK: [[add:%[a-zA-Z_\d]+]] = OpIAdd %int %int_1 [[extract]] 64fd4e5da5Sopenharmony_ci %29 = OpIAdd %int %35 %37 65fd4e5da5Sopenharmony_ci OpStore %o %29 66fd4e5da5Sopenharmony_ci OpReturn 67fd4e5da5Sopenharmony_ci OpFunctionEnd 68fd4e5da5Sopenharmony_ci)"; 69fd4e5da5Sopenharmony_ci 70fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<SimplificationPass>(text, false); 71fd4e5da5Sopenharmony_ci} 72fd4e5da5Sopenharmony_ci 73fd4e5da5Sopenharmony_ciTEST_F(SimplificationTest, NewInstructionTest) { 74fd4e5da5Sopenharmony_ci // Testing that new instructions are simplified. Specifically, 75fd4e5da5Sopenharmony_ci // that the new add instruction generated by FactorAddMul is 76fd4e5da5Sopenharmony_ci // further simplified by MergeGenericAddSub. 77fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 78fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 79fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 80fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" 81fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 82fd4e5da5Sopenharmony_ci OpSource GLSL 430 83fd4e5da5Sopenharmony_ci OpName %main "main" 84fd4e5da5Sopenharmony_ci %void = OpTypeVoid 85fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %void 86fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 87fd4e5da5Sopenharmony_ci %_ptr_int = OpTypePointer Function %int 88fd4e5da5Sopenharmony_ci; CHECK: [[mul:%[a-zA-Z_\d]+]] = OpIMul %int %13 %11 89fd4e5da5Sopenharmony_ci %main = OpFunction %void None %4 90fd4e5da5Sopenharmony_ci %7 = OpLabel 91fd4e5da5Sopenharmony_ci %8 = OpVariable %_ptr_int Function 92fd4e5da5Sopenharmony_ci %9 = OpVariable %_ptr_int Function 93fd4e5da5Sopenharmony_ci %10 = OpVariable %_ptr_int Function 94fd4e5da5Sopenharmony_ci %11 = OpLoad %int %8 95fd4e5da5Sopenharmony_ci %12 = OpLoad %int %9 96fd4e5da5Sopenharmony_ci %13 = OpLoad %int %10 97fd4e5da5Sopenharmony_ci %14 = OpISub %int %11 %12 98fd4e5da5Sopenharmony_ci %15 = OpIMul %int %13 %11 99fd4e5da5Sopenharmony_ci %16 = OpIMul %int %13 %12 100fd4e5da5Sopenharmony_ci %17 = OpIAdd %int %14 %15 101fd4e5da5Sopenharmony_ci OpReturn 102fd4e5da5Sopenharmony_ci OpFunctionEnd 103fd4e5da5Sopenharmony_ci)"; 104fd4e5da5Sopenharmony_ci 105fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<SimplificationPass>(text, false); 106fd4e5da5Sopenharmony_ci} 107fd4e5da5Sopenharmony_ci 108fd4e5da5Sopenharmony_ciTEST_F(SimplificationTest, AcrossBasicBlocks) { 109fd4e5da5Sopenharmony_ci // Testing that folding rules are combined across basic blocks. 110fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 111fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 112fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 113fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %i %o 114fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 115fd4e5da5Sopenharmony_ci OpSource GLSL 430 116fd4e5da5Sopenharmony_ci OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 117fd4e5da5Sopenharmony_ci OpSourceExtension "GL_GOOGLE_include_directive" 118fd4e5da5Sopenharmony_ci OpName %main "main" 119fd4e5da5Sopenharmony_ci OpName %i "i" 120fd4e5da5Sopenharmony_ci OpName %o "o" 121fd4e5da5Sopenharmony_ci OpDecorate %i Flat 122fd4e5da5Sopenharmony_ci OpDecorate %i Location 0 123fd4e5da5Sopenharmony_ci OpDecorate %o Location 0 124fd4e5da5Sopenharmony_ci %void = OpTypeVoid 125fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %void 126fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 127fd4e5da5Sopenharmony_ci %v4int = OpTypeVector %int 4 128fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 129fd4e5da5Sopenharmony_ci%_ptr_Input_v4int = OpTypePointer Input %v4int 130fd4e5da5Sopenharmony_ci %i = OpVariable %_ptr_Input_v4int Input 131fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 132fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 133fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int 134fd4e5da5Sopenharmony_ci %int_10 = OpConstant %int 10 135fd4e5da5Sopenharmony_ci %bool = OpTypeBool 136fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 137fd4e5da5Sopenharmony_ci%_ptr_Output_int = OpTypePointer Output %int 138fd4e5da5Sopenharmony_ci %o = OpVariable %_ptr_Output_int Output 139fd4e5da5Sopenharmony_ci %main = OpFunction %void None %8 140fd4e5da5Sopenharmony_ci %24 = OpLabel 141fd4e5da5Sopenharmony_ci; CHECK: [[load:%[a-zA-Z_\d]+]] = OpLoad %v4int %i 142fd4e5da5Sopenharmony_ci %25 = OpLoad %v4int %i 143fd4e5da5Sopenharmony_ci %41 = OpCompositeInsert %v4int %int_0 %25 0 144fd4e5da5Sopenharmony_ci %27 = OpAccessChain %_ptr_Input_int %i %uint_0 145fd4e5da5Sopenharmony_ci %28 = OpLoad %int %27 146fd4e5da5Sopenharmony_ci %29 = OpSGreaterThan %bool %28 %int_10 147fd4e5da5Sopenharmony_ci OpSelectionMerge %30 None 148fd4e5da5Sopenharmony_ci OpBranchConditional %29 %31 %32 149fd4e5da5Sopenharmony_ci %31 = OpLabel 150fd4e5da5Sopenharmony_ci %43 = OpCopyObject %v4int %25 151fd4e5da5Sopenharmony_ci OpBranch %30 152fd4e5da5Sopenharmony_ci %32 = OpLabel 153fd4e5da5Sopenharmony_ci %45 = OpCopyObject %v4int %25 154fd4e5da5Sopenharmony_ci OpBranch %30 155fd4e5da5Sopenharmony_ci %30 = OpLabel 156fd4e5da5Sopenharmony_ci %50 = OpPhi %v4int %43 %31 %45 %32 157fd4e5da5Sopenharmony_ci; CHECK: [[extract1:%[a-zA-Z_\d]+]] = OpCompositeExtract %int [[load]] 0 158fd4e5da5Sopenharmony_ci %47 = OpCompositeExtract %int %50 0 159fd4e5da5Sopenharmony_ci; CHECK: [[extract2:%[a-zA-Z_\d]+]] = OpCompositeExtract %int [[load]] 1 160fd4e5da5Sopenharmony_ci %49 = OpCompositeExtract %int %41 1 161fd4e5da5Sopenharmony_ci; CHECK: [[add:%[a-zA-Z_\d]+]] = OpIAdd %int [[extract1]] [[extract2]] 162fd4e5da5Sopenharmony_ci %39 = OpIAdd %int %47 %49 163fd4e5da5Sopenharmony_ci OpStore %o %39 164fd4e5da5Sopenharmony_ci OpReturn 165fd4e5da5Sopenharmony_ci OpFunctionEnd 166fd4e5da5Sopenharmony_ci 167fd4e5da5Sopenharmony_ci)"; 168fd4e5da5Sopenharmony_ci 169fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<SimplificationPass>(text, false); 170fd4e5da5Sopenharmony_ci} 171fd4e5da5Sopenharmony_ci 172fd4e5da5Sopenharmony_ciTEST_F(SimplificationTest, ThroughLoops) { 173fd4e5da5Sopenharmony_ci // Testing that folding rules are applied multiple times to instructions 174fd4e5da5Sopenharmony_ci // to be able to propagate across loop iterations. 175fd4e5da5Sopenharmony_ci const std::string text = R"( 176fd4e5da5Sopenharmony_ci OpCapability Shader 177fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 178fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 179fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %o %i 180fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 181fd4e5da5Sopenharmony_ci OpSource GLSL 430 182fd4e5da5Sopenharmony_ci OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 183fd4e5da5Sopenharmony_ci OpSourceExtension "GL_GOOGLE_include_directive" 184fd4e5da5Sopenharmony_ci OpName %main "main" 185fd4e5da5Sopenharmony_ci OpName %o "o" 186fd4e5da5Sopenharmony_ci OpName %i "i" 187fd4e5da5Sopenharmony_ci OpDecorate %o Location 0 188fd4e5da5Sopenharmony_ci OpDecorate %i Flat 189fd4e5da5Sopenharmony_ci OpDecorate %i Location 0 190fd4e5da5Sopenharmony_ci %void = OpTypeVoid 191fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %void 192fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 193fd4e5da5Sopenharmony_ci %v4int = OpTypeVector %int 4 194fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 195fd4e5da5Sopenharmony_ci; CHECK: [[constant:%[a-zA-Z_\d]+]] = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0 196fd4e5da5Sopenharmony_ci %13 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0 197fd4e5da5Sopenharmony_ci %bool = OpTypeBool 198fd4e5da5Sopenharmony_ci%_ptr_Output_int = OpTypePointer Output %int 199fd4e5da5Sopenharmony_ci %o = OpVariable %_ptr_Output_int Output 200fd4e5da5Sopenharmony_ci%_ptr_Input_v4int = OpTypePointer Input %v4int 201fd4e5da5Sopenharmony_ci %i = OpVariable %_ptr_Input_v4int Input 202fd4e5da5Sopenharmony_ci %68 = OpUndef %v4int 203fd4e5da5Sopenharmony_ci %main = OpFunction %void None %8 204fd4e5da5Sopenharmony_ci %23 = OpLabel 205fd4e5da5Sopenharmony_ci; CHECK: [[load:%[a-zA-Z_\d]+]] = OpLoad %v4int %i 206fd4e5da5Sopenharmony_ci %load = OpLoad %v4int %i 207fd4e5da5Sopenharmony_ci OpBranch %24 208fd4e5da5Sopenharmony_ci %24 = OpLabel 209fd4e5da5Sopenharmony_ci %67 = OpPhi %v4int %load %23 %64 %26 210fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge_lab:%[a-zA-Z_\d]+]] 211fd4e5da5Sopenharmony_ci OpLoopMerge %25 %26 None 212fd4e5da5Sopenharmony_ci OpBranch %27 213fd4e5da5Sopenharmony_ci %27 = OpLabel 214fd4e5da5Sopenharmony_ci %48 = OpCompositeExtract %int %67 0 215fd4e5da5Sopenharmony_ci %30 = OpIEqual %bool %48 %int_0 216fd4e5da5Sopenharmony_ci OpBranchConditional %30 %31 %25 217fd4e5da5Sopenharmony_ci %31 = OpLabel 218fd4e5da5Sopenharmony_ci %50 = OpCompositeExtract %int %67 0 219fd4e5da5Sopenharmony_ci %54 = OpCompositeExtract %int %67 1 220fd4e5da5Sopenharmony_ci %58 = OpCompositeExtract %int %67 2 221fd4e5da5Sopenharmony_ci %62 = OpCompositeExtract %int %67 3 222fd4e5da5Sopenharmony_ci %64 = OpCompositeConstruct %v4int %50 %54 %58 %62 223fd4e5da5Sopenharmony_ci OpBranch %26 224fd4e5da5Sopenharmony_ci %26 = OpLabel 225fd4e5da5Sopenharmony_ci OpBranch %24 226fd4e5da5Sopenharmony_ci %25 = OpLabel 227fd4e5da5Sopenharmony_ci; CHECK: [[merge_lab]] = OpLabel 228fd4e5da5Sopenharmony_ci; CHECK: [[extract:%[a-zA-Z_\d]+]] = OpCompositeExtract %int [[load]] 0 229fd4e5da5Sopenharmony_ci %66 = OpCompositeExtract %int %67 0 230fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpStore %o [[extract]] 231fd4e5da5Sopenharmony_ci OpStore %o %66 232fd4e5da5Sopenharmony_ci OpReturn 233fd4e5da5Sopenharmony_ci OpFunctionEnd 234fd4e5da5Sopenharmony_ci)"; 235fd4e5da5Sopenharmony_ci 236fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<SimplificationPass>(text, false); 237fd4e5da5Sopenharmony_ci} 238fd4e5da5Sopenharmony_ci 239fd4e5da5Sopenharmony_ciTEST_F(SimplificationTest, CopyObjectWithDecorations1) { 240fd4e5da5Sopenharmony_ci // Don't simplify OpCopyObject if the result id has a decoration that the 241fd4e5da5Sopenharmony_ci // operand does not. 242fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 243fd4e5da5Sopenharmony_ciOpCapability ShaderNonUniform 244fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 245fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 246fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" 247fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 248fd4e5da5Sopenharmony_ciOpSource GLSL 430 249fd4e5da5Sopenharmony_ciOpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 250fd4e5da5Sopenharmony_ciOpSourceExtension "GL_GOOGLE_include_directive" 251fd4e5da5Sopenharmony_ciOpDecorate %3 NonUniform 252fd4e5da5Sopenharmony_ci%void = OpTypeVoid 253fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 254fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 255fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %5 256fd4e5da5Sopenharmony_ci%7 = OpLabel 257fd4e5da5Sopenharmony_ci%8 = OpUndef %int 258fd4e5da5Sopenharmony_ci%3 = OpCopyObject %int %8 259fd4e5da5Sopenharmony_ci%9 = OpIAdd %int %3 %3 260fd4e5da5Sopenharmony_ciOpReturn 261fd4e5da5Sopenharmony_ciOpFunctionEnd 262fd4e5da5Sopenharmony_ci)"; 263fd4e5da5Sopenharmony_ci 264fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<SimplificationPass>(text, text, false); 265fd4e5da5Sopenharmony_ci} 266fd4e5da5Sopenharmony_ci 267fd4e5da5Sopenharmony_ciTEST_F(SimplificationTest, CopyObjectWithDecorations2) { 268fd4e5da5Sopenharmony_ci // Simplify OpCopyObject if the result id is a subset of the decorations of 269fd4e5da5Sopenharmony_ci // the operand. 270fd4e5da5Sopenharmony_ci const std::string before = R"(OpCapability Shader 271fd4e5da5Sopenharmony_ciOpCapability ShaderNonUniform 272fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 273fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 274fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" 275fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 276fd4e5da5Sopenharmony_ciOpSource GLSL 430 277fd4e5da5Sopenharmony_ciOpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 278fd4e5da5Sopenharmony_ciOpSourceExtension "GL_GOOGLE_include_directive" 279fd4e5da5Sopenharmony_ciOpDecorate %3 NonUniform 280fd4e5da5Sopenharmony_ci%void = OpTypeVoid 281fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 282fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 283fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %5 284fd4e5da5Sopenharmony_ci%7 = OpLabel 285fd4e5da5Sopenharmony_ci%3 = OpUndef %int 286fd4e5da5Sopenharmony_ci%8 = OpCopyObject %int %3 287fd4e5da5Sopenharmony_ci%9 = OpIAdd %int %8 %8 288fd4e5da5Sopenharmony_ciOpReturn 289fd4e5da5Sopenharmony_ciOpFunctionEnd 290fd4e5da5Sopenharmony_ci)"; 291fd4e5da5Sopenharmony_ci 292fd4e5da5Sopenharmony_ci const std::string after = R"(OpCapability Shader 293fd4e5da5Sopenharmony_ciOpCapability ShaderNonUniform 294fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 295fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 296fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" 297fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 298fd4e5da5Sopenharmony_ciOpSource GLSL 430 299fd4e5da5Sopenharmony_ciOpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 300fd4e5da5Sopenharmony_ciOpSourceExtension "GL_GOOGLE_include_directive" 301fd4e5da5Sopenharmony_ciOpDecorate %3 NonUniform 302fd4e5da5Sopenharmony_ci%void = OpTypeVoid 303fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 304fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 305fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %5 306fd4e5da5Sopenharmony_ci%7 = OpLabel 307fd4e5da5Sopenharmony_ci%3 = OpUndef %int 308fd4e5da5Sopenharmony_ci%9 = OpIAdd %int %3 %3 309fd4e5da5Sopenharmony_ciOpReturn 310fd4e5da5Sopenharmony_ciOpFunctionEnd 311fd4e5da5Sopenharmony_ci)"; 312fd4e5da5Sopenharmony_ci 313fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<SimplificationPass>(before, after, false); 314fd4e5da5Sopenharmony_ci} 315fd4e5da5Sopenharmony_ci 316fd4e5da5Sopenharmony_ciTEST_F(SimplificationTest, DontMoveDecorations) { 317fd4e5da5Sopenharmony_ci const std::string spirv = R"( 318fd4e5da5Sopenharmony_ci; CHECK-NOT: RelaxedPrecision 319fd4e5da5Sopenharmony_ci; CHECK: [[sub:%\w+]] = OpFSub 320fd4e5da5Sopenharmony_ci; CHECK: OpStore {{.*}} [[sub]] 321fd4e5da5Sopenharmony_ciOpCapability Shader 322fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 323fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 324fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 325fd4e5da5Sopenharmony_ciOpDecorate %add RelaxedPrecision 326fd4e5da5Sopenharmony_ciOpDecorate %block Block 327fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 Offset 0 328fd4e5da5Sopenharmony_ciOpMemberDecorate %block 1 Offset 4 329fd4e5da5Sopenharmony_ciOpDecorate %in DescriptorSet 0 330fd4e5da5Sopenharmony_ciOpDecorate %in Binding 0 331fd4e5da5Sopenharmony_ciOpDecorate %out DescriptorSet 0 332fd4e5da5Sopenharmony_ciOpDecorate %out Binding 1 333fd4e5da5Sopenharmony_ci%void = OpTypeVoid 334fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 335fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 336fd4e5da5Sopenharmony_ci%block = OpTypeStruct %float %float 337fd4e5da5Sopenharmony_ci%ptr_ssbo_block = OpTypePointer StorageBuffer %block 338fd4e5da5Sopenharmony_ci%in = OpVariable %ptr_ssbo_block StorageBuffer 339fd4e5da5Sopenharmony_ci%out = OpVariable %ptr_ssbo_block StorageBuffer 340fd4e5da5Sopenharmony_ci%ptr_ssbo_float = OpTypePointer StorageBuffer %float 341fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 342fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 343fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 344fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 345fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 346fd4e5da5Sopenharmony_ci%entry = OpLabel 347fd4e5da5Sopenharmony_ci%in_gep_0 = OpAccessChain %ptr_ssbo_float %in %int_0 348fd4e5da5Sopenharmony_ci%in_gep_1 = OpAccessChain %ptr_ssbo_float %in %int_1 349fd4e5da5Sopenharmony_ci%load_0 = OpLoad %float %in_gep_0 350fd4e5da5Sopenharmony_ci%load_1 = OpLoad %float %in_gep_1 351fd4e5da5Sopenharmony_ci%sub = OpFSub %float %load_0 %load_1 352fd4e5da5Sopenharmony_ci%add = OpFAdd %float %float_0 %sub 353fd4e5da5Sopenharmony_ci%out_gep_0 = OpAccessChain %ptr_ssbo_float %out %int_0 354fd4e5da5Sopenharmony_ciOpStore %out_gep_0 %add 355fd4e5da5Sopenharmony_ciOpReturn 356fd4e5da5Sopenharmony_ciOpFunctionEnd 357fd4e5da5Sopenharmony_ci)"; 358fd4e5da5Sopenharmony_ci 359fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<SimplificationPass>(spirv, true); 360fd4e5da5Sopenharmony_ci} 361fd4e5da5Sopenharmony_ci 362fd4e5da5Sopenharmony_ciTEST_F(SimplificationTest, FunctionDeclaration) { 363fd4e5da5Sopenharmony_ci // Make sure the pass works with a function declaration that is called. 364fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Addresses 365fd4e5da5Sopenharmony_ciOpCapability Linkage 366fd4e5da5Sopenharmony_ciOpCapability Kernel 367fd4e5da5Sopenharmony_ciOpCapability Int8 368fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.std" 369fd4e5da5Sopenharmony_ciOpMemoryModel Physical64 OpenCL 370fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %2 "_Z23julia__1166_kernel_77094Bool" 371fd4e5da5Sopenharmony_ciOpExecutionMode %2 ContractionOff 372fd4e5da5Sopenharmony_ciOpSource Unknown 0 373fd4e5da5Sopenharmony_ciOpDecorate %3 LinkageAttributes "julia_error_7712" Import 374fd4e5da5Sopenharmony_ci%void = OpTypeVoid 375fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 376fd4e5da5Sopenharmony_ci%3 = OpFunction %void None %5 377fd4e5da5Sopenharmony_ciOpFunctionEnd 378fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %5 379fd4e5da5Sopenharmony_ci%6 = OpLabel 380fd4e5da5Sopenharmony_ci%7 = OpFunctionCall %void %3 381fd4e5da5Sopenharmony_ciOpReturn 382fd4e5da5Sopenharmony_ciOpFunctionEnd 383fd4e5da5Sopenharmony_ci)"; 384fd4e5da5Sopenharmony_ci 385fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<SimplificationPass>(text, text, false); 386fd4e5da5Sopenharmony_ci} 387fd4e5da5Sopenharmony_ci} // namespace 388fd4e5da5Sopenharmony_ci} // namespace opt 389fd4e5da5Sopenharmony_ci} // namespace spvtools 390