1fd4e5da5Sopenharmony_ci// Copyright (c) 2017 Google Inc. 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 "source/opt/scalar_replacement_pass.h" 18fd4e5da5Sopenharmony_ci#include "test/opt/assembly_builder.h" 19fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 20fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 21fd4e5da5Sopenharmony_ci 22fd4e5da5Sopenharmony_cinamespace spvtools { 23fd4e5da5Sopenharmony_cinamespace opt { 24fd4e5da5Sopenharmony_cinamespace { 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_ciusing ScalarReplacementPassName = ::testing::Test; 27fd4e5da5Sopenharmony_ci 28fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementPassName, Default) { 29fd4e5da5Sopenharmony_ci auto srp = ScalarReplacementPass(); 30fd4e5da5Sopenharmony_ci EXPECT_STREQ(srp.name(), "scalar-replacement=100"); 31fd4e5da5Sopenharmony_ci} 32fd4e5da5Sopenharmony_ci 33fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementPassName, Large) { 34fd4e5da5Sopenharmony_ci auto srp = ScalarReplacementPass(0xffffffffu); 35fd4e5da5Sopenharmony_ci EXPECT_STREQ(srp.name(), "scalar-replacement=4294967295"); 36fd4e5da5Sopenharmony_ci} 37fd4e5da5Sopenharmony_ci 38fd4e5da5Sopenharmony_ciusing ScalarReplacementTest = PassTest<::testing::Test>; 39fd4e5da5Sopenharmony_ci 40fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, SimpleStruct) { 41fd4e5da5Sopenharmony_ci const std::string text = R"( 42fd4e5da5Sopenharmony_ci; 43fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct [[elem:%\w+]] 44fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Function [[struct]] 45fd4e5da5Sopenharmony_ci; CHECK: [[elem_ptr:%\w+]] = OpTypePointer Function [[elem]] 46fd4e5da5Sopenharmony_ci; CHECK: OpConstantNull [[struct]] 47fd4e5da5Sopenharmony_ci; CHECK: [[null:%\w+]] = OpConstantNull [[elem]] 48fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[struct_ptr]] 49fd4e5da5Sopenharmony_ci; CHECK: [[one:%\w+]] = OpVariable [[elem_ptr]] Function [[null]] 50fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[two:%\w+]] = OpVariable [[elem_ptr]] Function [[null]] 51fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[elem_ptr]] Function [[null]] 52fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[struct_ptr]] 53fd4e5da5Sopenharmony_ci; CHECK-NOT: OpInBoundsAccessChain 54fd4e5da5Sopenharmony_ci; CHECK: [[l1:%\w+]] = OpLoad [[elem]] [[two]] 55fd4e5da5Sopenharmony_ci; CHECK-NOT: OpAccessChain 56fd4e5da5Sopenharmony_ci; CHECK: [[l2:%\w+]] = OpLoad [[elem]] [[one]] 57fd4e5da5Sopenharmony_ci; CHECK: OpIAdd [[elem]] [[l1]] [[l2]] 58fd4e5da5Sopenharmony_ci; 59fd4e5da5Sopenharmony_ciOpCapability Shader 60fd4e5da5Sopenharmony_ciOpCapability Linkage 61fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 62fd4e5da5Sopenharmony_ciOpName %6 "simple_struct" 63fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 64fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 65fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 %2 %2 66fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 67fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %2 68fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 69fd4e5da5Sopenharmony_ci%7 = OpConstantNull %3 70fd4e5da5Sopenharmony_ci%8 = OpConstant %2 0 71fd4e5da5Sopenharmony_ci%9 = OpConstant %2 1 72fd4e5da5Sopenharmony_ci%10 = OpConstant %2 2 73fd4e5da5Sopenharmony_ci%11 = OpConstant %2 3 74fd4e5da5Sopenharmony_ci%12 = OpFunction %2 None %6 75fd4e5da5Sopenharmony_ci%13 = OpLabel 76fd4e5da5Sopenharmony_ci%14 = OpVariable %4 Function %7 77fd4e5da5Sopenharmony_ci%15 = OpInBoundsAccessChain %5 %14 %8 78fd4e5da5Sopenharmony_ci%16 = OpLoad %2 %15 79fd4e5da5Sopenharmony_ci%17 = OpAccessChain %5 %14 %10 80fd4e5da5Sopenharmony_ci%18 = OpLoad %2 %17 81fd4e5da5Sopenharmony_ci%19 = OpIAdd %2 %16 %18 82fd4e5da5Sopenharmony_ciOpReturnValue %19 83fd4e5da5Sopenharmony_ciOpFunctionEnd 84fd4e5da5Sopenharmony_ci )"; 85fd4e5da5Sopenharmony_ci 86fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 87fd4e5da5Sopenharmony_ci} 88fd4e5da5Sopenharmony_ci 89fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, StructInitialization) { 90fd4e5da5Sopenharmony_ci const std::string text = R"( 91fd4e5da5Sopenharmony_ci; 92fd4e5da5Sopenharmony_ci; CHECK: [[elem:%\w+]] = OpTypeInt 32 0 93fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct [[elem]] [[elem]] [[elem]] [[elem]] 94fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Function [[struct]] 95fd4e5da5Sopenharmony_ci; CHECK: [[elem_ptr:%\w+]] = OpTypePointer Function [[elem]] 96fd4e5da5Sopenharmony_ci; CHECK: [[zero:%\w+]] = OpConstant [[elem]] 0 97fd4e5da5Sopenharmony_ci; CHECK: [[undef:%\w+]] = OpUndef [[elem]] 98fd4e5da5Sopenharmony_ci; CHECK: [[two:%\w+]] = OpConstant [[elem]] 2 99fd4e5da5Sopenharmony_ci; CHECK: [[null:%\w+]] = OpConstantNull [[elem]] 100fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[struct_ptr]] 101fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[elem_ptr]] Function [[null]] 102fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[elem_ptr]] Function [[two]] 103fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[elem_ptr]] Function [[undef]] 104fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[elem_ptr]] Function 105fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[elem_ptr]] Function [[zero]] 106fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[elem_ptr]] Function [[undef]] 107fd4e5da5Sopenharmony_ci; 108fd4e5da5Sopenharmony_ciOpCapability Shader 109fd4e5da5Sopenharmony_ciOpCapability Linkage 110fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 111fd4e5da5Sopenharmony_ciOpName %6 "struct_init" 112fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 113fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 114fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 %2 %2 115fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 116fd4e5da5Sopenharmony_ci%20 = OpTypePointer Function %2 117fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %1 118fd4e5da5Sopenharmony_ci%7 = OpConstant %2 0 119fd4e5da5Sopenharmony_ci%8 = OpUndef %2 120fd4e5da5Sopenharmony_ci%9 = OpConstant %2 2 121fd4e5da5Sopenharmony_ci%30 = OpConstant %2 1 122fd4e5da5Sopenharmony_ci%31 = OpConstant %2 3 123fd4e5da5Sopenharmony_ci%10 = OpConstantNull %2 124fd4e5da5Sopenharmony_ci%11 = OpConstantComposite %3 %7 %8 %9 %10 125fd4e5da5Sopenharmony_ci%12 = OpFunction %1 None %6 126fd4e5da5Sopenharmony_ci%13 = OpLabel 127fd4e5da5Sopenharmony_ci%14 = OpVariable %4 Function %11 128fd4e5da5Sopenharmony_ci%15 = OpAccessChain %20 %14 %7 129fd4e5da5Sopenharmony_ciOpStore %15 %10 130fd4e5da5Sopenharmony_ci%16 = OpAccessChain %20 %14 %9 131fd4e5da5Sopenharmony_ciOpStore %16 %10 132fd4e5da5Sopenharmony_ci%17 = OpAccessChain %20 %14 %30 133fd4e5da5Sopenharmony_ciOpStore %17 %10 134fd4e5da5Sopenharmony_ci%18 = OpAccessChain %20 %14 %31 135fd4e5da5Sopenharmony_ciOpStore %18 %10 136fd4e5da5Sopenharmony_ciOpReturn 137fd4e5da5Sopenharmony_ciOpFunctionEnd 138fd4e5da5Sopenharmony_ci )"; 139fd4e5da5Sopenharmony_ci 140fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 141fd4e5da5Sopenharmony_ci} 142fd4e5da5Sopenharmony_ci 143fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, SpecConstantInitialization) { 144fd4e5da5Sopenharmony_ci const std::string text = R"( 145fd4e5da5Sopenharmony_ci; 146fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0 147fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct [[int]] [[int]] 148fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Function [[struct]] 149fd4e5da5Sopenharmony_ci; CHECK: [[int_ptr:%\w+]] = OpTypePointer Function [[int]] 150fd4e5da5Sopenharmony_ci; CHECK: [[spec_comp:%\w+]] = OpSpecConstantComposite [[struct]] 151fd4e5da5Sopenharmony_ci; CHECK: [[ex0:%\w+]] = OpSpecConstantOp [[int]] CompositeExtract [[spec_comp]] 0 152fd4e5da5Sopenharmony_ci; CHECK: [[ex1:%\w+]] = OpSpecConstantOp [[int]] CompositeExtract [[spec_comp]] 1 153fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[struct]] 154fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[int_ptr]] Function [[ex1]] 155fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[int_ptr]] Function [[ex0]] 156fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[struct]] 157fd4e5da5Sopenharmony_ci; 158fd4e5da5Sopenharmony_ciOpCapability Shader 159fd4e5da5Sopenharmony_ciOpCapability Linkage 160fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 161fd4e5da5Sopenharmony_ciOpName %6 "spec_const" 162fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 163fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 164fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 165fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 166fd4e5da5Sopenharmony_ci%20 = OpTypePointer Function %2 167fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %1 168fd4e5da5Sopenharmony_ci%6 = OpConstant %2 0 169fd4e5da5Sopenharmony_ci%30 = OpConstant %2 1 170fd4e5da5Sopenharmony_ci%7 = OpSpecConstant %2 0 171fd4e5da5Sopenharmony_ci%8 = OpSpecConstantOp %2 IAdd %7 %7 172fd4e5da5Sopenharmony_ci%9 = OpSpecConstantComposite %3 %7 %8 173fd4e5da5Sopenharmony_ci%10 = OpFunction %1 None %5 174fd4e5da5Sopenharmony_ci%11 = OpLabel 175fd4e5da5Sopenharmony_ci%12 = OpVariable %4 Function %9 176fd4e5da5Sopenharmony_ci%13 = OpAccessChain %20 %12 %6 177fd4e5da5Sopenharmony_ci%14 = OpLoad %2 %13 178fd4e5da5Sopenharmony_ci%15 = OpAccessChain %20 %12 %30 179fd4e5da5Sopenharmony_ci%16 = OpLoad %2 %15 180fd4e5da5Sopenharmony_ciOpReturn 181fd4e5da5Sopenharmony_ciOpFunctionEnd 182fd4e5da5Sopenharmony_ci )"; 183fd4e5da5Sopenharmony_ci 184fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 185fd4e5da5Sopenharmony_ci} 186fd4e5da5Sopenharmony_ci 187fd4e5da5Sopenharmony_ci// TODO(alanbaker): Re-enable when vector and matrix scalarization is supported. 188fd4e5da5Sopenharmony_ci// TEST_F(ScalarReplacementTest, VectorInitialization) { 189fd4e5da5Sopenharmony_ci// const std::string text = R"( 190fd4e5da5Sopenharmony_ci// ; 191fd4e5da5Sopenharmony_ci// ; CHECK: [[elem:%\w+]] = OpTypeInt 32 0 192fd4e5da5Sopenharmony_ci// ; CHECK: [[vector:%\w+]] = OpTypeVector [[elem]] 4 193fd4e5da5Sopenharmony_ci// ; CHECK: [[vector_ptr:%\w+]] = OpTypePointer Function [[vector]] 194fd4e5da5Sopenharmony_ci// ; CHECK: [[elem_ptr:%\w+]] = OpTypePointer Function [[elem]] 195fd4e5da5Sopenharmony_ci// ; CHECK: [[zero:%\w+]] = OpConstant [[elem]] 0 196fd4e5da5Sopenharmony_ci// ; CHECK: [[undef:%\w+]] = OpUndef [[elem]] 197fd4e5da5Sopenharmony_ci// ; CHECK: [[two:%\w+]] = OpConstant [[elem]] 2 198fd4e5da5Sopenharmony_ci// ; CHECK: [[null:%\w+]] = OpConstantNull [[elem]] 199fd4e5da5Sopenharmony_ci// ; CHECK-NOT: OpVariable [[vector_ptr]] 200fd4e5da5Sopenharmony_ci// ; CHECK: OpVariable [[elem_ptr]] Function [[zero]] 201fd4e5da5Sopenharmony_ci// ; CHECK-NOT: OpVariable [[elem_ptr]] Function [[undef]] 202fd4e5da5Sopenharmony_ci// ; CHECK-NEXT: OpVariable [[elem_ptr]] Function 203fd4e5da5Sopenharmony_ci// ; CHECK-NEXT: OpVariable [[elem_ptr]] Function [[two]] 204fd4e5da5Sopenharmony_ci// ; CHECK-NEXT: OpVariable [[elem_ptr]] Function [[null]] 205fd4e5da5Sopenharmony_ci// ; CHECK-NOT: OpVariable [[elem_ptr]] Function [[undef]] 206fd4e5da5Sopenharmony_ci// ; 207fd4e5da5Sopenharmony_ci// OpCapability Shader 208fd4e5da5Sopenharmony_ci// OpCapability Linkage 209fd4e5da5Sopenharmony_ci// OpMemoryModel Logical GLSL450 210fd4e5da5Sopenharmony_ci// OpName %6 "vector_init" 211fd4e5da5Sopenharmony_ci// %1 = OpTypeVoid 212fd4e5da5Sopenharmony_ci// %2 = OpTypeInt 32 0 213fd4e5da5Sopenharmony_ci// %3 = OpTypeVector %2 4 214fd4e5da5Sopenharmony_ci// %4 = OpTypePointer Function %3 215fd4e5da5Sopenharmony_ci// %20 = OpTypePointer Function %2 216fd4e5da5Sopenharmony_ci// %6 = OpTypeFunction %1 217fd4e5da5Sopenharmony_ci// %7 = OpConstant %2 0 218fd4e5da5Sopenharmony_ci// %8 = OpUndef %2 219fd4e5da5Sopenharmony_ci// %9 = OpConstant %2 2 220fd4e5da5Sopenharmony_ci// %30 = OpConstant %2 1 221fd4e5da5Sopenharmony_ci// %31 = OpConstant %2 3 222fd4e5da5Sopenharmony_ci// %10 = OpConstantNull %2 223fd4e5da5Sopenharmony_ci// %11 = OpConstantComposite %3 %10 %9 %8 %7 224fd4e5da5Sopenharmony_ci// %12 = OpFunction %1 None %6 225fd4e5da5Sopenharmony_ci// %13 = OpLabel 226fd4e5da5Sopenharmony_ci// %14 = OpVariable %4 Function %11 227fd4e5da5Sopenharmony_ci// %15 = OpAccessChain %20 %14 %7 228fd4e5da5Sopenharmony_ci// OpStore %15 %10 229fd4e5da5Sopenharmony_ci// %16 = OpAccessChain %20 %14 %9 230fd4e5da5Sopenharmony_ci// OpStore %16 %10 231fd4e5da5Sopenharmony_ci// %17 = OpAccessChain %20 %14 %30 232fd4e5da5Sopenharmony_ci// OpStore %17 %10 233fd4e5da5Sopenharmony_ci// %18 = OpAccessChain %20 %14 %31 234fd4e5da5Sopenharmony_ci// OpStore %18 %10 235fd4e5da5Sopenharmony_ci// OpReturn 236fd4e5da5Sopenharmony_ci// OpFunctionEnd 237fd4e5da5Sopenharmony_ci// )"; 238fd4e5da5Sopenharmony_ci// 239fd4e5da5Sopenharmony_ci// SinglePassRunAndMatch<opt::ScalarReplacementPass>(text, true); 240fd4e5da5Sopenharmony_ci// } 241fd4e5da5Sopenharmony_ci// 242fd4e5da5Sopenharmony_ci// TEST_F(ScalarReplacementTest, MatrixInitialization) { 243fd4e5da5Sopenharmony_ci// const std::string text = R"( 244fd4e5da5Sopenharmony_ci// ; 245fd4e5da5Sopenharmony_ci// ; CHECK: [[float:%\w+]] = OpTypeFloat 32 246fd4e5da5Sopenharmony_ci// ; CHECK: [[vector:%\w+]] = OpTypeVector [[float]] 2 247fd4e5da5Sopenharmony_ci// ; CHECK: [[matrix:%\w+]] = OpTypeMatrix [[vector]] 2 248fd4e5da5Sopenharmony_ci// ; CHECK: [[matrix_ptr:%\w+]] = OpTypePointer Function [[matrix]] 249fd4e5da5Sopenharmony_ci// ; CHECK: [[float_ptr:%\w+]] = OpTypePointer Function [[float]] 250fd4e5da5Sopenharmony_ci// ; CHECK: [[vec_ptr:%\w+]] = OpTypePointer Function [[vector]] 251fd4e5da5Sopenharmony_ci// ; CHECK: [[zerof:%\w+]] = OpConstant [[float]] 0 252fd4e5da5Sopenharmony_ci// ; CHECK: [[onef:%\w+]] = OpConstant [[float]] 1 253fd4e5da5Sopenharmony_ci// ; CHECK: [[one_zero:%\w+]] = OpConstantComposite [[vector]] [[onef]] 254fd4e5da5Sopenharmony_ci// [[zerof]] ; CHECK: [[zero_one:%\w+]] = OpConstantComposite [[vector]] 255fd4e5da5Sopenharmony_ci// [[zerof]] [[onef]] ; CHECK: [[const_mat:%\w+]] = OpConstantComposite 256fd4e5da5Sopenharmony_ci// [[matrix]] [[one_zero]] 257fd4e5da5Sopenharmony_ci// [[zero_one]] ; CHECK-NOT: OpVariable [[matrix]] ; CHECK-NOT: OpVariable 258fd4e5da5Sopenharmony_ci// [[vector]] Function [[one_zero]] ; CHECK: [[f1:%\w+]] = OpVariable 259fd4e5da5Sopenharmony_ci// [[float_ptr]] Function [[zerof]] ; CHECK-NEXT: [[f2:%\w+]] = OpVariable 260fd4e5da5Sopenharmony_ci// [[float_ptr]] Function [[onef]] ; CHECK-NEXT: [[vec_var:%\w+]] = OpVariable 261fd4e5da5Sopenharmony_ci// [[vec_ptr]] Function [[zero_one]] ; CHECK-NOT: OpVariable [[matrix]] ; 262fd4e5da5Sopenharmony_ci// CHECK-NOT: OpVariable [[vector]] Function [[one_zero]] 263fd4e5da5Sopenharmony_ci// ; 264fd4e5da5Sopenharmony_ci// OpCapability Shader 265fd4e5da5Sopenharmony_ci// OpCapability Linkage 266fd4e5da5Sopenharmony_ci// OpMemoryModel Logical GLSL450 267fd4e5da5Sopenharmony_ci// OpName %7 "matrix_init" 268fd4e5da5Sopenharmony_ci// %1 = OpTypeVoid 269fd4e5da5Sopenharmony_ci// %2 = OpTypeFloat 32 270fd4e5da5Sopenharmony_ci// %3 = OpTypeVector %2 2 271fd4e5da5Sopenharmony_ci// %4 = OpTypeMatrix %3 2 272fd4e5da5Sopenharmony_ci// %5 = OpTypePointer Function %4 273fd4e5da5Sopenharmony_ci// %6 = OpTypePointer Function %2 274fd4e5da5Sopenharmony_ci// %30 = OpTypePointer Function %3 275fd4e5da5Sopenharmony_ci// %10 = OpTypeInt 32 0 276fd4e5da5Sopenharmony_ci// %7 = OpTypeFunction %1 %10 277fd4e5da5Sopenharmony_ci// %8 = OpConstant %2 0.0 278fd4e5da5Sopenharmony_ci// %9 = OpConstant %2 1.0 279fd4e5da5Sopenharmony_ci// %11 = OpConstant %10 0 280fd4e5da5Sopenharmony_ci// %12 = OpConstant %10 1 281fd4e5da5Sopenharmony_ci// %13 = OpConstantComposite %3 %9 %8 282fd4e5da5Sopenharmony_ci// %14 = OpConstantComposite %3 %8 %9 283fd4e5da5Sopenharmony_ci// %15 = OpConstantComposite %4 %13 %14 284fd4e5da5Sopenharmony_ci// %16 = OpFunction %1 None %7 285fd4e5da5Sopenharmony_ci// %31 = OpFunctionParameter %10 286fd4e5da5Sopenharmony_ci// %17 = OpLabel 287fd4e5da5Sopenharmony_ci// %18 = OpVariable %5 Function %15 288fd4e5da5Sopenharmony_ci// %19 = OpAccessChain %6 %18 %11 %12 289fd4e5da5Sopenharmony_ci// OpStore %19 %8 290fd4e5da5Sopenharmony_ci// %20 = OpAccessChain %6 %18 %11 %11 291fd4e5da5Sopenharmony_ci// OpStore %20 %8 292fd4e5da5Sopenharmony_ci// %21 = OpAccessChain %30 %18 %12 293fd4e5da5Sopenharmony_ci// OpStore %21 %14 294fd4e5da5Sopenharmony_ci// OpReturn 295fd4e5da5Sopenharmony_ci// OpFunctionEnd 296fd4e5da5Sopenharmony_ci// )"; 297fd4e5da5Sopenharmony_ci// 298fd4e5da5Sopenharmony_ci// SinglePassRunAndMatch<opt::ScalarReplacementPass>(text, true); 299fd4e5da5Sopenharmony_ci// } 300fd4e5da5Sopenharmony_ci 301fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ElideAccessChain) { 302fd4e5da5Sopenharmony_ci const std::string text = R"( 303fd4e5da5Sopenharmony_ci; 304fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable 305fd4e5da5Sopenharmony_ci; CHECK-NOT: OpAccessChain 306fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var]] 307fd4e5da5Sopenharmony_ci; 308fd4e5da5Sopenharmony_ciOpCapability Shader 309fd4e5da5Sopenharmony_ciOpCapability Linkage 310fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 311fd4e5da5Sopenharmony_ciOpName %6 "elide_access_chain" 312fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 313fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 314fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 %2 %2 315fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 316fd4e5da5Sopenharmony_ci%20 = OpTypePointer Function %2 317fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %1 318fd4e5da5Sopenharmony_ci%7 = OpConstant %2 0 319fd4e5da5Sopenharmony_ci%8 = OpUndef %2 320fd4e5da5Sopenharmony_ci%9 = OpConstant %2 2 321fd4e5da5Sopenharmony_ci%10 = OpConstantNull %2 322fd4e5da5Sopenharmony_ci%11 = OpConstantComposite %3 %7 %8 %9 %10 323fd4e5da5Sopenharmony_ci%12 = OpFunction %1 None %6 324fd4e5da5Sopenharmony_ci%13 = OpLabel 325fd4e5da5Sopenharmony_ci%14 = OpVariable %4 Function %11 326fd4e5da5Sopenharmony_ci%15 = OpAccessChain %20 %14 %7 327fd4e5da5Sopenharmony_ciOpStore %15 %10 328fd4e5da5Sopenharmony_ciOpReturn 329fd4e5da5Sopenharmony_ciOpFunctionEnd 330fd4e5da5Sopenharmony_ci )"; 331fd4e5da5Sopenharmony_ci 332fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 333fd4e5da5Sopenharmony_ci} 334fd4e5da5Sopenharmony_ci 335fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ElideMultipleAccessChains) { 336fd4e5da5Sopenharmony_ci const std::string text = R"( 337fd4e5da5Sopenharmony_ci; 338fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable 339fd4e5da5Sopenharmony_ci; CHECK-NOT: OpInBoundsAccessChain 340fd4e5da5Sopenharmony_ci; CHECK OpStore [[var]] 341fd4e5da5Sopenharmony_ci; 342fd4e5da5Sopenharmony_ciOpCapability Shader 343fd4e5da5Sopenharmony_ciOpCapability Linkage 344fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 345fd4e5da5Sopenharmony_ciOpName %6 "elide_two_access_chains" 346fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 347fd4e5da5Sopenharmony_ci%2 = OpTypeFloat 32 348fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 349fd4e5da5Sopenharmony_ci%4 = OpTypeStruct %3 %3 350fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %4 351fd4e5da5Sopenharmony_ci%6 = OpTypePointer Function %2 352fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %1 353fd4e5da5Sopenharmony_ci%8 = OpConstant %2 0.0 354fd4e5da5Sopenharmony_ci%9 = OpConstant %2 1.0 355fd4e5da5Sopenharmony_ci%10 = OpTypeInt 32 0 356fd4e5da5Sopenharmony_ci%11 = OpConstant %10 0 357fd4e5da5Sopenharmony_ci%12 = OpConstant %10 1 358fd4e5da5Sopenharmony_ci%13 = OpConstantComposite %3 %9 %8 359fd4e5da5Sopenharmony_ci%14 = OpConstantComposite %3 %8 %9 360fd4e5da5Sopenharmony_ci%15 = OpConstantComposite %4 %13 %14 361fd4e5da5Sopenharmony_ci%16 = OpFunction %1 None %7 362fd4e5da5Sopenharmony_ci%17 = OpLabel 363fd4e5da5Sopenharmony_ci%18 = OpVariable %5 Function %15 364fd4e5da5Sopenharmony_ci%19 = OpInBoundsAccessChain %6 %18 %11 %12 365fd4e5da5Sopenharmony_ciOpStore %19 %8 366fd4e5da5Sopenharmony_ciOpReturn 367fd4e5da5Sopenharmony_ciOpFunctionEnd 368fd4e5da5Sopenharmony_ci )"; 369fd4e5da5Sopenharmony_ci 370fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 371fd4e5da5Sopenharmony_ci} 372fd4e5da5Sopenharmony_ci 373fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ReplaceAccessChain) { 374fd4e5da5Sopenharmony_ci const std::string text = R"( 375fd4e5da5Sopenharmony_ci; 376fd4e5da5Sopenharmony_ci; CHECK: [[param:%\w+]] = OpFunctionParameter 377fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable 378fd4e5da5Sopenharmony_ci; CHECK: [[access:%\w+]] = OpAccessChain {{%\w+}} [[var]] [[param]] 379fd4e5da5Sopenharmony_ci; CHECK: OpStore [[access]] 380fd4e5da5Sopenharmony_ci; 381fd4e5da5Sopenharmony_ciOpCapability Shader 382fd4e5da5Sopenharmony_ciOpCapability Linkage 383fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 384fd4e5da5Sopenharmony_ciOpName %7 "replace_access_chain" 385fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 386fd4e5da5Sopenharmony_ci%2 = OpTypeFloat 32 387fd4e5da5Sopenharmony_ci%10 = OpTypeInt 32 0 388fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %10 2 389fd4e5da5Sopenharmony_ci%3 = OpTypeArray %2 %uint_2 390fd4e5da5Sopenharmony_ci%4 = OpTypeStruct %3 %3 391fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %4 392fd4e5da5Sopenharmony_ci%20 = OpTypePointer Function %3 393fd4e5da5Sopenharmony_ci%6 = OpTypePointer Function %2 394fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %1 %10 395fd4e5da5Sopenharmony_ci%8 = OpConstant %2 0.0 396fd4e5da5Sopenharmony_ci%9 = OpConstant %2 1.0 397fd4e5da5Sopenharmony_ci%11 = OpConstant %10 0 398fd4e5da5Sopenharmony_ci%12 = OpConstant %10 1 399fd4e5da5Sopenharmony_ci%13 = OpConstantComposite %3 %9 %8 400fd4e5da5Sopenharmony_ci%14 = OpConstantComposite %3 %8 %9 401fd4e5da5Sopenharmony_ci%15 = OpConstantComposite %4 %13 %14 402fd4e5da5Sopenharmony_ci%16 = OpFunction %1 None %7 403fd4e5da5Sopenharmony_ci%32 = OpFunctionParameter %10 404fd4e5da5Sopenharmony_ci%17 = OpLabel 405fd4e5da5Sopenharmony_ci%18 = OpVariable %5 Function %15 406fd4e5da5Sopenharmony_ci%19 = OpAccessChain %6 %18 %11 %32 407fd4e5da5Sopenharmony_ciOpStore %19 %8 408fd4e5da5Sopenharmony_ciOpReturn 409fd4e5da5Sopenharmony_ciOpFunctionEnd 410fd4e5da5Sopenharmony_ci )"; 411fd4e5da5Sopenharmony_ci 412fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 413fd4e5da5Sopenharmony_ci} 414fd4e5da5Sopenharmony_ci 415fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ArrayInitialization) { 416fd4e5da5Sopenharmony_ci const std::string text = R"( 417fd4e5da5Sopenharmony_ci; 418fd4e5da5Sopenharmony_ci; CHECK: [[float:%\w+]] = OpTypeFloat 32 419fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray 420fd4e5da5Sopenharmony_ci; CHECK: [[array_ptr:%\w+]] = OpTypePointer Function [[array]] 421fd4e5da5Sopenharmony_ci; CHECK: [[float_ptr:%\w+]] = OpTypePointer Function [[float]] 422fd4e5da5Sopenharmony_ci; CHECK: [[float0:%\w+]] = OpConstant [[float]] 0 423fd4e5da5Sopenharmony_ci; CHECK: [[float1:%\w+]] = OpConstant [[float]] 1 424fd4e5da5Sopenharmony_ci; CHECK: [[float2:%\w+]] = OpConstant [[float]] 2 425fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[array_ptr]] 426fd4e5da5Sopenharmony_ci; CHECK: [[var0:%\w+]] = OpVariable [[float_ptr]] Function [[float0]] 427fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[var1:%\w+]] = OpVariable [[float_ptr]] Function [[float1]] 428fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[var2:%\w+]] = OpVariable [[float_ptr]] Function [[float2]] 429fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[array_ptr]] 430fd4e5da5Sopenharmony_ci; 431fd4e5da5Sopenharmony_ciOpCapability Shader 432fd4e5da5Sopenharmony_ciOpCapability Linkage 433fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 434fd4e5da5Sopenharmony_ciOpName %func "array_init" 435fd4e5da5Sopenharmony_ci%void = OpTypeVoid 436fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 437fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 438fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 439fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 440fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2 441fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3 442fd4e5da5Sopenharmony_ci%float_array = OpTypeArray %float %uint_3 443fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer Function %float_array 444fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer Function %float 445fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 446fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 447fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2 448fd4e5da5Sopenharmony_ci%const_array = OpConstantComposite %float_array %float_2 %float_1 %float_0 449fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 450fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 451fd4e5da5Sopenharmony_ci%2 = OpLabel 452fd4e5da5Sopenharmony_ci%3 = OpVariable %array_ptr Function %const_array 453fd4e5da5Sopenharmony_ci%4 = OpInBoundsAccessChain %float_ptr %3 %uint_0 454fd4e5da5Sopenharmony_ciOpStore %4 %float_0 455fd4e5da5Sopenharmony_ci%5 = OpInBoundsAccessChain %float_ptr %3 %uint_1 456fd4e5da5Sopenharmony_ciOpStore %5 %float_0 457fd4e5da5Sopenharmony_ci%6 = OpInBoundsAccessChain %float_ptr %3 %uint_2 458fd4e5da5Sopenharmony_ciOpStore %6 %float_0 459fd4e5da5Sopenharmony_ciOpReturn 460fd4e5da5Sopenharmony_ciOpFunctionEnd 461fd4e5da5Sopenharmony_ci )"; 462fd4e5da5Sopenharmony_ci 463fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 464fd4e5da5Sopenharmony_ci} 465fd4e5da5Sopenharmony_ci 466fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, NonUniformCompositeInitialization) { 467fd4e5da5Sopenharmony_ci const std::string text = R"( 468fd4e5da5Sopenharmony_ci; 469fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 470fd4e5da5Sopenharmony_ci; CHECK: [[long:%\w+]] = OpTypeInt 64 1 471fd4e5da5Sopenharmony_ci; CHECK: [[dvector:%\w+]] = OpTypeVector 472fd4e5da5Sopenharmony_ci; CHECK: [[vector:%\w+]] = OpTypeVector 473fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray 474fd4e5da5Sopenharmony_ci; CHECK: [[matrix:%\w+]] = OpTypeMatrix 475fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%\w+]] = OpTypeStruct [[uint]] [[vector]] 476fd4e5da5Sopenharmony_ci; CHECK: [[struct2:%\w+]] = OpTypeStruct [[struct1]] [[matrix]] [[array]] [[uint]] 477fd4e5da5Sopenharmony_ci; CHECK: [[struct1_ptr:%\w+]] = OpTypePointer Function [[struct1]] 478fd4e5da5Sopenharmony_ci; CHECK: [[matrix_ptr:%\w+]] = OpTypePointer Function [[matrix]] 479fd4e5da5Sopenharmony_ci; CHECK: [[array_ptr:%\w+]] = OpTypePointer Function [[array]] 480fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 481fd4e5da5Sopenharmony_ci; CHECK: [[struct2_ptr:%\w+]] = OpTypePointer Function [[struct2]] 482fd4e5da5Sopenharmony_ci; CHECK: [[const_array:%\w+]] = OpConstantComposite [[array]] 483fd4e5da5Sopenharmony_ci; CHECK: [[const_matrix:%\w+]] = OpConstantNull [[matrix]] 484fd4e5da5Sopenharmony_ci; CHECK: [[const_struct1:%\w+]] = OpConstantComposite [[struct1]] 485fd4e5da5Sopenharmony_ci; CHECK: OpUndef [[uint]] 486fd4e5da5Sopenharmony_ci; CHECK: OpUndef [[vector]] 487fd4e5da5Sopenharmony_ci; CHECK: OpUndef [[long]] 488fd4e5da5Sopenharmony_ci; CHECK: OpFunction 489fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[struct2_ptr]] Function 490fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[uint_ptr]] Function 491fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[matrix_ptr]] Function [[const_matrix]] 492fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[struct1_ptr]] Function [[const_struct1]] 493fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[struct2_ptr]] Function 494fd4e5da5Sopenharmony_ci; 495fd4e5da5Sopenharmony_ciOpCapability Shader 496fd4e5da5Sopenharmony_ciOpCapability Linkage 497fd4e5da5Sopenharmony_ciOpCapability Int64 498fd4e5da5Sopenharmony_ciOpCapability Float64 499fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 500fd4e5da5Sopenharmony_ciOpName %func "non_uniform_composite_init" 501fd4e5da5Sopenharmony_ci%void = OpTypeVoid 502fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 503fd4e5da5Sopenharmony_ci%int64 = OpTypeInt 64 1 504fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 505fd4e5da5Sopenharmony_ci%double = OpTypeFloat 64 506fd4e5da5Sopenharmony_ci%double2 = OpTypeVector %double 2 507fd4e5da5Sopenharmony_ci%float4 = OpTypeVector %float 4 508fd4e5da5Sopenharmony_ci%int64_0 = OpConstant %int64 0 509fd4e5da5Sopenharmony_ci%int64_1 = OpConstant %int64 1 510fd4e5da5Sopenharmony_ci%int64_2 = OpConstant %int64 2 511fd4e5da5Sopenharmony_ci%int64_3 = OpConstant %int64 3 512fd4e5da5Sopenharmony_ci%int64_array3 = OpTypeArray %int64 %int64_3 513fd4e5da5Sopenharmony_ci%matrix_double2 = OpTypeMatrix %double2 2 514fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint %float4 515fd4e5da5Sopenharmony_ci%struct2 = OpTypeStruct %struct1 %matrix_double2 %int64_array3 %uint 516fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 517fd4e5da5Sopenharmony_ci%matrix_double2_ptr = OpTypePointer Function %matrix_double2 518fd4e5da5Sopenharmony_ci%int64_array_ptr = OpTypePointer Function %int64_array3 519fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 520fd4e5da5Sopenharmony_ci%struct2_ptr = OpTypePointer Function %struct2 521fd4e5da5Sopenharmony_ci%const_uint = OpConstant %uint 0 522fd4e5da5Sopenharmony_ci%const_int64_array = OpConstantComposite %int64_array3 %int64_0 %int64_1 %int64_2 523fd4e5da5Sopenharmony_ci%const_double2 = OpConstantNull %double2 524fd4e5da5Sopenharmony_ci%const_matrix_double2 = OpConstantNull %matrix_double2 525fd4e5da5Sopenharmony_ci%undef_float4 = OpUndef %float4 526fd4e5da5Sopenharmony_ci%const_struct1 = OpConstantComposite %struct1 %const_uint %undef_float4 527fd4e5da5Sopenharmony_ci%const_struct2 = OpConstantComposite %struct2 %const_struct1 %const_matrix_double2 %const_int64_array %const_uint 528fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 529fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 530fd4e5da5Sopenharmony_ci%2 = OpLabel 531fd4e5da5Sopenharmony_ci%var = OpVariable %struct2_ptr Function %const_struct2 532fd4e5da5Sopenharmony_ci%3 = OpAccessChain %struct1_ptr %var %int64_0 533fd4e5da5Sopenharmony_ciOpStore %3 %const_struct1 534fd4e5da5Sopenharmony_ci%4 = OpAccessChain %matrix_double2_ptr %var %int64_1 535fd4e5da5Sopenharmony_ciOpStore %4 %const_matrix_double2 536fd4e5da5Sopenharmony_ci%5 = OpAccessChain %int64_array_ptr %var %int64_2 537fd4e5da5Sopenharmony_ciOpStore %5 %const_int64_array 538fd4e5da5Sopenharmony_ci%6 = OpAccessChain %uint_ptr %var %int64_3 539fd4e5da5Sopenharmony_ciOpStore %6 %const_uint 540fd4e5da5Sopenharmony_ciOpReturn 541fd4e5da5Sopenharmony_ciOpFunctionEnd 542fd4e5da5Sopenharmony_ci )"; 543fd4e5da5Sopenharmony_ci 544fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 545fd4e5da5Sopenharmony_ci} 546fd4e5da5Sopenharmony_ci 547fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ElideUncombinedAccessChains) { 548fd4e5da5Sopenharmony_ci const std::string text = R"( 549fd4e5da5Sopenharmony_ci; 550fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 551fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 552fd4e5da5Sopenharmony_ci; CHECK: [[const:%\w+]] = OpConstant [[uint]] 0 553fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable [[uint_ptr]] Function 554fd4e5da5Sopenharmony_ci; CHECK-NOT: OpAccessChain 555fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var]] [[const]] 556fd4e5da5Sopenharmony_ci; 557fd4e5da5Sopenharmony_ciOpCapability Shader 558fd4e5da5Sopenharmony_ciOpCapability Linkage 559fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 560fd4e5da5Sopenharmony_ciOpName %func "elide_uncombined_access_chains" 561fd4e5da5Sopenharmony_ci%void = OpTypeVoid 562fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 563fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint 564fd4e5da5Sopenharmony_ci%struct2 = OpTypeStruct %struct1 565fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 566fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 567fd4e5da5Sopenharmony_ci%struct2_ptr = OpTypePointer Function %struct2 568fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 569fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 570fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 571fd4e5da5Sopenharmony_ci%2 = OpLabel 572fd4e5da5Sopenharmony_ci%var = OpVariable %struct2_ptr Function 573fd4e5da5Sopenharmony_ci%3 = OpAccessChain %struct1_ptr %var %uint_0 574fd4e5da5Sopenharmony_ci%4 = OpAccessChain %uint_ptr %3 %uint_0 575fd4e5da5Sopenharmony_ciOpStore %4 %uint_0 576fd4e5da5Sopenharmony_ciOpReturn 577fd4e5da5Sopenharmony_ciOpFunctionEnd 578fd4e5da5Sopenharmony_ci )"; 579fd4e5da5Sopenharmony_ci 580fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 581fd4e5da5Sopenharmony_ci} 582fd4e5da5Sopenharmony_ci 583fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ElideSingleUncombinedAccessChains) { 584fd4e5da5Sopenharmony_ci const std::string text = R"( 585fd4e5da5Sopenharmony_ci; 586fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 587fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray [[uint]] 588fd4e5da5Sopenharmony_ci; CHECK: [[array_ptr:%\w+]] = OpTypePointer Function [[array]] 589fd4e5da5Sopenharmony_ci; CHECK: [[const:%\w+]] = OpConstant [[uint]] 0 590fd4e5da5Sopenharmony_ci; CHECK: [[param:%\w+]] = OpFunctionParameter [[uint]] 591fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable [[array_ptr]] Function 592fd4e5da5Sopenharmony_ci; CHECK: [[access:%\w+]] = OpAccessChain {{.*}} [[var]] [[param]] 593fd4e5da5Sopenharmony_ci; CHECK: OpStore [[access]] [[const]] 594fd4e5da5Sopenharmony_ci; 595fd4e5da5Sopenharmony_ciOpCapability Shader 596fd4e5da5Sopenharmony_ciOpCapability Linkage 597fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 598fd4e5da5Sopenharmony_ciOpName %func "elide_single_uncombined_access_chains" 599fd4e5da5Sopenharmony_ci%void = OpTypeVoid 600fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 601fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 602fd4e5da5Sopenharmony_ci%array = OpTypeArray %uint %uint_1 603fd4e5da5Sopenharmony_ci%struct2 = OpTypeStruct %array 604fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 605fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer Function %array 606fd4e5da5Sopenharmony_ci%struct2_ptr = OpTypePointer Function %struct2 607fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 608fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void %uint 609fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 610fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %uint 611fd4e5da5Sopenharmony_ci%2 = OpLabel 612fd4e5da5Sopenharmony_ci%var = OpVariable %struct2_ptr Function 613fd4e5da5Sopenharmony_ci%3 = OpAccessChain %array_ptr %var %uint_0 614fd4e5da5Sopenharmony_ci%4 = OpAccessChain %uint_ptr %3 %param 615fd4e5da5Sopenharmony_ciOpStore %4 %uint_0 616fd4e5da5Sopenharmony_ciOpReturn 617fd4e5da5Sopenharmony_ciOpFunctionEnd 618fd4e5da5Sopenharmony_ci )"; 619fd4e5da5Sopenharmony_ci 620fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 621fd4e5da5Sopenharmony_ci} 622fd4e5da5Sopenharmony_ci 623fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ReplaceWholeLoad) { 624fd4e5da5Sopenharmony_ci const std::string text = R"( 625fd4e5da5Sopenharmony_ci; 626fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 627fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%\w+]] = OpTypeStruct [[uint]] [[uint]] 628fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 629fd4e5da5Sopenharmony_ci; CHECK: [[const:%\w+]] = OpConstant [[uint]] 0 630fd4e5da5Sopenharmony_ci; CHECK: [[var1:%\w+]] = OpVariable [[uint_ptr]] Function 631fd4e5da5Sopenharmony_ci; CHECK: [[var0:%\w+]] = OpVariable [[uint_ptr]] Function 632fd4e5da5Sopenharmony_ci; CHECK: [[l1:%\w+]] = OpLoad [[uint]] [[var1]] 633fd4e5da5Sopenharmony_ci; CHECK: [[l0:%\w+]] = OpLoad [[uint]] [[var0]] 634fd4e5da5Sopenharmony_ci; CHECK: OpCompositeConstruct [[struct1]] [[l0]] [[l1]] 635fd4e5da5Sopenharmony_ci; 636fd4e5da5Sopenharmony_ciOpCapability Shader 637fd4e5da5Sopenharmony_ciOpCapability Linkage 638fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 639fd4e5da5Sopenharmony_ciOpName %func "replace_whole_load" 640fd4e5da5Sopenharmony_ci%void = OpTypeVoid 641fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 642fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint %uint 643fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 644fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 645fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 646fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 647fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 648fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 649fd4e5da5Sopenharmony_ci%2 = OpLabel 650fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 651fd4e5da5Sopenharmony_ci%load = OpLoad %struct1 %var 652fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 653fd4e5da5Sopenharmony_ciOpStore %3 %uint_0 654fd4e5da5Sopenharmony_ci%4 = OpAccessChain %uint_ptr %var %uint_1 655fd4e5da5Sopenharmony_ciOpStore %4 %uint_0 656fd4e5da5Sopenharmony_ciOpReturn 657fd4e5da5Sopenharmony_ciOpFunctionEnd 658fd4e5da5Sopenharmony_ci )"; 659fd4e5da5Sopenharmony_ci 660fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 661fd4e5da5Sopenharmony_ci} 662fd4e5da5Sopenharmony_ci 663fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ReplaceWholeLoadCopyMemoryAccess) { 664fd4e5da5Sopenharmony_ci const std::string text = R"( 665fd4e5da5Sopenharmony_ci; 666fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 667fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%\w+]] = OpTypeStruct [[uint]] [[uint]] 668fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 669fd4e5da5Sopenharmony_ci; CHECK: [[undef:%\w+]] = OpUndef [[uint]] 670fd4e5da5Sopenharmony_ci; CHECK: [[var0:%\w+]] = OpVariable [[uint_ptr]] Function 671fd4e5da5Sopenharmony_ci; CHECK: [[l0:%\w+]] = OpLoad [[uint]] [[var0]] Nontemporal 672fd4e5da5Sopenharmony_ci; CHECK: OpCompositeConstruct [[struct1]] [[l0]] [[undef]] 673fd4e5da5Sopenharmony_ci; 674fd4e5da5Sopenharmony_ciOpCapability Shader 675fd4e5da5Sopenharmony_ciOpCapability Linkage 676fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 677fd4e5da5Sopenharmony_ciOpName %func "replace_whole_load_copy_memory_access" 678fd4e5da5Sopenharmony_ci%void = OpTypeVoid 679fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 680fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint %uint 681fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 682fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 683fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 684fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 685fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 686fd4e5da5Sopenharmony_ci%2 = OpLabel 687fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 688fd4e5da5Sopenharmony_ci%load = OpLoad %struct1 %var Nontemporal 689fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 690fd4e5da5Sopenharmony_ciOpStore %3 %uint_0 691fd4e5da5Sopenharmony_ciOpReturn 692fd4e5da5Sopenharmony_ciOpFunctionEnd 693fd4e5da5Sopenharmony_ci )"; 694fd4e5da5Sopenharmony_ci 695fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 696fd4e5da5Sopenharmony_ci} 697fd4e5da5Sopenharmony_ci 698fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ReplaceWholeStore) { 699fd4e5da5Sopenharmony_ci const std::string text = R"( 700fd4e5da5Sopenharmony_ci; 701fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 702fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%\w+]] = OpTypeStruct [[uint]] [[uint]] 703fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 704fd4e5da5Sopenharmony_ci; CHECK: [[const:%\w+]] = OpConstant [[uint]] 0 705fd4e5da5Sopenharmony_ci; CHECK: [[const_struct:%\w+]] = OpConstantComposite [[struct1]] [[const]] [[const]] 706fd4e5da5Sopenharmony_ci; CHECK: [[var0:%\w+]] = OpVariable [[uint_ptr]] Function 707fd4e5da5Sopenharmony_ci; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[uint]] [[const_struct]] 0 708fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var0]] [[ex0]] 709fd4e5da5Sopenharmony_ci; 710fd4e5da5Sopenharmony_ciOpCapability Shader 711fd4e5da5Sopenharmony_ciOpCapability Linkage 712fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 713fd4e5da5Sopenharmony_ciOpName %func "replace_whole_store" 714fd4e5da5Sopenharmony_ci%void = OpTypeVoid 715fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 716fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint %uint 717fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 718fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 719fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 720fd4e5da5Sopenharmony_ci%const_struct = OpConstantComposite %struct1 %uint_0 %uint_0 721fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 722fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 723fd4e5da5Sopenharmony_ci%2 = OpLabel 724fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 725fd4e5da5Sopenharmony_ciOpStore %var %const_struct 726fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 727fd4e5da5Sopenharmony_ci%4 = OpLoad %uint %3 728fd4e5da5Sopenharmony_ciOpReturn 729fd4e5da5Sopenharmony_ciOpFunctionEnd 730fd4e5da5Sopenharmony_ci )"; 731fd4e5da5Sopenharmony_ci 732fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 733fd4e5da5Sopenharmony_ci} 734fd4e5da5Sopenharmony_ci 735fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ReplaceWholeStoreCopyMemoryAccess) { 736fd4e5da5Sopenharmony_ci const std::string text = R"( 737fd4e5da5Sopenharmony_ci; 738fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 739fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%\w+]] = OpTypeStruct [[uint]] [[uint]] 740fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 741fd4e5da5Sopenharmony_ci; CHECK: [[const:%\w+]] = OpConstant [[uint]] 0 742fd4e5da5Sopenharmony_ci; CHECK: [[const_struct:%\w+]] = OpConstantComposite [[struct1]] [[const]] [[const]] 743fd4e5da5Sopenharmony_ci; CHECK: [[var0:%\w+]] = OpVariable [[uint_ptr]] Function 744fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 745fd4e5da5Sopenharmony_ci; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[uint]] [[const_struct]] 0 746fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var0]] [[ex0]] Aligned 4 747fd4e5da5Sopenharmony_ci; 748fd4e5da5Sopenharmony_ciOpCapability Shader 749fd4e5da5Sopenharmony_ciOpCapability Linkage 750fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 751fd4e5da5Sopenharmony_ciOpName %func "replace_whole_store_copy_memory_access" 752fd4e5da5Sopenharmony_ci%void = OpTypeVoid 753fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 754fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint %uint 755fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 756fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 757fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 758fd4e5da5Sopenharmony_ci%const_struct = OpConstantComposite %struct1 %uint_0 %uint_0 759fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 760fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 761fd4e5da5Sopenharmony_ci%2 = OpLabel 762fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 763fd4e5da5Sopenharmony_ciOpStore %var %const_struct Aligned 4 764fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 765fd4e5da5Sopenharmony_ci%4 = OpLoad %uint %3 766fd4e5da5Sopenharmony_ciOpReturn 767fd4e5da5Sopenharmony_ciOpFunctionEnd 768fd4e5da5Sopenharmony_ci )"; 769fd4e5da5Sopenharmony_ci 770fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 771fd4e5da5Sopenharmony_ci} 772fd4e5da5Sopenharmony_ci 773fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DontTouchVolatileLoad) { 774fd4e5da5Sopenharmony_ci const std::string text = R"( 775fd4e5da5Sopenharmony_ci; 776fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct 777fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Function [[struct]] 778fd4e5da5Sopenharmony_ci; CHECK: OpLabel 779fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[struct_ptr]] 780fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 781fd4e5da5Sopenharmony_ci; 782fd4e5da5Sopenharmony_ciOpCapability Shader 783fd4e5da5Sopenharmony_ciOpCapability Linkage 784fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 785fd4e5da5Sopenharmony_ciOpName %func "dont_touch_volatile_load" 786fd4e5da5Sopenharmony_ci%void = OpTypeVoid 787fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 788fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint 789fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 790fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 791fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 792fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 793fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 794fd4e5da5Sopenharmony_ci%2 = OpLabel 795fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 796fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 797fd4e5da5Sopenharmony_ci%4 = OpLoad %uint %3 Volatile 798fd4e5da5Sopenharmony_ciOpReturn 799fd4e5da5Sopenharmony_ciOpFunctionEnd 800fd4e5da5Sopenharmony_ci )"; 801fd4e5da5Sopenharmony_ci 802fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 803fd4e5da5Sopenharmony_ci} 804fd4e5da5Sopenharmony_ci 805fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DontTouchVolatileStore) { 806fd4e5da5Sopenharmony_ci const std::string text = R"( 807fd4e5da5Sopenharmony_ci; 808fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct 809fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Function [[struct]] 810fd4e5da5Sopenharmony_ci; CHECK: OpLabel 811fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[struct_ptr]] 812fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 813fd4e5da5Sopenharmony_ci; 814fd4e5da5Sopenharmony_ciOpCapability Shader 815fd4e5da5Sopenharmony_ciOpCapability Linkage 816fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 817fd4e5da5Sopenharmony_ciOpName %func "dont_touch_volatile_store" 818fd4e5da5Sopenharmony_ci%void = OpTypeVoid 819fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 820fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint 821fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 822fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 823fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 824fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 825fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 826fd4e5da5Sopenharmony_ci%2 = OpLabel 827fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 828fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 829fd4e5da5Sopenharmony_ciOpStore %3 %uint_0 Volatile 830fd4e5da5Sopenharmony_ciOpReturn 831fd4e5da5Sopenharmony_ciOpFunctionEnd 832fd4e5da5Sopenharmony_ci )"; 833fd4e5da5Sopenharmony_ci 834fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 835fd4e5da5Sopenharmony_ci} 836fd4e5da5Sopenharmony_ci 837fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DontTouchSpecNonFunctionVariable) { 838fd4e5da5Sopenharmony_ci const std::string text = R"( 839fd4e5da5Sopenharmony_ci; 840fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct 841fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Uniform [[struct]] 842fd4e5da5Sopenharmony_ci; CHECK: OpConstant 843fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[struct_ptr]] 844fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 845fd4e5da5Sopenharmony_ci; 846fd4e5da5Sopenharmony_ciOpCapability Shader 847fd4e5da5Sopenharmony_ciOpCapability Linkage 848fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 849fd4e5da5Sopenharmony_ciOpName %func "dont_touch_spec_constant_access_chain" 850fd4e5da5Sopenharmony_ci%void = OpTypeVoid 851fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 852fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint 853fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Uniform %uint 854fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Uniform %struct1 855fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 856fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Uniform 857fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 858fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 859fd4e5da5Sopenharmony_ci%2 = OpLabel 860fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 861fd4e5da5Sopenharmony_ciOpStore %3 %uint_0 Volatile 862fd4e5da5Sopenharmony_ciOpReturn 863fd4e5da5Sopenharmony_ciOpFunctionEnd 864fd4e5da5Sopenharmony_ci )"; 865fd4e5da5Sopenharmony_ci 866fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 867fd4e5da5Sopenharmony_ci} 868fd4e5da5Sopenharmony_ci 869fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DontTouchSpecConstantAccessChain) { 870fd4e5da5Sopenharmony_ci const std::string text = R"( 871fd4e5da5Sopenharmony_ci; 872fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray 873fd4e5da5Sopenharmony_ci; CHECK: [[array_ptr:%\w+]] = OpTypePointer Function [[array]] 874fd4e5da5Sopenharmony_ci; CHECK: OpLabel 875fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[array_ptr]] 876fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 877fd4e5da5Sopenharmony_ci; 878fd4e5da5Sopenharmony_ciOpCapability Shader 879fd4e5da5Sopenharmony_ciOpCapability Linkage 880fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 881fd4e5da5Sopenharmony_ciOpName %func "dont_touch_spec_constant_access_chain" 882fd4e5da5Sopenharmony_ci%void = OpTypeVoid 883fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 884fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 885fd4e5da5Sopenharmony_ci%array = OpTypeArray %uint %uint_1 886fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 887fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer Function %array 888fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 889fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %uint 0 890fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 891fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 892fd4e5da5Sopenharmony_ci%2 = OpLabel 893fd4e5da5Sopenharmony_ci%var = OpVariable %array_ptr Function 894fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %spec_const 895fd4e5da5Sopenharmony_ciOpStore %3 %uint_0 Volatile 896fd4e5da5Sopenharmony_ciOpReturn 897fd4e5da5Sopenharmony_ciOpFunctionEnd 898fd4e5da5Sopenharmony_ci )"; 899fd4e5da5Sopenharmony_ci 900fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 901fd4e5da5Sopenharmony_ci} 902fd4e5da5Sopenharmony_ci 903fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, NoPartialAccesses) { 904fd4e5da5Sopenharmony_ci const std::string text = R"( 905fd4e5da5Sopenharmony_ci; 906fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 907fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 908fd4e5da5Sopenharmony_ci; CHECK: OpLabel 909fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 910fd4e5da5Sopenharmony_ci; 911fd4e5da5Sopenharmony_ciOpCapability Shader 912fd4e5da5Sopenharmony_ciOpCapability Linkage 913fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 914fd4e5da5Sopenharmony_ciOpName %func "no_partial_accesses" 915fd4e5da5Sopenharmony_ci%void = OpTypeVoid 916fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 917fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint 918fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 919fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 920fd4e5da5Sopenharmony_ci%const = OpConstantNull %struct1 921fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 922fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 923fd4e5da5Sopenharmony_ci%2 = OpLabel 924fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 925fd4e5da5Sopenharmony_ciOpStore %var %const 926fd4e5da5Sopenharmony_ciOpReturn 927fd4e5da5Sopenharmony_ciOpFunctionEnd 928fd4e5da5Sopenharmony_ci )"; 929fd4e5da5Sopenharmony_ci 930fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 931fd4e5da5Sopenharmony_ci} 932fd4e5da5Sopenharmony_ci 933fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DontTouchPtrAccessChain) { 934fd4e5da5Sopenharmony_ci const std::string text = R"( 935fd4e5da5Sopenharmony_ci; 936fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct 937fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Function [[struct]] 938fd4e5da5Sopenharmony_ci; CHECK: OpLabel 939fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[struct_ptr]] 940fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 941fd4e5da5Sopenharmony_ci; 942fd4e5da5Sopenharmony_ciOpCapability Shader 943fd4e5da5Sopenharmony_ciOpCapability Linkage 944fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 945fd4e5da5Sopenharmony_ciOpName %func "dont_touch_ptr_access_chain" 946fd4e5da5Sopenharmony_ci%void = OpTypeVoid 947fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 948fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint 949fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 950fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 951fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 952fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 953fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 954fd4e5da5Sopenharmony_ci%2 = OpLabel 955fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 956fd4e5da5Sopenharmony_ci%3 = OpPtrAccessChain %uint_ptr %var %uint_0 %uint_0 957fd4e5da5Sopenharmony_ciOpStore %3 %uint_0 958fd4e5da5Sopenharmony_ci%4 = OpAccessChain %uint_ptr %var %uint_0 959fd4e5da5Sopenharmony_ciOpStore %4 %uint_0 960fd4e5da5Sopenharmony_ciOpReturn 961fd4e5da5Sopenharmony_ciOpFunctionEnd 962fd4e5da5Sopenharmony_ci )"; 963fd4e5da5Sopenharmony_ci 964fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, false); 965fd4e5da5Sopenharmony_ci} 966fd4e5da5Sopenharmony_ci 967fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DontTouchInBoundsPtrAccessChain) { 968fd4e5da5Sopenharmony_ci const std::string text = R"( 969fd4e5da5Sopenharmony_ci; 970fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct 971fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Function [[struct]] 972fd4e5da5Sopenharmony_ci; CHECK: OpLabel 973fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[struct_ptr]] 974fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 975fd4e5da5Sopenharmony_ci; 976fd4e5da5Sopenharmony_ciOpCapability Shader 977fd4e5da5Sopenharmony_ciOpCapability Linkage 978fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 979fd4e5da5Sopenharmony_ciOpName %func "dont_touch_in_bounds_ptr_access_chain" 980fd4e5da5Sopenharmony_ci%void = OpTypeVoid 981fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 982fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint 983fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 984fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 985fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 986fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 987fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 988fd4e5da5Sopenharmony_ci%2 = OpLabel 989fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 990fd4e5da5Sopenharmony_ci%3 = OpInBoundsPtrAccessChain %uint_ptr %var %uint_0 %uint_0 991fd4e5da5Sopenharmony_ciOpStore %3 %uint_0 992fd4e5da5Sopenharmony_ci%4 = OpInBoundsAccessChain %uint_ptr %var %uint_0 993fd4e5da5Sopenharmony_ciOpStore %4 %uint_0 994fd4e5da5Sopenharmony_ciOpReturn 995fd4e5da5Sopenharmony_ciOpFunctionEnd 996fd4e5da5Sopenharmony_ci )"; 997fd4e5da5Sopenharmony_ci 998fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, false); 999fd4e5da5Sopenharmony_ci} 1000fd4e5da5Sopenharmony_ci 1001fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DonTouchAliasedDecoration) { 1002fd4e5da5Sopenharmony_ci const std::string text = R"( 1003fd4e5da5Sopenharmony_ci; 1004fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct 1005fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Function [[struct]] 1006fd4e5da5Sopenharmony_ci; CHECK: OpLabel 1007fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[struct_ptr]] 1008fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 1009fd4e5da5Sopenharmony_ci; 1010fd4e5da5Sopenharmony_ciOpCapability Shader 1011fd4e5da5Sopenharmony_ciOpCapability Linkage 1012fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1013fd4e5da5Sopenharmony_ciOpName %func "aliased" 1014fd4e5da5Sopenharmony_ciOpDecorate %var Aliased 1015fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1016fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1017fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint 1018fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 1019fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 1020fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1021fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 1022fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 1023fd4e5da5Sopenharmony_ci%2 = OpLabel 1024fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 1025fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 1026fd4e5da5Sopenharmony_ci%4 = OpLoad %uint %3 1027fd4e5da5Sopenharmony_ciOpReturn 1028fd4e5da5Sopenharmony_ciOpFunctionEnd 1029fd4e5da5Sopenharmony_ci )"; 1030fd4e5da5Sopenharmony_ci 1031fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1032fd4e5da5Sopenharmony_ci} 1033fd4e5da5Sopenharmony_ci 1034fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, CopyRestrictDecoration) { 1035fd4e5da5Sopenharmony_ci const std::string text = R"( 1036fd4e5da5Sopenharmony_ci; 1037fd4e5da5Sopenharmony_ci; CHECK: OpName 1038fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpDecorate [[var0:%\w+]] Restrict 1039fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpDecorate [[var1:%\w+]] Restrict 1040fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 1041fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct 1042fd4e5da5Sopenharmony_ci; CHECK: [[int_ptr:%\w+]] = OpTypePointer Function [[int]] 1043fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Function [[struct]] 1044fd4e5da5Sopenharmony_ci; CHECK: OpLabel 1045fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[var1]] = OpVariable [[int_ptr]] 1046fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[var0]] = OpVariable [[int_ptr]] 1047fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[struct_ptr]] 1048fd4e5da5Sopenharmony_ci; 1049fd4e5da5Sopenharmony_ciOpCapability Shader 1050fd4e5da5Sopenharmony_ciOpCapability Linkage 1051fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1052fd4e5da5Sopenharmony_ciOpName %func "restrict" 1053fd4e5da5Sopenharmony_ciOpDecorate %var Restrict 1054fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1055fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1056fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint %uint 1057fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 1058fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 1059fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1060fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 1061fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 1062fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 1063fd4e5da5Sopenharmony_ci%2 = OpLabel 1064fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 1065fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 1066fd4e5da5Sopenharmony_ci%4 = OpLoad %uint %3 1067fd4e5da5Sopenharmony_ci%5 = OpAccessChain %uint_ptr %var %uint_1 1068fd4e5da5Sopenharmony_ci%6 = OpLoad %uint %5 1069fd4e5da5Sopenharmony_ciOpReturn 1070fd4e5da5Sopenharmony_ciOpFunctionEnd 1071fd4e5da5Sopenharmony_ci )"; 1072fd4e5da5Sopenharmony_ci 1073fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1074fd4e5da5Sopenharmony_ci} 1075fd4e5da5Sopenharmony_ci 1076fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DontClobberDecoratesOnSubtypes) { 1077fd4e5da5Sopenharmony_ci const std::string text = R"( 1078fd4e5da5Sopenharmony_ci; 1079fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[array:%\w+]] ArrayStride 1 1080fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 1081fd4e5da5Sopenharmony_ci; CHECK: [[array]] = OpTypeArray [[uint]] 1082fd4e5da5Sopenharmony_ci; CHECK: [[array_ptr:%\w+]] = OpTypePointer Function [[array]] 1083fd4e5da5Sopenharmony_ci; CHECK: OpLabel 1084fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[array_ptr]] Function 1085fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 1086fd4e5da5Sopenharmony_ci; 1087fd4e5da5Sopenharmony_ciOpCapability Shader 1088fd4e5da5Sopenharmony_ciOpCapability Linkage 1089fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1090fd4e5da5Sopenharmony_ciOpName %func "array_stride" 1091fd4e5da5Sopenharmony_ciOpDecorate %array ArrayStride 1 1092fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1093fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1094fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 1095fd4e5da5Sopenharmony_ci%array = OpTypeArray %uint %uint_1 1096fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %array 1097fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 1098fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 1099fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1100fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void %uint 1101fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 1102fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %uint 1103fd4e5da5Sopenharmony_ci%2 = OpLabel 1104fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 1105fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 %param 1106fd4e5da5Sopenharmony_ci%4 = OpLoad %uint %3 1107fd4e5da5Sopenharmony_ciOpReturn 1108fd4e5da5Sopenharmony_ciOpFunctionEnd 1109fd4e5da5Sopenharmony_ci )"; 1110fd4e5da5Sopenharmony_ci 1111fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1112fd4e5da5Sopenharmony_ci} 1113fd4e5da5Sopenharmony_ci 1114fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DontCopyMemberDecorate) { 1115fd4e5da5Sopenharmony_ci const std::string text = R"( 1116fd4e5da5Sopenharmony_ci; 1117fd4e5da5Sopenharmony_ci; CHECK-NOT: OpDecorate 1118fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 1119fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct [[uint]] 1120fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 1121fd4e5da5Sopenharmony_ci; CHECK: [[struct_ptr:%\w+]] = OpTypePointer Function [[struct]] 1122fd4e5da5Sopenharmony_ci; CHECK: OpLabel 1123fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[uint_ptr]] Function 1124fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 1125fd4e5da5Sopenharmony_ci; 1126fd4e5da5Sopenharmony_ciOpCapability Shader 1127fd4e5da5Sopenharmony_ciOpCapability Linkage 1128fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1129fd4e5da5Sopenharmony_ciOpName %func "member_decorate" 1130fd4e5da5Sopenharmony_ciOpMemberDecorate %struct1 0 Offset 1 1131fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1132fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1133fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 1134fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint 1135fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 1136fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 1137fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1138fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void %uint 1139fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 1140fd4e5da5Sopenharmony_ci%2 = OpLabel 1141fd4e5da5Sopenharmony_ci%var = OpVariable %struct1_ptr Function 1142fd4e5da5Sopenharmony_ci%3 = OpAccessChain %uint_ptr %var %uint_0 1143fd4e5da5Sopenharmony_ci%4 = OpLoad %uint %3 1144fd4e5da5Sopenharmony_ciOpReturn 1145fd4e5da5Sopenharmony_ciOpFunctionEnd 1146fd4e5da5Sopenharmony_ci )"; 1147fd4e5da5Sopenharmony_ci 1148fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1149fd4e5da5Sopenharmony_ci} 1150fd4e5da5Sopenharmony_ci 1151fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, NoPartialAccesses2) { 1152fd4e5da5Sopenharmony_ci const std::string text = R"( 1153fd4e5da5Sopenharmony_ci; 1154fd4e5da5Sopenharmony_ci; CHECK: [[float:%\w+]] = OpTypeFloat 32 1155fd4e5da5Sopenharmony_ci; CHECK: [[float_ptr:%\w+]] = OpTypePointer Function [[float]] 1156fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[float_ptr]] Function 1157fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[float_ptr]] Function 1158fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[float_ptr]] Function 1159fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[float_ptr]] Function 1160fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[float_ptr]] Function 1161fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[float_ptr]] Function 1162fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[float_ptr]] Function 1163fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 1164fd4e5da5Sopenharmony_ci; 1165fd4e5da5Sopenharmony_ciOpCapability Shader 1166fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1167fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1168fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %fo 1169fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1170fd4e5da5Sopenharmony_ciOpSource GLSL 430 1171fd4e5da5Sopenharmony_ciOpName %main "main" 1172fd4e5da5Sopenharmony_ciOpName %S "S" 1173fd4e5da5Sopenharmony_ciOpMemberName %S 0 "x" 1174fd4e5da5Sopenharmony_ciOpMemberName %S 1 "y" 1175fd4e5da5Sopenharmony_ciOpName %ts1 "ts1" 1176fd4e5da5Sopenharmony_ciOpName %S_0 "S" 1177fd4e5da5Sopenharmony_ciOpMemberName %S_0 0 "x" 1178fd4e5da5Sopenharmony_ciOpMemberName %S_0 1 "y" 1179fd4e5da5Sopenharmony_ciOpName %U_t "U_t" 1180fd4e5da5Sopenharmony_ciOpMemberName %U_t 0 "g_s1" 1181fd4e5da5Sopenharmony_ciOpMemberName %U_t 1 "g_s2" 1182fd4e5da5Sopenharmony_ciOpMemberName %U_t 2 "g_s3" 1183fd4e5da5Sopenharmony_ciOpName %_ "" 1184fd4e5da5Sopenharmony_ciOpName %ts2 "ts2" 1185fd4e5da5Sopenharmony_ciOpName %_Globals_ "_Globals_" 1186fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 0 "g_b" 1187fd4e5da5Sopenharmony_ciOpName %__0 "" 1188fd4e5da5Sopenharmony_ciOpName %ts3 "ts3" 1189fd4e5da5Sopenharmony_ciOpName %ts4 "ts4" 1190fd4e5da5Sopenharmony_ciOpName %fo "fo" 1191fd4e5da5Sopenharmony_ciOpMemberDecorate %S_0 0 Offset 0 1192fd4e5da5Sopenharmony_ciOpMemberDecorate %S_0 1 Offset 4 1193fd4e5da5Sopenharmony_ciOpMemberDecorate %U_t 0 Offset 0 1194fd4e5da5Sopenharmony_ciOpMemberDecorate %U_t 1 Offset 8 1195fd4e5da5Sopenharmony_ciOpMemberDecorate %U_t 2 Offset 16 1196fd4e5da5Sopenharmony_ciOpDecorate %U_t BufferBlock 1197fd4e5da5Sopenharmony_ciOpDecorate %_ DescriptorSet 0 1198fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 0 Offset 0 1199fd4e5da5Sopenharmony_ciOpDecorate %_Globals_ Block 1200fd4e5da5Sopenharmony_ciOpDecorate %__0 DescriptorSet 0 1201fd4e5da5Sopenharmony_ciOpDecorate %__0 Binding 0 1202fd4e5da5Sopenharmony_ciOpDecorate %fo Location 0 1203fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1204fd4e5da5Sopenharmony_ci%15 = OpTypeFunction %void 1205fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1206fd4e5da5Sopenharmony_ci%S = OpTypeStruct %float %float 1207fd4e5da5Sopenharmony_ci%_ptr_Function_S = OpTypePointer Function %S 1208fd4e5da5Sopenharmony_ci%S_0 = OpTypeStruct %float %float 1209fd4e5da5Sopenharmony_ci%U_t = OpTypeStruct %S_0 %S_0 %S_0 1210fd4e5da5Sopenharmony_ci%_ptr_Uniform_U_t = OpTypePointer Uniform %U_t 1211fd4e5da5Sopenharmony_ci%_ = OpVariable %_ptr_Uniform_U_t Uniform 1212fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1213fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 1214fd4e5da5Sopenharmony_ci%_ptr_Uniform_S_0 = OpTypePointer Uniform %S_0 1215fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 1216fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1217fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1218fd4e5da5Sopenharmony_ci%_Globals_ = OpTypeStruct %uint 1219fd4e5da5Sopenharmony_ci%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_ 1220fd4e5da5Sopenharmony_ci%__0 = OpVariable %_ptr_Uniform__Globals_ Uniform 1221fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 1222fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1223fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1224fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float 1225fd4e5da5Sopenharmony_ci%fo = OpVariable %_ptr_Output_float Output 1226fd4e5da5Sopenharmony_ci%main = OpFunction %void None %15 1227fd4e5da5Sopenharmony_ci%30 = OpLabel 1228fd4e5da5Sopenharmony_ci%ts1 = OpVariable %_ptr_Function_S Function 1229fd4e5da5Sopenharmony_ci%ts2 = OpVariable %_ptr_Function_S Function 1230fd4e5da5Sopenharmony_ci%ts3 = OpVariable %_ptr_Function_S Function 1231fd4e5da5Sopenharmony_ci%ts4 = OpVariable %_ptr_Function_S Function 1232fd4e5da5Sopenharmony_ci%31 = OpAccessChain %_ptr_Uniform_S_0 %_ %int_0 1233fd4e5da5Sopenharmony_ci%32 = OpLoad %S_0 %31 1234fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %float %32 0 1235fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Function_float %ts1 %int_0 1236fd4e5da5Sopenharmony_ciOpStore %34 %33 1237fd4e5da5Sopenharmony_ci%35 = OpCompositeExtract %float %32 1 1238fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_float %ts1 %int_1 1239fd4e5da5Sopenharmony_ciOpStore %36 %35 1240fd4e5da5Sopenharmony_ci%37 = OpAccessChain %_ptr_Uniform_S_0 %_ %int_1 1241fd4e5da5Sopenharmony_ci%38 = OpLoad %S_0 %37 1242fd4e5da5Sopenharmony_ci%39 = OpCompositeExtract %float %38 0 1243fd4e5da5Sopenharmony_ci%40 = OpAccessChain %_ptr_Function_float %ts2 %int_0 1244fd4e5da5Sopenharmony_ciOpStore %40 %39 1245fd4e5da5Sopenharmony_ci%41 = OpCompositeExtract %float %38 1 1246fd4e5da5Sopenharmony_ci%42 = OpAccessChain %_ptr_Function_float %ts2 %int_1 1247fd4e5da5Sopenharmony_ciOpStore %42 %41 1248fd4e5da5Sopenharmony_ci%43 = OpAccessChain %_ptr_Uniform_uint %__0 %int_0 1249fd4e5da5Sopenharmony_ci%44 = OpLoad %uint %43 1250fd4e5da5Sopenharmony_ci%45 = OpINotEqual %bool %44 %uint_0 1251fd4e5da5Sopenharmony_ciOpSelectionMerge %46 None 1252fd4e5da5Sopenharmony_ciOpBranchConditional %45 %47 %48 1253fd4e5da5Sopenharmony_ci%47 = OpLabel 1254fd4e5da5Sopenharmony_ci%49 = OpLoad %S %ts1 1255fd4e5da5Sopenharmony_ciOpStore %ts3 %49 1256fd4e5da5Sopenharmony_ciOpBranch %46 1257fd4e5da5Sopenharmony_ci%48 = OpLabel 1258fd4e5da5Sopenharmony_ci%50 = OpLoad %S %ts2 1259fd4e5da5Sopenharmony_ciOpStore %ts3 %50 1260fd4e5da5Sopenharmony_ciOpBranch %46 1261fd4e5da5Sopenharmony_ci%46 = OpLabel 1262fd4e5da5Sopenharmony_ci%51 = OpLoad %S %ts3 1263fd4e5da5Sopenharmony_ciOpStore %ts4 %51 1264fd4e5da5Sopenharmony_ci%52 = OpAccessChain %_ptr_Function_float %ts4 %int_1 1265fd4e5da5Sopenharmony_ci%53 = OpLoad %float %52 1266fd4e5da5Sopenharmony_ciOpStore %fo %53 1267fd4e5da5Sopenharmony_ciOpReturn 1268fd4e5da5Sopenharmony_ciOpFunctionEnd 1269fd4e5da5Sopenharmony_ci )"; 1270fd4e5da5Sopenharmony_ci 1271fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1272fd4e5da5Sopenharmony_ci} 1273fd4e5da5Sopenharmony_ci 1274fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ReplaceWholeLoadAndStore) { 1275fd4e5da5Sopenharmony_ci const std::string text = R"( 1276fd4e5da5Sopenharmony_ci; 1277fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 1278fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%\w+]] = OpTypeStruct [[uint]] [[uint]] 1279fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 1280fd4e5da5Sopenharmony_ci; CHECK: [[const:%\w+]] = OpConstant [[uint]] 0 1281fd4e5da5Sopenharmony_ci; CHECK: [[undef:%\w+]] = OpUndef [[uint]] 1282fd4e5da5Sopenharmony_ci; CHECK: [[var0:%\w+]] = OpVariable [[uint_ptr]] Function 1283fd4e5da5Sopenharmony_ci; CHECK: [[var1:%\w+]] = OpVariable [[uint_ptr]] Function 1284fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 1285fd4e5da5Sopenharmony_ci; CHECK: [[l0:%\w+]] = OpLoad [[uint]] [[var0]] 1286fd4e5da5Sopenharmony_ci; CHECK: [[c0:%\w+]] = OpCompositeConstruct [[struct1]] [[l0]] [[undef]] 1287fd4e5da5Sopenharmony_ci; CHECK: [[e0:%\w+]] = OpCompositeExtract [[uint]] [[c0]] 0 1288fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var1]] [[e0]] 1289fd4e5da5Sopenharmony_ci; CHECK: [[l1:%\w+]] = OpLoad [[uint]] [[var1]] 1290fd4e5da5Sopenharmony_ci; CHECK: [[c1:%\w+]] = OpCompositeConstruct [[struct1]] [[l1]] [[undef]] 1291fd4e5da5Sopenharmony_ci; CHECK: [[e1:%\w+]] = OpCompositeExtract [[uint]] [[c1]] 0 1292fd4e5da5Sopenharmony_ci; 1293fd4e5da5Sopenharmony_ciOpCapability Shader 1294fd4e5da5Sopenharmony_ciOpCapability Linkage 1295fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1296fd4e5da5Sopenharmony_ciOpName %func "replace_whole_load" 1297fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1298fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1299fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint %uint 1300fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 1301fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 1302fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1303fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 1304fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 1305fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 1306fd4e5da5Sopenharmony_ci%2 = OpLabel 1307fd4e5da5Sopenharmony_ci%var2 = OpVariable %struct1_ptr Function 1308fd4e5da5Sopenharmony_ci%var1 = OpVariable %struct1_ptr Function 1309fd4e5da5Sopenharmony_ci%load1 = OpLoad %struct1 %var1 1310fd4e5da5Sopenharmony_ciOpStore %var2 %load1 1311fd4e5da5Sopenharmony_ci%load2 = OpLoad %struct1 %var2 1312fd4e5da5Sopenharmony_ci%3 = OpCompositeExtract %uint %load2 0 1313fd4e5da5Sopenharmony_ciOpReturn 1314fd4e5da5Sopenharmony_ciOpFunctionEnd 1315fd4e5da5Sopenharmony_ci )"; 1316fd4e5da5Sopenharmony_ci 1317fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1318fd4e5da5Sopenharmony_ci} 1319fd4e5da5Sopenharmony_ci 1320fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ReplaceWholeLoadAndStore2) { 1321fd4e5da5Sopenharmony_ci // TODO: We can improve this case by ensuring that |var2| is processed first. 1322fd4e5da5Sopenharmony_ci const std::string text = R"( 1323fd4e5da5Sopenharmony_ci; 1324fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 1325fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%\w+]] = OpTypeStruct [[uint]] [[uint]] 1326fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 1327fd4e5da5Sopenharmony_ci; CHECK: [[const:%\w+]] = OpConstant [[uint]] 0 1328fd4e5da5Sopenharmony_ci; CHECK: [[undef:%\w+]] = OpUndef [[uint]] 1329fd4e5da5Sopenharmony_ci; CHECK: [[var1:%\w+]] = OpVariable [[uint_ptr]] Function 1330fd4e5da5Sopenharmony_ci; CHECK: [[var0a:%\w+]] = OpVariable [[uint_ptr]] Function 1331fd4e5da5Sopenharmony_ci; CHECK: [[var0b:%\w+]] = OpVariable [[uint_ptr]] Function 1332fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 1333fd4e5da5Sopenharmony_ci; CHECK: [[l0a:%\w+]] = OpLoad [[uint]] [[var0a]] 1334fd4e5da5Sopenharmony_ci; CHECK: [[l0b:%\w+]] = OpLoad [[uint]] [[var0b]] 1335fd4e5da5Sopenharmony_ci; CHECK: [[c0:%\w+]] = OpCompositeConstruct [[struct1]] [[l0b]] [[l0a]] 1336fd4e5da5Sopenharmony_ci; CHECK: [[e0:%\w+]] = OpCompositeExtract [[uint]] [[c0]] 0 1337fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var1]] [[e0]] 1338fd4e5da5Sopenharmony_ci; CHECK: [[l1:%\w+]] = OpLoad [[uint]] [[var1]] 1339fd4e5da5Sopenharmony_ci; CHECK: [[c1:%\w+]] = OpCompositeConstruct [[struct1]] [[l1]] [[undef]] 1340fd4e5da5Sopenharmony_ci; CHECK: [[e1:%\w+]] = OpCompositeExtract [[uint]] [[c1]] 0 1341fd4e5da5Sopenharmony_ci; 1342fd4e5da5Sopenharmony_ciOpCapability Shader 1343fd4e5da5Sopenharmony_ciOpCapability Linkage 1344fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1345fd4e5da5Sopenharmony_ciOpName %func "replace_whole_load" 1346fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1347fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1348fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint %uint 1349fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 1350fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 1351fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1352fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 1353fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 1354fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 1355fd4e5da5Sopenharmony_ci%2 = OpLabel 1356fd4e5da5Sopenharmony_ci%var1 = OpVariable %struct1_ptr Function 1357fd4e5da5Sopenharmony_ci%var2 = OpVariable %struct1_ptr Function 1358fd4e5da5Sopenharmony_ci%load1 = OpLoad %struct1 %var1 1359fd4e5da5Sopenharmony_ciOpStore %var2 %load1 1360fd4e5da5Sopenharmony_ci%load2 = OpLoad %struct1 %var2 1361fd4e5da5Sopenharmony_ci%3 = OpCompositeExtract %uint %load2 0 1362fd4e5da5Sopenharmony_ciOpReturn 1363fd4e5da5Sopenharmony_ciOpFunctionEnd 1364fd4e5da5Sopenharmony_ci )"; 1365fd4e5da5Sopenharmony_ci 1366fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1367fd4e5da5Sopenharmony_ci} 1368fd4e5da5Sopenharmony_ci 1369fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, CreateAmbiguousNullConstant1) { 1370fd4e5da5Sopenharmony_ci const std::string text = R"( 1371fd4e5da5Sopenharmony_ci; 1372fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 1373fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%\w+]] = OpTypeStruct [[uint]] [[struct_member:%\w+]] 1374fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 1375fd4e5da5Sopenharmony_ci; CHECK: [[const:%\w+]] = OpConstant [[uint]] 0 1376fd4e5da5Sopenharmony_ci; CHECK: [[undef:%\w+]] = OpUndef [[struct_member]] 1377fd4e5da5Sopenharmony_ci; CHECK: [[var0a:%\w+]] = OpVariable [[uint_ptr]] Function 1378fd4e5da5Sopenharmony_ci; CHECK: [[var1:%\w+]] = OpVariable [[uint_ptr]] Function 1379fd4e5da5Sopenharmony_ci; CHECK: [[var0b:%\w+]] = OpVariable [[uint_ptr]] Function 1380fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 1381fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var1]] 1382fd4e5da5Sopenharmony_ci; CHECK: [[l1:%\w+]] = OpLoad [[uint]] [[var1]] 1383fd4e5da5Sopenharmony_ci; CHECK: [[c1:%\w+]] = OpCompositeConstruct [[struct1]] [[l1]] [[undef]] 1384fd4e5da5Sopenharmony_ci; CHECK: [[e1:%\w+]] = OpCompositeExtract [[uint]] [[c1]] 0 1385fd4e5da5Sopenharmony_ci; 1386fd4e5da5Sopenharmony_ciOpCapability Shader 1387fd4e5da5Sopenharmony_ciOpCapability Linkage 1388fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1389fd4e5da5Sopenharmony_ciOpName %func "replace_whole_load" 1390fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1391fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1392fd4e5da5Sopenharmony_ci%struct2 = OpTypeStruct %uint 1393fd4e5da5Sopenharmony_ci%struct3 = OpTypeStruct %uint 1394fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint %struct2 1395fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 1396fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 1397fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1398fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 1399fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 1400fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 1401fd4e5da5Sopenharmony_ci%2 = OpLabel 1402fd4e5da5Sopenharmony_ci%var1 = OpVariable %struct1_ptr Function 1403fd4e5da5Sopenharmony_ci%var2 = OpVariable %struct1_ptr Function 1404fd4e5da5Sopenharmony_ci%load1 = OpLoad %struct1 %var1 1405fd4e5da5Sopenharmony_ciOpStore %var2 %load1 1406fd4e5da5Sopenharmony_ci%load2 = OpLoad %struct1 %var2 1407fd4e5da5Sopenharmony_ci%3 = OpCompositeExtract %uint %load2 0 1408fd4e5da5Sopenharmony_ciOpReturn 1409fd4e5da5Sopenharmony_ciOpFunctionEnd 1410fd4e5da5Sopenharmony_ci )"; 1411fd4e5da5Sopenharmony_ci 1412fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1413fd4e5da5Sopenharmony_ci} 1414fd4e5da5Sopenharmony_ci 1415fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, SpecConstantArray) { 1416fd4e5da5Sopenharmony_ci const std::string text = R"( 1417fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 1418fd4e5da5Sopenharmony_ci; CHECK: [[spec_const:%\w+]] = OpSpecConstant [[int]] 4 1419fd4e5da5Sopenharmony_ci; CHECK: [[spec_op:%\w+]] = OpSpecConstantOp [[int]] IAdd [[spec_const]] [[spec_const]] 1420fd4e5da5Sopenharmony_ci; CHECK: [[array1:%\w+]] = OpTypeArray [[int]] [[spec_const]] 1421fd4e5da5Sopenharmony_ci; CHECK: [[array2:%\w+]] = OpTypeArray [[int]] [[spec_op]] 1422fd4e5da5Sopenharmony_ci; CHECK: [[ptr_array1:%\w+]] = OpTypePointer Function [[array1]] 1423fd4e5da5Sopenharmony_ci; CHECK: [[ptr_array2:%\w+]] = OpTypePointer Function [[array2]] 1424fd4e5da5Sopenharmony_ci; CHECK: OpLabel 1425fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[ptr_array1]] Function 1426fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable [[ptr_array2]] Function 1427fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable 1428fd4e5da5Sopenharmony_ciOpCapability Shader 1429fd4e5da5Sopenharmony_ciOpCapability Linkage 1430fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1431fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1432fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1433fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1434fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %int 4 1435fd4e5da5Sopenharmony_ci%spec_op = OpSpecConstantOp %int IAdd %spec_const %spec_const 1436fd4e5da5Sopenharmony_ci%array_1 = OpTypeArray %int %spec_const 1437fd4e5da5Sopenharmony_ci%array_2 = OpTypeArray %int %spec_op 1438fd4e5da5Sopenharmony_ci%ptr_array_1_Function = OpTypePointer Function %array_1 1439fd4e5da5Sopenharmony_ci%ptr_array_2_Function = OpTypePointer Function %array_2 1440fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1441fd4e5da5Sopenharmony_ci%1 = OpLabel 1442fd4e5da5Sopenharmony_ci%var_1 = OpVariable %ptr_array_1_Function Function 1443fd4e5da5Sopenharmony_ci%var_2 = OpVariable %ptr_array_2_Function Function 1444fd4e5da5Sopenharmony_ciOpReturn 1445fd4e5da5Sopenharmony_ciOpFunctionEnd 1446fd4e5da5Sopenharmony_ci)"; 1447fd4e5da5Sopenharmony_ci 1448fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1449fd4e5da5Sopenharmony_ci} 1450fd4e5da5Sopenharmony_ci 1451fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, CreateAmbiguousNullConstant2) { 1452fd4e5da5Sopenharmony_ci const std::string text = R"( 1453fd4e5da5Sopenharmony_ci; 1454fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 1455fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%\w+]] = OpTypeStruct [[uint]] [[struct_member:%\w+]] 1456fd4e5da5Sopenharmony_ci; CHECK: [[uint_ptr:%\w+]] = OpTypePointer Function [[uint]] 1457fd4e5da5Sopenharmony_ci; CHECK: [[const:%\w+]] = OpConstant [[uint]] 0 1458fd4e5da5Sopenharmony_ci; CHECK: [[undef:%\w+]] = OpUndef [[struct_member]] 1459fd4e5da5Sopenharmony_ci; CHECK: [[var0a:%\w+]] = OpVariable [[uint_ptr]] Function 1460fd4e5da5Sopenharmony_ci; CHECK: [[var1:%\w+]] = OpVariable [[uint_ptr]] Function 1461fd4e5da5Sopenharmony_ci; CHECK: [[var0b:%\w+]] = OpVariable [[uint_ptr]] Function 1462fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var1]] 1463fd4e5da5Sopenharmony_ci; CHECK: [[l1:%\w+]] = OpLoad [[uint]] [[var1]] 1464fd4e5da5Sopenharmony_ci; CHECK: [[c1:%\w+]] = OpCompositeConstruct [[struct1]] [[l1]] [[undef]] 1465fd4e5da5Sopenharmony_ci; CHECK: [[e1:%\w+]] = OpCompositeExtract [[uint]] [[c1]] 0 1466fd4e5da5Sopenharmony_ci; 1467fd4e5da5Sopenharmony_ciOpCapability Shader 1468fd4e5da5Sopenharmony_ciOpCapability Linkage 1469fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1470fd4e5da5Sopenharmony_ciOpName %func "replace_whole_load" 1471fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1472fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1473fd4e5da5Sopenharmony_ci%struct3 = OpTypeStruct %uint 1474fd4e5da5Sopenharmony_ci%struct2 = OpTypeStruct %uint 1475fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %uint %struct2 1476fd4e5da5Sopenharmony_ci%uint_ptr = OpTypePointer Function %uint 1477fd4e5da5Sopenharmony_ci%struct1_ptr = OpTypePointer Function %struct1 1478fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1479fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 1480fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 1481fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 1482fd4e5da5Sopenharmony_ci%2 = OpLabel 1483fd4e5da5Sopenharmony_ci%var1 = OpVariable %struct1_ptr Function 1484fd4e5da5Sopenharmony_ci%var2 = OpVariable %struct1_ptr Function 1485fd4e5da5Sopenharmony_ci%load1 = OpLoad %struct1 %var1 1486fd4e5da5Sopenharmony_ciOpStore %var2 %load1 1487fd4e5da5Sopenharmony_ci%load2 = OpLoad %struct1 %var2 1488fd4e5da5Sopenharmony_ci%3 = OpCompositeExtract %uint %load2 0 1489fd4e5da5Sopenharmony_ciOpReturn 1490fd4e5da5Sopenharmony_ciOpFunctionEnd 1491fd4e5da5Sopenharmony_ci )"; 1492fd4e5da5Sopenharmony_ci 1493fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1494fd4e5da5Sopenharmony_ci} 1495fd4e5da5Sopenharmony_ci 1496fd4e5da5Sopenharmony_ci// Test that a struct of size 4 is not replaced when there is a limit of 2. 1497fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, TestLimit) { 1498fd4e5da5Sopenharmony_ci const std::string text = R"( 1499fd4e5da5Sopenharmony_ciOpCapability Shader 1500fd4e5da5Sopenharmony_ciOpCapability Linkage 1501fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1502fd4e5da5Sopenharmony_ciOpName %6 "simple_struct" 1503fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 1504fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 1505fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 %2 %2 1506fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 1507fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %2 1508fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 1509fd4e5da5Sopenharmony_ci%7 = OpConstantNull %3 1510fd4e5da5Sopenharmony_ci%8 = OpConstant %2 0 1511fd4e5da5Sopenharmony_ci%9 = OpConstant %2 1 1512fd4e5da5Sopenharmony_ci%10 = OpConstant %2 2 1513fd4e5da5Sopenharmony_ci%11 = OpConstant %2 3 1514fd4e5da5Sopenharmony_ci%12 = OpFunction %2 None %6 1515fd4e5da5Sopenharmony_ci%13 = OpLabel 1516fd4e5da5Sopenharmony_ci%14 = OpVariable %4 Function %7 1517fd4e5da5Sopenharmony_ci%15 = OpInBoundsAccessChain %5 %14 %8 1518fd4e5da5Sopenharmony_ci%16 = OpLoad %2 %15 1519fd4e5da5Sopenharmony_ci%17 = OpAccessChain %5 %14 %10 1520fd4e5da5Sopenharmony_ci%18 = OpLoad %2 %17 1521fd4e5da5Sopenharmony_ci%19 = OpIAdd %2 %16 %18 1522fd4e5da5Sopenharmony_ciOpReturnValue %19 1523fd4e5da5Sopenharmony_ciOpFunctionEnd 1524fd4e5da5Sopenharmony_ci )"; 1525fd4e5da5Sopenharmony_ci 1526fd4e5da5Sopenharmony_ci auto result = 1527fd4e5da5Sopenharmony_ci SinglePassRunAndDisassemble<ScalarReplacementPass>(text, true, false, 2); 1528fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 1529fd4e5da5Sopenharmony_ci} 1530fd4e5da5Sopenharmony_ci 1531fd4e5da5Sopenharmony_ci// Test that a struct of size 4 is replaced when there is a limit of 0 (no 1532fd4e5da5Sopenharmony_ci// limit). This is the same spir-v as a test above, so we do not check that it 1533fd4e5da5Sopenharmony_ci// is correctly transformed. We leave that to the test above. 1534fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, TestUnimited) { 1535fd4e5da5Sopenharmony_ci const std::string text = R"( 1536fd4e5da5Sopenharmony_ciOpCapability Shader 1537fd4e5da5Sopenharmony_ciOpCapability Linkage 1538fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1539fd4e5da5Sopenharmony_ciOpName %6 "simple_struct" 1540fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 1541fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 1542fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 %2 %2 1543fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 1544fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %2 1545fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 1546fd4e5da5Sopenharmony_ci%7 = OpConstantNull %3 1547fd4e5da5Sopenharmony_ci%8 = OpConstant %2 0 1548fd4e5da5Sopenharmony_ci%9 = OpConstant %2 1 1549fd4e5da5Sopenharmony_ci%10 = OpConstant %2 2 1550fd4e5da5Sopenharmony_ci%11 = OpConstant %2 3 1551fd4e5da5Sopenharmony_ci%12 = OpFunction %2 None %6 1552fd4e5da5Sopenharmony_ci%13 = OpLabel 1553fd4e5da5Sopenharmony_ci%14 = OpVariable %4 Function %7 1554fd4e5da5Sopenharmony_ci%15 = OpInBoundsAccessChain %5 %14 %8 1555fd4e5da5Sopenharmony_ci%16 = OpLoad %2 %15 1556fd4e5da5Sopenharmony_ci%17 = OpAccessChain %5 %14 %10 1557fd4e5da5Sopenharmony_ci%18 = OpLoad %2 %17 1558fd4e5da5Sopenharmony_ci%19 = OpIAdd %2 %16 %18 1559fd4e5da5Sopenharmony_ciOpReturnValue %19 1560fd4e5da5Sopenharmony_ciOpFunctionEnd 1561fd4e5da5Sopenharmony_ci )"; 1562fd4e5da5Sopenharmony_ci 1563fd4e5da5Sopenharmony_ci auto result = 1564fd4e5da5Sopenharmony_ci SinglePassRunAndDisassemble<ScalarReplacementPass>(text, true, false, 0); 1565fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result)); 1566fd4e5da5Sopenharmony_ci} 1567fd4e5da5Sopenharmony_ci 1568fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, AmbigousPointer) { 1569fd4e5da5Sopenharmony_ci const std::string text = R"( 1570fd4e5da5Sopenharmony_ci; CHECK: [[s1:%\w+]] = OpTypeStruct %uint 1571fd4e5da5Sopenharmony_ci; CHECK: [[s2:%\w+]] = OpTypeStruct %uint 1572fd4e5da5Sopenharmony_ci; CHECK: [[s3:%\w+]] = OpTypeStruct [[s2]] 1573fd4e5da5Sopenharmony_ci; CHECK: [[s3_const:%\w+]] = OpConstantComposite [[s3]] 1574fd4e5da5Sopenharmony_ci; CHECK: [[s2_ptr:%\w+]] = OpTypePointer Function [[s2]] 1575fd4e5da5Sopenharmony_ci; CHECK: OpCompositeExtract [[s2]] [[s3_const]] 1576fd4e5da5Sopenharmony_ci 1577fd4e5da5Sopenharmony_ci OpCapability Shader 1578fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1579fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1580fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 1581fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1582fd4e5da5Sopenharmony_ci OpSource ESSL 310 1583fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1584fd4e5da5Sopenharmony_ci %5 = OpTypeFunction %void 1585fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 1586fd4e5da5Sopenharmony_ci %_struct_7 = OpTypeStruct %uint 1587fd4e5da5Sopenharmony_ci %_struct_8 = OpTypeStruct %uint 1588fd4e5da5Sopenharmony_ci %_struct_9 = OpTypeStruct %_struct_8 1589fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 1590fd4e5da5Sopenharmony_ci %11 = OpConstantComposite %_struct_8 %uint_1 1591fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %_struct_9 %11 1592fd4e5da5Sopenharmony_ci%_ptr_Function__struct_9 = OpTypePointer Function %_struct_9 1593fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7 1594fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %5 1595fd4e5da5Sopenharmony_ci %15 = OpLabel 1596fd4e5da5Sopenharmony_ci %var = OpVariable %_ptr_Function__struct_9 Function 1597fd4e5da5Sopenharmony_ci OpStore %var %12 1598fd4e5da5Sopenharmony_ci %ld = OpLoad %_struct_9 %var 1599fd4e5da5Sopenharmony_ci %ex = OpCompositeExtract %_struct_8 %ld 0 1600fd4e5da5Sopenharmony_ci OpReturn 1601fd4e5da5Sopenharmony_ci OpFunctionEnd 1602fd4e5da5Sopenharmony_ci )"; 1603fd4e5da5Sopenharmony_ci 1604fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1605fd4e5da5Sopenharmony_ci} 1606fd4e5da5Sopenharmony_ci 1607fd4e5da5Sopenharmony_ci// Test that scalar replacement does not crash when there is an OpAccessChain 1608fd4e5da5Sopenharmony_ci// with no index. If we choose to handle this case in the future, then the 1609fd4e5da5Sopenharmony_ci// result can change. 1610fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, TestAccessChainWithNoIndexes) { 1611fd4e5da5Sopenharmony_ci const std::string text = R"( 1612fd4e5da5Sopenharmony_ci OpCapability Shader 1613fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1614fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %1 "main" 1615fd4e5da5Sopenharmony_ci OpExecutionMode %1 OriginLowerLeft 1616fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1617fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %void 1618fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1619fd4e5da5Sopenharmony_ci %_struct_5 = OpTypeStruct %float 1620fd4e5da5Sopenharmony_ci%_ptr_Function__struct_5 = OpTypePointer Function %_struct_5 1621fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %3 1622fd4e5da5Sopenharmony_ci %7 = OpLabel 1623fd4e5da5Sopenharmony_ci %8 = OpVariable %_ptr_Function__struct_5 Function 1624fd4e5da5Sopenharmony_ci %9 = OpAccessChain %_ptr_Function__struct_5 %8 1625fd4e5da5Sopenharmony_ci OpReturn 1626fd4e5da5Sopenharmony_ci OpFunctionEnd 1627fd4e5da5Sopenharmony_ci )"; 1628fd4e5da5Sopenharmony_ci 1629fd4e5da5Sopenharmony_ci auto result = 1630fd4e5da5Sopenharmony_ci SinglePassRunAndDisassemble<ScalarReplacementPass>(text, true, false); 1631fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 1632fd4e5da5Sopenharmony_ci} 1633fd4e5da5Sopenharmony_ci 1634fd4e5da5Sopenharmony_ci// Test that id overflow is handled gracefully. 1635fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, IdBoundOverflow1) { 1636fd4e5da5Sopenharmony_ci const std::string text = R"( 1637fd4e5da5Sopenharmony_ciOpCapability ImageQuery 1638fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1639fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %4 "main" 1640fd4e5da5Sopenharmony_ciOpExecutionMode %4 OriginUpperLeft 1641fd4e5da5Sopenharmony_ciOpDecorate %4194302 DescriptorSet 1073495039 1642fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 1643fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %2 1644fd4e5da5Sopenharmony_ci%6 = OpTypeFloat 32 1645fd4e5da5Sopenharmony_ci%7 = OpTypeStruct %6 %6 1646fd4e5da5Sopenharmony_ci%557056 = OpTypeStruct %7 1647fd4e5da5Sopenharmony_ci%9 = OpTypePointer Function %7 1648fd4e5da5Sopenharmony_ci%18 = OpTypeFunction %7 %9 1649fd4e5da5Sopenharmony_ci%4 = OpFunction %2 Pure|Const %3 1650fd4e5da5Sopenharmony_ci%1836763 = OpLabel 1651fd4e5da5Sopenharmony_ci%4194302 = OpVariable %9 Function 1652fd4e5da5Sopenharmony_ci%10 = OpVariable %9 Function 1653fd4e5da5Sopenharmony_ciOpKill 1654fd4e5da5Sopenharmony_ci%4194301 = OpLabel 1655fd4e5da5Sopenharmony_ci%524296 = OpLoad %7 %4194302 1656fd4e5da5Sopenharmony_ciOpKill 1657fd4e5da5Sopenharmony_ciOpFunctionEnd 1658fd4e5da5Sopenharmony_ci )"; 1659fd4e5da5Sopenharmony_ci 1660fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1661fd4e5da5Sopenharmony_ci 1662fd4e5da5Sopenharmony_ci std::vector<Message> messages = { 1663fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}, 1664fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}}; 1665fd4e5da5Sopenharmony_ci SetMessageConsumer(GetTestMessageConsumer(messages)); 1666fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<ScalarReplacementPass>(text, true, false); 1667fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::Failure, std::get<1>(result)); 1668fd4e5da5Sopenharmony_ci} 1669fd4e5da5Sopenharmony_ci 1670fd4e5da5Sopenharmony_ci// Test that id overflow is handled gracefully. 1671fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, IdBoundOverflow2) { 1672fd4e5da5Sopenharmony_ci const std::string text = R"( 1673fd4e5da5Sopenharmony_ciOpCapability Shader 1674fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1675fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %4 "main" %17 1676fd4e5da5Sopenharmony_ciOpExecutionMode %4 OriginUpperLeft 1677fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 1678fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %2 1679fd4e5da5Sopenharmony_ci%6 = OpTypeFloat 32 1680fd4e5da5Sopenharmony_ci%7 = OpTypeVector %6 4 1681fd4e5da5Sopenharmony_ci%8 = OpTypeStruct %7 1682fd4e5da5Sopenharmony_ci%9 = OpTypePointer Function %8 1683fd4e5da5Sopenharmony_ci%16 = OpTypePointer Output %7 1684fd4e5da5Sopenharmony_ci%21 = OpTypeInt 32 1 1685fd4e5da5Sopenharmony_ci%22 = OpConstant %21 0 1686fd4e5da5Sopenharmony_ci%23 = OpTypePointer Function %7 1687fd4e5da5Sopenharmony_ci%17 = OpVariable %16 Output 1688fd4e5da5Sopenharmony_ci%4 = OpFunction %2 None %3 1689fd4e5da5Sopenharmony_ci%5 = OpLabel 1690fd4e5da5Sopenharmony_ci%4194300 = OpVariable %23 Function 1691fd4e5da5Sopenharmony_ci%10 = OpVariable %9 Function 1692fd4e5da5Sopenharmony_ci%4194301 = OpAccessChain %23 %10 %22 1693fd4e5da5Sopenharmony_ci%4194302 = OpLoad %7 %4194301 1694fd4e5da5Sopenharmony_ciOpStore %4194300 %4194302 1695fd4e5da5Sopenharmony_ci%15 = OpLoad %7 %4194300 1696fd4e5da5Sopenharmony_ciOpStore %17 %15 1697fd4e5da5Sopenharmony_ciOpReturn 1698fd4e5da5Sopenharmony_ciOpFunctionEnd 1699fd4e5da5Sopenharmony_ci )"; 1700fd4e5da5Sopenharmony_ci 1701fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1702fd4e5da5Sopenharmony_ci 1703fd4e5da5Sopenharmony_ci std::vector<Message> messages = { 1704fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}}; 1705fd4e5da5Sopenharmony_ci SetMessageConsumer(GetTestMessageConsumer(messages)); 1706fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<ScalarReplacementPass>(text, true, false); 1707fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::Failure, std::get<1>(result)); 1708fd4e5da5Sopenharmony_ci} 1709fd4e5da5Sopenharmony_ci 1710fd4e5da5Sopenharmony_ci// Test that id overflow is handled gracefully. 1711fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, IdBoundOverflow3) { 1712fd4e5da5Sopenharmony_ci const std::string text = R"( 1713fd4e5da5Sopenharmony_ciOpCapability InterpolationFunction 1714fd4e5da5Sopenharmony_ciOpExtension "z" 1715fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1716fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %4 "main" 1717fd4e5da5Sopenharmony_ciOpExecutionMode %4 OriginUpperLeft 1718fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 1719fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %2 1720fd4e5da5Sopenharmony_ci%6 = OpTypeFloat 32 1721fd4e5da5Sopenharmony_ci%7 = OpTypeStruct %6 %6 1722fd4e5da5Sopenharmony_ci%9 = OpTypePointer Function %7 1723fd4e5da5Sopenharmony_ci%18 = OpTypeFunction %7 %9 1724fd4e5da5Sopenharmony_ci%21 = OpTypeInt 32 0 1725fd4e5da5Sopenharmony_ci%22 = OpConstant %21 4293000676 1726fd4e5da5Sopenharmony_ci%4194302 = OpConstantNull %6 1727fd4e5da5Sopenharmony_ci%4 = OpFunction %2 Inline|Pure %3 1728fd4e5da5Sopenharmony_ci%786464 = OpLabel 1729fd4e5da5Sopenharmony_ci%4194298 = OpVariable %9 Function 1730fd4e5da5Sopenharmony_ci%10 = OpVariable %9 Function 1731fd4e5da5Sopenharmony_ci%4194299 = OpUDiv %21 %22 %22 1732fd4e5da5Sopenharmony_ci%4194300 = OpLoad %7 %10 1733fd4e5da5Sopenharmony_ci%50959 = OpLoad %7 %4194298 1734fd4e5da5Sopenharmony_ciOpKill 1735fd4e5da5Sopenharmony_ciOpFunctionEnd 1736fd4e5da5Sopenharmony_ci%1 = OpFunction %7 None %18 1737fd4e5da5Sopenharmony_ci%19 = OpFunctionParameter %9 1738fd4e5da5Sopenharmony_ci%147667 = OpLabel 1739fd4e5da5Sopenharmony_ci%2044391 = OpUDiv %21 %22 %22 1740fd4e5da5Sopenharmony_ci%25 = OpLoad %7 %19 1741fd4e5da5Sopenharmony_ciOpReturnValue %25 1742fd4e5da5Sopenharmony_ciOpFunctionEnd 1743fd4e5da5Sopenharmony_ci%4194295 = OpFunction %2 None %3 1744fd4e5da5Sopenharmony_ci%4194296 = OpLabel 1745fd4e5da5Sopenharmony_ciOpKill 1746fd4e5da5Sopenharmony_ciOpFunctionEnd 1747fd4e5da5Sopenharmony_ci )"; 1748fd4e5da5Sopenharmony_ci 1749fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1750fd4e5da5Sopenharmony_ci 1751fd4e5da5Sopenharmony_ci std::vector<Message> messages = { 1752fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}, 1753fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}, 1754fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}, 1755fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}, 1756fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}, 1757fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}, 1758fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}, 1759fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}, 1760fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}}; 1761fd4e5da5Sopenharmony_ci SetMessageConsumer(GetTestMessageConsumer(messages)); 1762fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<ScalarReplacementPass>(text, true, false); 1763fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::Failure, std::get<1>(result)); 1764fd4e5da5Sopenharmony_ci} 1765fd4e5da5Sopenharmony_ci 1766fd4e5da5Sopenharmony_ci// Test that replacements for OpAccessChain do not go out of bounds. 1767fd4e5da5Sopenharmony_ci// https://github.com/KhronosGroup/SPIRV-Tools/issues/2609. 1768fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, OutOfBoundOpAccessChain) { 1769fd4e5da5Sopenharmony_ci const std::string text = R"( 1770fd4e5da5Sopenharmony_ci OpCapability Shader 1771fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1772fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1773fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %_GLF_color 1774fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 1775fd4e5da5Sopenharmony_ci OpSource ESSL 310 1776fd4e5da5Sopenharmony_ci OpName %main "main" 1777fd4e5da5Sopenharmony_ci OpName %a "a" 1778fd4e5da5Sopenharmony_ci OpName %_GLF_color "_GLF_color" 1779fd4e5da5Sopenharmony_ci OpDecorate %_GLF_color Location 0 1780fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1781fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %void 1782fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 1783fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 1784fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 1785fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1786fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 1787fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 1788fd4e5da5Sopenharmony_ci%_arr_float_uint_1 = OpTypeArray %float %uint_1 1789fd4e5da5Sopenharmony_ci%_ptr_Function__arr_float_uint_1 = OpTypePointer Function %_arr_float_uint_1 1790fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 1791fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float 1792fd4e5da5Sopenharmony_ci %_GLF_color = OpVariable %_ptr_Output_float Output 1793fd4e5da5Sopenharmony_ci %main = OpFunction %void None %3 1794fd4e5da5Sopenharmony_ci %5 = OpLabel 1795fd4e5da5Sopenharmony_ci %a = OpVariable %_ptr_Function__arr_float_uint_1 Function 1796fd4e5da5Sopenharmony_ci %21 = OpAccessChain %_ptr_Function_float %a %int_1 1797fd4e5da5Sopenharmony_ci %22 = OpLoad %float %21 1798fd4e5da5Sopenharmony_ci OpStore %_GLF_color %22 1799fd4e5da5Sopenharmony_ci OpReturn 1800fd4e5da5Sopenharmony_ci OpFunctionEnd 1801fd4e5da5Sopenharmony_ci )"; 1802fd4e5da5Sopenharmony_ci 1803fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1804fd4e5da5Sopenharmony_ci 1805fd4e5da5Sopenharmony_ci auto result = 1806fd4e5da5Sopenharmony_ci SinglePassRunAndDisassemble<ScalarReplacementPass>(text, true, false); 1807fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 1808fd4e5da5Sopenharmony_ci} 1809fd4e5da5Sopenharmony_ci 1810fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, CharIndex) { 1811fd4e5da5Sopenharmony_ci const std::string text = R"( 1812fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0 1813fd4e5da5Sopenharmony_ci; CHECK: [[ptr:%\w+]] = OpTypePointer Function [[int]] 1814fd4e5da5Sopenharmony_ci; CHECK: OpVariable [[ptr]] Function 1815fd4e5da5Sopenharmony_ciOpCapability Shader 1816fd4e5da5Sopenharmony_ciOpCapability Int8 1817fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1818fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 1819fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 1820fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1821fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1822fd4e5da5Sopenharmony_ci%int_1024 = OpConstant %int 1024 1823fd4e5da5Sopenharmony_ci%char = OpTypeInt 8 0 1824fd4e5da5Sopenharmony_ci%char_1 = OpConstant %char 1 1825fd4e5da5Sopenharmony_ci%array = OpTypeArray %int %int_1024 1826fd4e5da5Sopenharmony_ci%ptr_func_array = OpTypePointer Function %array 1827fd4e5da5Sopenharmony_ci%ptr_func_int = OpTypePointer Function %int 1828fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1829fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1830fd4e5da5Sopenharmony_ci%entry = OpLabel 1831fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_func_array Function 1832fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_func_int %var %char_1 1833fd4e5da5Sopenharmony_ciOpStore %gep %int_1024 1834fd4e5da5Sopenharmony_ciOpReturn 1835fd4e5da5Sopenharmony_ciOpFunctionEnd 1836fd4e5da5Sopenharmony_ci)"; 1837fd4e5da5Sopenharmony_ci 1838fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true, 0); 1839fd4e5da5Sopenharmony_ci} 1840fd4e5da5Sopenharmony_ci 1841fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, OutOfBoundsOpAccessChainNegative) { 1842fd4e5da5Sopenharmony_ci const std::string text = R"( 1843fd4e5da5Sopenharmony_ciOpCapability Shader 1844fd4e5da5Sopenharmony_ciOpCapability Int8 1845fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1846fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 1847fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 1848fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1849fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1850fd4e5da5Sopenharmony_ci%int_1024 = OpConstant %int 1024 1851fd4e5da5Sopenharmony_ci%char = OpTypeInt 8 1 1852fd4e5da5Sopenharmony_ci%char_n1 = OpConstant %char -1 1853fd4e5da5Sopenharmony_ci%array = OpTypeArray %int %int_1024 1854fd4e5da5Sopenharmony_ci%ptr_func_array = OpTypePointer Function %array 1855fd4e5da5Sopenharmony_ci%ptr_func_int = OpTypePointer Function %int 1856fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1857fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1858fd4e5da5Sopenharmony_ci%entry = OpLabel 1859fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_func_array Function 1860fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_func_int %var %char_n1 1861fd4e5da5Sopenharmony_ciOpStore %gep %int_1024 1862fd4e5da5Sopenharmony_ciOpReturn 1863fd4e5da5Sopenharmony_ciOpFunctionEnd 1864fd4e5da5Sopenharmony_ci)"; 1865fd4e5da5Sopenharmony_ci 1866fd4e5da5Sopenharmony_ci auto result = 1867fd4e5da5Sopenharmony_ci SinglePassRunAndDisassemble<ScalarReplacementPass>(text, true, true, 0); 1868fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 1869fd4e5da5Sopenharmony_ci} 1870fd4e5da5Sopenharmony_ci 1871fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, RelaxedPrecisionMemberDecoration) { 1872fd4e5da5Sopenharmony_ci const std::string text = R"( 1873fd4e5da5Sopenharmony_ci; CHECK: OpDecorate {{%\w+}} RelaxedPrecision 1874fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[new_var:%\w+]] RelaxedPrecision 1875fd4e5da5Sopenharmony_ci; CHECK: [[new_var]] = OpVariable %_ptr_Function_v3float Function 1876fd4e5da5Sopenharmony_ci; CHECK: OpLoad %v3float [[new_var]] 1877fd4e5da5Sopenharmony_ci OpCapability Shader 1878fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1879fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "Draw2DTexCol_VS" %2 %3 1880fd4e5da5Sopenharmony_ci OpSource HLSL 600 1881fd4e5da5Sopenharmony_ci OpDecorate %2 Location 0 1882fd4e5da5Sopenharmony_ci OpDecorate %3 Location 1 1883fd4e5da5Sopenharmony_ci OpDecorate %3 RelaxedPrecision 1884fd4e5da5Sopenharmony_ci OpMemberDecorate %_struct_4 1 RelaxedPrecision 1885fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1886fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 1887fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 1888fd4e5da5Sopenharmony_ci %v3float = OpTypeVector %float 3 1889fd4e5da5Sopenharmony_ci%_ptr_Input_v3float = OpTypePointer Input %v3float 1890fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1891fd4e5da5Sopenharmony_ci %11 = OpTypeFunction %void 1892fd4e5da5Sopenharmony_ci %_struct_4 = OpTypeStruct %v3float %v3float 1893fd4e5da5Sopenharmony_ci%_ptr_Function__struct_4 = OpTypePointer Function %_struct_4 1894fd4e5da5Sopenharmony_ci%_ptr_Function_v3float = OpTypePointer Function %v3float 1895fd4e5da5Sopenharmony_ci %2 = OpVariable %_ptr_Input_v3float Input 1896fd4e5da5Sopenharmony_ci %3 = OpVariable %_ptr_Input_v3float Input 1897fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %11 1898fd4e5da5Sopenharmony_ci %14 = OpLabel 1899fd4e5da5Sopenharmony_ci %15 = OpVariable %_ptr_Function__struct_4 Function 1900fd4e5da5Sopenharmony_ci %16 = OpLoad %v3float %2 1901fd4e5da5Sopenharmony_ci %17 = OpLoad %v3float %3 1902fd4e5da5Sopenharmony_ci %18 = OpCompositeConstruct %_struct_4 %16 %17 1903fd4e5da5Sopenharmony_ci OpStore %15 %18 1904fd4e5da5Sopenharmony_ci %19 = OpAccessChain %_ptr_Function_v3float %15 %int_1 1905fd4e5da5Sopenharmony_ci %20 = OpLoad %v3float %19 1906fd4e5da5Sopenharmony_ci OpReturn 1907fd4e5da5Sopenharmony_ci OpFunctionEnd 1908fd4e5da5Sopenharmony_ci)"; 1909fd4e5da5Sopenharmony_ci 1910fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1911fd4e5da5Sopenharmony_ci} 1912fd4e5da5Sopenharmony_ci 1913fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DebugDeclare) { 1914fd4e5da5Sopenharmony_ci const std::string text = R"( 1915fd4e5da5Sopenharmony_ciOpCapability Shader 1916fd4e5da5Sopenharmony_ciOpCapability Linkage 1917fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 1918fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1919fd4e5da5Sopenharmony_ci%test = OpString "test" 1920fd4e5da5Sopenharmony_ciOpName %6 "simple_struct" 1921fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 1922fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 1923fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %2 32 1924fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 %2 %2 1925fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 1926fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %2 1927fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 1928fd4e5da5Sopenharmony_ci%7 = OpConstantNull %3 1929fd4e5da5Sopenharmony_ci%8 = OpConstant %2 0 1930fd4e5da5Sopenharmony_ci%9 = OpConstant %2 1 1931fd4e5da5Sopenharmony_ci%10 = OpConstant %2 2 1932fd4e5da5Sopenharmony_ci%11 = OpConstant %2 3 1933fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %1 %ext DebugExpression 1934fd4e5da5Sopenharmony_ci%src = OpExtInst %1 %ext DebugSource %test 1935fd4e5da5Sopenharmony_ci%cu = OpExtInst %1 %ext DebugCompilationUnit 1 4 %src HLSL 1936fd4e5da5Sopenharmony_ci%dbg_tf = OpExtInst %1 %ext DebugTypeBasic %test %uint_32 Float 1937fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %1 %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %1 1938fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %1 %ext DebugFunction %test %main_ty %src 0 0 %cu %test FlagIsProtected|FlagIsPrivate 0 %12 1939fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %1 %ext DebugLocalVariable %test %dbg_tf %src 0 0 %dbg_main FlagIsLocal 1940fd4e5da5Sopenharmony_ci%12 = OpFunction %2 None %6 1941fd4e5da5Sopenharmony_ci%13 = OpLabel 1942fd4e5da5Sopenharmony_ci%scope = OpExtInst %1 %ext DebugScope %dbg_main 1943fd4e5da5Sopenharmony_ci%14 = OpVariable %4 Function %7 1944fd4e5da5Sopenharmony_ci 1945fd4e5da5Sopenharmony_ci; CHECK: [[deref:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugOperation Deref 1946fd4e5da5Sopenharmony_ci; CHECK: [[dbg_local_var:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable 1947fd4e5da5Sopenharmony_ci; CHECK: [[deref_expr:%\w+]] = OpExtInst %void [[ext]] DebugExpression [[deref]] 1948fd4e5da5Sopenharmony_ci; CHECK: [[repl3:%\w+]] = OpVariable %_ptr_Function_uint Function 1949fd4e5da5Sopenharmony_ci; CHECK: [[repl2:%\w+]] = OpVariable %_ptr_Function_uint Function 1950fd4e5da5Sopenharmony_ci; CHECK: [[repl1:%\w+]] = OpVariable %_ptr_Function_uint Function 1951fd4e5da5Sopenharmony_ci; CHECK: [[repl0:%\w+]] = OpVariable %_ptr_Function_uint Function 1952fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl3]] [[deref_expr]] %int_3 1953fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl2]] [[deref_expr]] %int_2 1954fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl1]] [[deref_expr]] %int_1 1955fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl0]] [[deref_expr]] %int_0 1956fd4e5da5Sopenharmony_ci; CHECK-NOT: DebugDeclare 1957fd4e5da5Sopenharmony_ci%decl = OpExtInst %1 %ext DebugDeclare %dbg_foo %14 %null_expr 1958fd4e5da5Sopenharmony_ci 1959fd4e5da5Sopenharmony_ci%15 = OpInBoundsAccessChain %5 %14 %8 1960fd4e5da5Sopenharmony_ci%16 = OpLoad %2 %15 1961fd4e5da5Sopenharmony_ci%17 = OpAccessChain %5 %14 %10 1962fd4e5da5Sopenharmony_ci%18 = OpLoad %2 %17 1963fd4e5da5Sopenharmony_ci%19 = OpIAdd %2 %16 %18 1964fd4e5da5Sopenharmony_ciOpReturnValue %19 1965fd4e5da5Sopenharmony_ciOpFunctionEnd 1966fd4e5da5Sopenharmony_ci)"; 1967fd4e5da5Sopenharmony_ci 1968fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 1969fd4e5da5Sopenharmony_ci} 1970fd4e5da5Sopenharmony_ci 1971fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DebugValue) { 1972fd4e5da5Sopenharmony_ci const std::string text = R"( 1973fd4e5da5Sopenharmony_ciOpCapability Shader 1974fd4e5da5Sopenharmony_ciOpCapability Linkage 1975fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 1976fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1977fd4e5da5Sopenharmony_ci%test = OpString "test" 1978fd4e5da5Sopenharmony_ciOpName %6 "simple_struct" 1979fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 1980fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 1981fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %2 32 1982fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 %2 %2 1983fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 1984fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %2 1985fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 1986fd4e5da5Sopenharmony_ci%7 = OpConstantNull %3 1987fd4e5da5Sopenharmony_ci%8 = OpConstant %2 0 1988fd4e5da5Sopenharmony_ci%9 = OpConstant %2 1 1989fd4e5da5Sopenharmony_ci%10 = OpConstant %2 2 1990fd4e5da5Sopenharmony_ci%11 = OpConstant %2 3 1991fd4e5da5Sopenharmony_ci%deref = OpExtInst %1 %ext DebugOperation Deref 1992fd4e5da5Sopenharmony_ci%deref_expr = OpExtInst %1 %ext DebugExpression %deref 1993fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %1 %ext DebugExpression 1994fd4e5da5Sopenharmony_ci%src = OpExtInst %1 %ext DebugSource %test 1995fd4e5da5Sopenharmony_ci%cu = OpExtInst %1 %ext DebugCompilationUnit 1 4 %src HLSL 1996fd4e5da5Sopenharmony_ci%dbg_tf = OpExtInst %1 %ext DebugTypeBasic %test %uint_32 Float 1997fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %1 %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %1 1998fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %1 %ext DebugFunction %test %main_ty %src 0 0 %cu %test FlagIsProtected|FlagIsPrivate 0 %12 1999fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %1 %ext DebugLocalVariable %test %dbg_tf %src 0 0 %dbg_main FlagIsLocal 2000fd4e5da5Sopenharmony_ci%12 = OpFunction %2 None %6 2001fd4e5da5Sopenharmony_ci%13 = OpLabel 2002fd4e5da5Sopenharmony_ci%scope = OpExtInst %1 %ext DebugScope %dbg_main 2003fd4e5da5Sopenharmony_ci%14 = OpVariable %4 Function %7 2004fd4e5da5Sopenharmony_ci 2005fd4e5da5Sopenharmony_ci; CHECK: [[deref:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugOperation Deref 2006fd4e5da5Sopenharmony_ci; CHECK: [[deref_expr:%\w+]] = OpExtInst %void [[ext]] DebugExpression [[deref]] 2007fd4e5da5Sopenharmony_ci; CHECK: [[dbg_local_var:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable 2008fd4e5da5Sopenharmony_ci; CHECK: [[repl3:%\w+]] = OpVariable %_ptr_Function_uint Function 2009fd4e5da5Sopenharmony_ci; CHECK: [[repl2:%\w+]] = OpVariable %_ptr_Function_uint Function 2010fd4e5da5Sopenharmony_ci; CHECK: [[repl1:%\w+]] = OpVariable %_ptr_Function_uint Function 2011fd4e5da5Sopenharmony_ci; CHECK: [[repl0:%\w+]] = OpVariable %_ptr_Function_uint Function 2012fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl0]] [[deref_expr]] %int_0 2013fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl1]] [[deref_expr]] %int_1 2014fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl2]] [[deref_expr]] %int_2 2015fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl3]] [[deref_expr]] %int_3 2016fd4e5da5Sopenharmony_ci%value = OpExtInst %1 %ext DebugValue %dbg_foo %14 %deref_expr 2017fd4e5da5Sopenharmony_ci 2018fd4e5da5Sopenharmony_ci%15 = OpInBoundsAccessChain %5 %14 %8 2019fd4e5da5Sopenharmony_ci%16 = OpLoad %2 %15 2020fd4e5da5Sopenharmony_ci%17 = OpAccessChain %5 %14 %10 2021fd4e5da5Sopenharmony_ci%18 = OpLoad %2 %17 2022fd4e5da5Sopenharmony_ci%19 = OpIAdd %2 %16 %18 2023fd4e5da5Sopenharmony_ciOpReturnValue %19 2024fd4e5da5Sopenharmony_ciOpFunctionEnd 2025fd4e5da5Sopenharmony_ci)"; 2026fd4e5da5Sopenharmony_ci 2027fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 2028fd4e5da5Sopenharmony_ci} 2029fd4e5da5Sopenharmony_ci 2030fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DebugDeclareRecursive) { 2031fd4e5da5Sopenharmony_ci const std::string text = R"( 2032fd4e5da5Sopenharmony_ciOpCapability Shader 2033fd4e5da5Sopenharmony_ciOpCapability Linkage 2034fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 2035fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2036fd4e5da5Sopenharmony_ci%test = OpString "test" 2037fd4e5da5Sopenharmony_ciOpName %6 "simple_struct" 2038fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 2039fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 2040fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %2 32 2041fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 2042fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 2043fd4e5da5Sopenharmony_ci%member = OpTypeStruct %2 %float 2044fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %member %float 2045fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 2046fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %2 2047fd4e5da5Sopenharmony_ci%ptr_float_Function = OpTypePointer Function %float 2048fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 2049fd4e5da5Sopenharmony_ci%cmember = OpConstantComposite %member %uint_32 %float_1 2050fd4e5da5Sopenharmony_ci%7 = OpConstantComposite %3 %uint_32 %cmember %float_1 2051fd4e5da5Sopenharmony_ci%8 = OpConstant %2 0 2052fd4e5da5Sopenharmony_ci%9 = OpConstant %2 1 2053fd4e5da5Sopenharmony_ci%10 = OpConstant %2 2 2054fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %1 %ext DebugExpression 2055fd4e5da5Sopenharmony_ci%src = OpExtInst %1 %ext DebugSource %test 2056fd4e5da5Sopenharmony_ci%cu = OpExtInst %1 %ext DebugCompilationUnit 1 4 %src HLSL 2057fd4e5da5Sopenharmony_ci%dbg_tf = OpExtInst %1 %ext DebugTypeBasic %test %uint_32 Float 2058fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %1 %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %1 2059fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %1 %ext DebugFunction %test %main_ty %src 0 0 %cu %test FlagIsProtected|FlagIsPrivate 0 %12 2060fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %1 %ext DebugLocalVariable %test %dbg_tf %src 0 0 %dbg_main FlagIsLocal 2061fd4e5da5Sopenharmony_ci%12 = OpFunction %2 None %6 2062fd4e5da5Sopenharmony_ci%13 = OpLabel 2063fd4e5da5Sopenharmony_ci%scope = OpExtInst %1 %ext DebugScope %dbg_main 2064fd4e5da5Sopenharmony_ci%14 = OpVariable %4 Function %7 2065fd4e5da5Sopenharmony_ci 2066fd4e5da5Sopenharmony_ci; CHECK: [[deref:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugOperation Deref 2067fd4e5da5Sopenharmony_ci; CHECK: [[dbg_local_var:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable 2068fd4e5da5Sopenharmony_ci; CHECK: [[deref_expr:%\w+]] = OpExtInst %void [[ext]] DebugExpression [[deref]] 2069fd4e5da5Sopenharmony_ci; CHECK: [[repl2:%\w+]] = OpVariable %_ptr_Function_float Function %float_1 2070fd4e5da5Sopenharmony_ci; CHECK: [[repl1:%\w+]] = OpVariable %_ptr_Function_uint Function %uint_32 2071fd4e5da5Sopenharmony_ci; CHECK: [[repl3:%\w+]] = OpVariable %_ptr_Function_float Function %float_1 2072fd4e5da5Sopenharmony_ci; CHECK: [[repl0:%\w+]] = OpVariable %_ptr_Function_uint Function %uint_32 2073fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl3]] [[deref_expr]] %int_2 2074fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl1]] [[deref_expr]] %int_1 %int_0 2075fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl2]] [[deref_expr]] %int_1 %int_1 2076fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl0]] [[deref_expr]] %int_0 2077fd4e5da5Sopenharmony_ci; CHECK-NOT: DebugDeclare 2078fd4e5da5Sopenharmony_ci%decl = OpExtInst %1 %ext DebugDeclare %dbg_foo %14 %null_expr 2079fd4e5da5Sopenharmony_ci 2080fd4e5da5Sopenharmony_ci%15 = OpInBoundsAccessChain %5 %14 %8 2081fd4e5da5Sopenharmony_ci%16 = OpLoad %2 %15 2082fd4e5da5Sopenharmony_ci%17 = OpAccessChain %ptr_float_Function %14 %10 2083fd4e5da5Sopenharmony_ci%18 = OpLoad %float %17 2084fd4e5da5Sopenharmony_ci%value = OpConvertFToU %2 %18 2085fd4e5da5Sopenharmony_ci%19 = OpIAdd %2 %16 %value 2086fd4e5da5Sopenharmony_ciOpReturnValue %19 2087fd4e5da5Sopenharmony_ciOpFunctionEnd 2088fd4e5da5Sopenharmony_ci)"; 2089fd4e5da5Sopenharmony_ci 2090fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 2091fd4e5da5Sopenharmony_ci} 2092fd4e5da5Sopenharmony_ci 2093fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DebugValueWithIndex) { 2094fd4e5da5Sopenharmony_ci const std::string text = R"( 2095fd4e5da5Sopenharmony_ciOpCapability Shader 2096fd4e5da5Sopenharmony_ciOpCapability Linkage 2097fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 2098fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2099fd4e5da5Sopenharmony_ci%test = OpString "test" 2100fd4e5da5Sopenharmony_ciOpName %6 "simple_struct" 2101fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 2102fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 2103fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %2 32 2104fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 %2 %2 2105fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 2106fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %2 2107fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 2108fd4e5da5Sopenharmony_ci%7 = OpConstantNull %3 2109fd4e5da5Sopenharmony_ci%8 = OpConstant %2 0 2110fd4e5da5Sopenharmony_ci%9 = OpConstant %2 1 2111fd4e5da5Sopenharmony_ci%10 = OpConstant %2 2 2112fd4e5da5Sopenharmony_ci%11 = OpConstant %2 3 2113fd4e5da5Sopenharmony_ci%deref = OpExtInst %1 %ext DebugOperation Deref 2114fd4e5da5Sopenharmony_ci%deref_expr = OpExtInst %1 %ext DebugExpression %deref 2115fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %1 %ext DebugExpression 2116fd4e5da5Sopenharmony_ci%src = OpExtInst %1 %ext DebugSource %test 2117fd4e5da5Sopenharmony_ci%cu = OpExtInst %1 %ext DebugCompilationUnit 1 4 %src HLSL 2118fd4e5da5Sopenharmony_ci%dbg_tf = OpExtInst %1 %ext DebugTypeBasic %test %uint_32 Float 2119fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %1 %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %1 2120fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %1 %ext DebugFunction %test %main_ty %src 0 0 %cu %test FlagIsProtected|FlagIsPrivate 0 %12 2121fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %1 %ext DebugLocalVariable %test %dbg_tf %src 0 0 %dbg_main FlagIsLocal 2122fd4e5da5Sopenharmony_ci%12 = OpFunction %2 None %6 2123fd4e5da5Sopenharmony_ci%13 = OpLabel 2124fd4e5da5Sopenharmony_ci%scope = OpExtInst %1 %ext DebugScope %dbg_main 2125fd4e5da5Sopenharmony_ci%14 = OpVariable %4 Function %7 2126fd4e5da5Sopenharmony_ci 2127fd4e5da5Sopenharmony_ci; CHECK: [[deref:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugOperation Deref 2128fd4e5da5Sopenharmony_ci; CHECK: [[deref_expr:%\w+]] = OpExtInst %void [[ext]] DebugExpression [[deref]] 2129fd4e5da5Sopenharmony_ci; CHECK: [[dbg_local_var:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable 2130fd4e5da5Sopenharmony_ci; CHECK: [[repl3:%\w+]] = OpVariable %_ptr_Function_uint Function 2131fd4e5da5Sopenharmony_ci; CHECK: [[repl2:%\w+]] = OpVariable %_ptr_Function_uint Function 2132fd4e5da5Sopenharmony_ci; CHECK: [[repl1:%\w+]] = OpVariable %_ptr_Function_uint Function 2133fd4e5da5Sopenharmony_ci; CHECK: [[repl0:%\w+]] = OpVariable %_ptr_Function_uint Function 2134fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl0]] [[deref_expr]] %uint_0 %uint_1 %uint_2 %int_0 2135fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl1]] [[deref_expr]] %uint_0 %uint_1 %uint_2 %int_1 2136fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl2]] [[deref_expr]] %uint_0 %uint_1 %uint_2 %int_2 2137fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl3]] [[deref_expr]] %uint_0 %uint_1 %uint_2 %int_3 2138fd4e5da5Sopenharmony_ci%value = OpExtInst %1 %ext DebugValue %dbg_foo %14 %deref_expr %8 %9 %10 2139fd4e5da5Sopenharmony_ci 2140fd4e5da5Sopenharmony_ci%15 = OpInBoundsAccessChain %5 %14 %8 2141fd4e5da5Sopenharmony_ci%16 = OpLoad %2 %15 2142fd4e5da5Sopenharmony_ci%17 = OpAccessChain %5 %14 %10 2143fd4e5da5Sopenharmony_ci%18 = OpLoad %2 %17 2144fd4e5da5Sopenharmony_ci%19 = OpIAdd %2 %16 %18 2145fd4e5da5Sopenharmony_ciOpReturnValue %19 2146fd4e5da5Sopenharmony_ciOpFunctionEnd 2147fd4e5da5Sopenharmony_ci)"; 2148fd4e5da5Sopenharmony_ci 2149fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 2150fd4e5da5Sopenharmony_ci} 2151fd4e5da5Sopenharmony_ci 2152fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, DebugDeclareForVariableInOtherBB) { 2153fd4e5da5Sopenharmony_ci const std::string text = R"( 2154fd4e5da5Sopenharmony_ciOpCapability Shader 2155fd4e5da5Sopenharmony_ciOpCapability Linkage 2156fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 2157fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2158fd4e5da5Sopenharmony_ci%test = OpString "test" 2159fd4e5da5Sopenharmony_ciOpName %6 "simple_struct" 2160fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 2161fd4e5da5Sopenharmony_ci%2 = OpTypeInt 32 0 2162fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %2 32 2163fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %2 %2 %2 %2 2164fd4e5da5Sopenharmony_ci%4 = OpTypePointer Function %3 2165fd4e5da5Sopenharmony_ci%5 = OpTypePointer Function %2 2166fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %2 2167fd4e5da5Sopenharmony_ci%7 = OpConstantNull %3 2168fd4e5da5Sopenharmony_ci%8 = OpConstant %2 0 2169fd4e5da5Sopenharmony_ci%9 = OpConstant %2 1 2170fd4e5da5Sopenharmony_ci%10 = OpConstant %2 2 2171fd4e5da5Sopenharmony_ci%11 = OpConstant %2 3 2172fd4e5da5Sopenharmony_ci%deref = OpExtInst %1 %ext DebugOperation Deref 2173fd4e5da5Sopenharmony_ci%deref_expr = OpExtInst %1 %ext DebugExpression %deref 2174fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %1 %ext DebugExpression 2175fd4e5da5Sopenharmony_ci%src = OpExtInst %1 %ext DebugSource %test 2176fd4e5da5Sopenharmony_ci%cu = OpExtInst %1 %ext DebugCompilationUnit 1 4 %src HLSL 2177fd4e5da5Sopenharmony_ci%dbg_tf = OpExtInst %1 %ext DebugTypeBasic %test %uint_32 Float 2178fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %1 %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %1 2179fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %1 %ext DebugFunction %test %main_ty %src 0 0 %cu %test FlagIsProtected|FlagIsPrivate 0 %12 2180fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %1 %ext DebugLocalVariable %test %dbg_tf %src 0 0 %dbg_main FlagIsLocal 2181fd4e5da5Sopenharmony_ci%12 = OpFunction %2 None %6 2182fd4e5da5Sopenharmony_ci%13 = OpLabel 2183fd4e5da5Sopenharmony_ci%scope = OpExtInst %1 %ext DebugScope %dbg_main 2184fd4e5da5Sopenharmony_ci%14 = OpVariable %4 Function %7 2185fd4e5da5Sopenharmony_ci 2186fd4e5da5Sopenharmony_ci; CHECK: [[dbg_local_var:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugLocalVariable 2187fd4e5da5Sopenharmony_ci; CHECK: [[repl3:%\w+]] = OpVariable %_ptr_Function_uint Function 2188fd4e5da5Sopenharmony_ci; CHECK: [[repl2:%\w+]] = OpVariable %_ptr_Function_uint Function 2189fd4e5da5Sopenharmony_ci; CHECK: [[repl1:%\w+]] = OpVariable %_ptr_Function_uint Function 2190fd4e5da5Sopenharmony_ci; CHECK: [[repl0:%\w+]] = OpVariable %_ptr_Function_uint Function 2191fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl3]] [[deref_expr:%\w+]] %int_3 2192fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl2]] [[deref_expr]] %int_2 2193fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl1]] [[deref_expr]] %int_1 2194fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl0]] [[deref_expr]] %int_0 2195fd4e5da5Sopenharmony_ci 2196fd4e5da5Sopenharmony_ciOpBranch %20 2197fd4e5da5Sopenharmony_ci%20 = OpLabel 2198fd4e5da5Sopenharmony_ci%value = OpExtInst %1 %ext DebugDeclare %dbg_foo %14 %null_expr 2199fd4e5da5Sopenharmony_ci%15 = OpInBoundsAccessChain %5 %14 %8 2200fd4e5da5Sopenharmony_ci%16 = OpLoad %2 %15 2201fd4e5da5Sopenharmony_ci%17 = OpAccessChain %5 %14 %10 2202fd4e5da5Sopenharmony_ci%18 = OpLoad %2 %17 2203fd4e5da5Sopenharmony_ci%19 = OpIAdd %2 %16 %18 2204fd4e5da5Sopenharmony_ciOpReturnValue %19 2205fd4e5da5Sopenharmony_ciOpFunctionEnd 2206fd4e5da5Sopenharmony_ci)"; 2207fd4e5da5Sopenharmony_ci 2208fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 2209fd4e5da5Sopenharmony_ci} 2210fd4e5da5Sopenharmony_ci 2211fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, ImageTexelPointer) { 2212fd4e5da5Sopenharmony_ci // Test whether the scalar replacement correctly checks the 2213fd4e5da5Sopenharmony_ci // OpImageTexelPointer user of an aggregate with an image type. 2214fd4e5da5Sopenharmony_ci const std::string text = R"( 2215fd4e5da5Sopenharmony_ci; 2216fd4e5da5Sopenharmony_ci; CHECK: [[imgTy:%\w+]] = OpTypeImage %uint Buffer 2 0 0 2 R32ui 2217fd4e5da5Sopenharmony_ci; CHECK: [[ptrImgTy:%\w+]] = OpTypePointer Function [[imgTy]] 2218fd4e5da5Sopenharmony_ci; CHECK: [[img:%\w+]] = OpVariable [[ptrImgTy]] Function 2219fd4e5da5Sopenharmony_ci; CHECK: [[imgTexelPtr:%\w+]] = OpImageTexelPointer {{%\w+}} [[img]] %uint_0 %uint_0 2220fd4e5da5Sopenharmony_ci; CHECK: OpAtomicIAdd %uint [[imgTexelPtr]] %uint_1 %uint_0 %uint_1 2221fd4e5da5Sopenharmony_ci; 2222fd4e5da5Sopenharmony_ciOpCapability Shader 2223fd4e5da5Sopenharmony_ciOpCapability SampledBuffer 2224fd4e5da5Sopenharmony_ciOpCapability ImageBuffer 2225fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2226fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %1 "main" 2227fd4e5da5Sopenharmony_ciOpExecutionMode %1 LocalSize 64 1 1 2228fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2229fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 2230fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 2231fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 2232fd4e5da5Sopenharmony_ci%_ptr_Image_uint = OpTypePointer Image %uint 2233fd4e5da5Sopenharmony_ci%type_buffer_image = OpTypeImage %uint Buffer 2 0 0 2 R32ui 2234fd4e5da5Sopenharmony_ci%_ptr_Function_type_buffer_image = OpTypePointer Function %type_buffer_image 2235fd4e5da5Sopenharmony_ci%image_struct = OpTypeStruct %type_buffer_image %type_buffer_image 2236fd4e5da5Sopenharmony_ci%_ptr_Function_image_struct = OpTypePointer Function %image_struct 2237fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 2238fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %func 2239fd4e5da5Sopenharmony_ci%2 = OpLabel 2240fd4e5da5Sopenharmony_ci%3 = OpVariable %_ptr_Function_image_struct Function 2241fd4e5da5Sopenharmony_ci%4 = OpAccessChain %_ptr_Function_type_buffer_image %3 %uint_1 2242fd4e5da5Sopenharmony_ci%5 = OpImageTexelPointer %_ptr_Image_uint %4 %uint_0 %uint_0 2243fd4e5da5Sopenharmony_ci%6 = OpAtomicIAdd %uint %5 %uint_1 %uint_0 %uint_1 2244fd4e5da5Sopenharmony_ciOpReturn 2245fd4e5da5Sopenharmony_ciOpFunctionEnd 2246fd4e5da5Sopenharmony_ci )"; 2247fd4e5da5Sopenharmony_ci 2248fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, false); 2249fd4e5da5Sopenharmony_ci} 2250fd4e5da5Sopenharmony_ci 2251fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, FunctionDeclaration) { 2252fd4e5da5Sopenharmony_ci // Make sure the pass works with a function declaration that is called. 2253fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Addresses 2254fd4e5da5Sopenharmony_ciOpCapability Linkage 2255fd4e5da5Sopenharmony_ciOpCapability Kernel 2256fd4e5da5Sopenharmony_ciOpCapability Int8 2257fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.std" 2258fd4e5da5Sopenharmony_ciOpMemoryModel Physical64 OpenCL 2259fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %2 "_Z23julia__1166_kernel_77094Bool" 2260fd4e5da5Sopenharmony_ciOpExecutionMode %2 ContractionOff 2261fd4e5da5Sopenharmony_ciOpSource Unknown 0 2262fd4e5da5Sopenharmony_ciOpDecorate %3 LinkageAttributes "julia_error_7712" Import 2263fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2264fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 2265fd4e5da5Sopenharmony_ci%3 = OpFunction %void None %5 2266fd4e5da5Sopenharmony_ciOpFunctionEnd 2267fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %5 2268fd4e5da5Sopenharmony_ci%6 = OpLabel 2269fd4e5da5Sopenharmony_ci%7 = OpFunctionCall %void %3 2270fd4e5da5Sopenharmony_ciOpReturn 2271fd4e5da5Sopenharmony_ciOpFunctionEnd 2272fd4e5da5Sopenharmony_ci)"; 2273fd4e5da5Sopenharmony_ci 2274fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<ScalarReplacementPass>(text, text, false); 2275fd4e5da5Sopenharmony_ci} 2276fd4e5da5Sopenharmony_ci 2277fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, UndefImageMember) { 2278fd4e5da5Sopenharmony_ci // Test that scalar replacement creates an undef for a type that cannot have 2279fd4e5da5Sopenharmony_ci // and OpConstantNull. 2280fd4e5da5Sopenharmony_ci const std::string text = R"( 2281fd4e5da5Sopenharmony_ci; CHECK: [[image_type:%\w+]] = OpTypeSampledImage {{%\w+}} 2282fd4e5da5Sopenharmony_ci; CHECK: [[struct_type:%\w+]] = OpTypeStruct [[image_type]] 2283fd4e5da5Sopenharmony_ci; CHECK: [[undef:%\w+]] = OpUndef [[image_type]] 2284fd4e5da5Sopenharmony_ci; CHECK: {{%\w+}} = OpCompositeConstruct [[struct_type]] [[undef]] 2285fd4e5da5Sopenharmony_ci OpCapability Shader 2286fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2287fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2288fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 2289fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 2290fd4e5da5Sopenharmony_ci %void = OpTypeVoid 2291fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %void 2292fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 2293fd4e5da5Sopenharmony_ci %6 = OpTypeImage %float 2D 0 0 0 1 Unknown 2294fd4e5da5Sopenharmony_ci %7 = OpTypeSampledImage %6 2295fd4e5da5Sopenharmony_ci %_struct_8 = OpTypeStruct %7 2296fd4e5da5Sopenharmony_ci %9 = OpTypeFunction %_struct_8 2297fd4e5da5Sopenharmony_ci %10 = OpUndef %_struct_8 2298fd4e5da5Sopenharmony_ci%_ptr_Function__struct_8 = OpTypePointer Function %_struct_8 2299fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %4 2300fd4e5da5Sopenharmony_ci %11 = OpLabel 2301fd4e5da5Sopenharmony_ci %16 = OpVariable %_ptr_Function__struct_8 Function 2302fd4e5da5Sopenharmony_ci OpStore %16 %10 2303fd4e5da5Sopenharmony_ci %12 = OpLoad %_struct_8 %16 2304fd4e5da5Sopenharmony_ci OpReturn 2305fd4e5da5Sopenharmony_ci OpFunctionEnd 2306fd4e5da5Sopenharmony_ci )"; 2307fd4e5da5Sopenharmony_ci 2308fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 2309fd4e5da5Sopenharmony_ci} 2310fd4e5da5Sopenharmony_ci 2311fd4e5da5Sopenharmony_ciTEST_F(ScalarReplacementTest, RestrictPointer) { 2312fd4e5da5Sopenharmony_ci // This test makes sure that a variable with the restrict pointer decoration 2313fd4e5da5Sopenharmony_ci // is replaced, and that the pointer is applied to the new variable. 2314fd4e5da5Sopenharmony_ci const std::string text = R"( 2315fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[new_var:%\w+]] RestrictPointer 2316fd4e5da5Sopenharmony_ci; CHECK: [[struct_type:%\w+]] = OpTypeStruct %int 2317fd4e5da5Sopenharmony_ci; CHECK: [[ptr_type:%\w+]] = OpTypePointer PhysicalStorageBuffer [[struct_type]] 2318fd4e5da5Sopenharmony_ci; CHECK: [[dup_struct_type:%\w+]] = OpTypeStruct %int 2319fd4e5da5Sopenharmony_ci; CHECK: {{%\w+}} = OpTypePointer PhysicalStorageBuffer [[dup_struct_type]] 2320fd4e5da5Sopenharmony_ci; CHECK: [[var_type:%\w+]] = OpTypePointer Function [[ptr_type]] 2321fd4e5da5Sopenharmony_ci; CHECK: [[new_var]] = OpVariable [[var_type]] Function 2322fd4e5da5Sopenharmony_ci OpCapability Shader 2323fd4e5da5Sopenharmony_ci OpCapability PhysicalStorageBufferAddresses 2324fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2325fd4e5da5Sopenharmony_ci OpMemoryModel PhysicalStorageBuffer64 GLSL450 2326fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 2327fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 2328fd4e5da5Sopenharmony_ci OpMemberDecorate %3 0 Offset 0 2329fd4e5da5Sopenharmony_ci OpDecorate %3 Block 2330fd4e5da5Sopenharmony_ci OpMemberDecorate %4 0 Offset 0 2331fd4e5da5Sopenharmony_ci OpDecorate %4 Block 2332fd4e5da5Sopenharmony_ci OpDecorate %5 RestrictPointer 2333fd4e5da5Sopenharmony_ci %6 = OpTypeVoid 2334fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %6 2335fd4e5da5Sopenharmony_ci %8 = OpTypeInt 32 1 2336fd4e5da5Sopenharmony_ci %9 = OpConstant %8 0 2337fd4e5da5Sopenharmony_ci %3 = OpTypeStruct %8 2338fd4e5da5Sopenharmony_ci %10 = OpTypePointer PhysicalStorageBuffer %3 2339fd4e5da5Sopenharmony_ci %11 = OpTypeStruct %10 2340fd4e5da5Sopenharmony_ci %4 = OpTypeStruct %8 2341fd4e5da5Sopenharmony_ci %12 = OpTypePointer PhysicalStorageBuffer %4 2342fd4e5da5Sopenharmony_ci %13 = OpTypePointer Function %11 2343fd4e5da5Sopenharmony_ci %14 = OpTypePointer Function %10 2344fd4e5da5Sopenharmony_ci %15 = OpTypePointer Function %12 2345fd4e5da5Sopenharmony_ci %16 = OpUndef %11 2346fd4e5da5Sopenharmony_ci %2 = OpFunction %6 None %7 2347fd4e5da5Sopenharmony_ci %17 = OpLabel 2348fd4e5da5Sopenharmony_ci %5 = OpVariable %13 Function 2349fd4e5da5Sopenharmony_ci OpStore %5 %16 2350fd4e5da5Sopenharmony_ci %18 = OpAccessChain %14 %5 %9 2351fd4e5da5Sopenharmony_ci OpReturn 2352fd4e5da5Sopenharmony_ci OpFunctionEnd 2353fd4e5da5Sopenharmony_ci )"; 2354fd4e5da5Sopenharmony_ci 2355fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_UNIVERSAL_1_6); 2356fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<ScalarReplacementPass>(text, true); 2357fd4e5da5Sopenharmony_ci} 2358fd4e5da5Sopenharmony_ci 2359fd4e5da5Sopenharmony_ci} // namespace 2360fd4e5da5Sopenharmony_ci} // namespace opt 2361fd4e5da5Sopenharmony_ci} // namespace spvtools 2362