1fd4e5da5Sopenharmony_ci// Copyright (c) 2016 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 <algorithm> 16fd4e5da5Sopenharmony_ci#include <string> 17fd4e5da5Sopenharmony_ci#include <unordered_set> 18fd4e5da5Sopenharmony_ci#include <vector> 19fd4e5da5Sopenharmony_ci 20fd4e5da5Sopenharmony_ci#include "test/opt/assembly_builder.h" 21fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 22fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 23fd4e5da5Sopenharmony_ci 24fd4e5da5Sopenharmony_cinamespace spvtools { 25fd4e5da5Sopenharmony_cinamespace opt { 26fd4e5da5Sopenharmony_cinamespace { 27fd4e5da5Sopenharmony_ci 28fd4e5da5Sopenharmony_ciusing EliminateDeadConstantBasicTest = PassTest<::testing::Test>; 29fd4e5da5Sopenharmony_ci 30fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadConstantBasicTest, BasicAllDeadConstants) { 31fd4e5da5Sopenharmony_ci const std::vector<const char*> text = { 32fd4e5da5Sopenharmony_ci // clang-format off 33fd4e5da5Sopenharmony_ci "OpCapability Shader", 34fd4e5da5Sopenharmony_ci "OpCapability Float64", 35fd4e5da5Sopenharmony_ci "%1 = OpExtInstImport \"GLSL.std.450\"", 36fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 37fd4e5da5Sopenharmony_ci "OpEntryPoint Vertex %main \"main\"", 38fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 39fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 40fd4e5da5Sopenharmony_ci "%4 = OpTypeFunction %void", 41fd4e5da5Sopenharmony_ci "%bool = OpTypeBool", 42fd4e5da5Sopenharmony_ci "%true = OpConstantTrue %bool", 43fd4e5da5Sopenharmony_ci "%false = OpConstantFalse %bool", 44fd4e5da5Sopenharmony_ci "%int = OpTypeInt 32 1", 45fd4e5da5Sopenharmony_ci "%9 = OpConstant %int 1", 46fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 47fd4e5da5Sopenharmony_ci "%11 = OpConstant %uint 2", 48fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 49fd4e5da5Sopenharmony_ci "%13 = OpConstant %float 3.1415", 50fd4e5da5Sopenharmony_ci "%double = OpTypeFloat 64", 51fd4e5da5Sopenharmony_ci "%15 = OpConstant %double 3.14159265358979", 52fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %4", 53fd4e5da5Sopenharmony_ci "%16 = OpLabel", 54fd4e5da5Sopenharmony_ci "OpReturn", 55fd4e5da5Sopenharmony_ci "OpFunctionEnd", 56fd4e5da5Sopenharmony_ci // clang-format on 57fd4e5da5Sopenharmony_ci }; 58fd4e5da5Sopenharmony_ci // None of the above constants is ever used, so all of them should be 59fd4e5da5Sopenharmony_ci // eliminated. 60fd4e5da5Sopenharmony_ci const char* const_decl_opcodes[] = { 61fd4e5da5Sopenharmony_ci " OpConstantTrue ", 62fd4e5da5Sopenharmony_ci " OpConstantFalse ", 63fd4e5da5Sopenharmony_ci " OpConstant ", 64fd4e5da5Sopenharmony_ci }; 65fd4e5da5Sopenharmony_ci // Skip lines that have any one of const_decl_opcodes. 66fd4e5da5Sopenharmony_ci const std::string expected_disassembly = 67fd4e5da5Sopenharmony_ci SelectiveJoin(text, [&const_decl_opcodes](const char* line) { 68fd4e5da5Sopenharmony_ci return std::any_of( 69fd4e5da5Sopenharmony_ci std::begin(const_decl_opcodes), std::end(const_decl_opcodes), 70fd4e5da5Sopenharmony_ci [&line](const char* const_decl_op) { 71fd4e5da5Sopenharmony_ci return std::string(line).find(const_decl_op) != std::string::npos; 72fd4e5da5Sopenharmony_ci }); 73fd4e5da5Sopenharmony_ci }); 74fd4e5da5Sopenharmony_ci 75fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<EliminateDeadConstantPass>( 76fd4e5da5Sopenharmony_ci JoinAllInsts(text), expected_disassembly, /* skip_nop = */ true); 77fd4e5da5Sopenharmony_ci} 78fd4e5da5Sopenharmony_ci 79fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadConstantBasicTest, BasicNoneDeadConstants) { 80fd4e5da5Sopenharmony_ci const std::vector<const char*> text = { 81fd4e5da5Sopenharmony_ci // clang-format off 82fd4e5da5Sopenharmony_ci "OpCapability Shader", 83fd4e5da5Sopenharmony_ci "OpCapability Float64", 84fd4e5da5Sopenharmony_ci "%1 = OpExtInstImport \"GLSL.std.450\"", 85fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 86fd4e5da5Sopenharmony_ci "OpEntryPoint Vertex %main \"main\"", 87fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 88fd4e5da5Sopenharmony_ci "OpName %btv \"btv\"", 89fd4e5da5Sopenharmony_ci "OpName %bfv \"bfv\"", 90fd4e5da5Sopenharmony_ci "OpName %iv \"iv\"", 91fd4e5da5Sopenharmony_ci "OpName %uv \"uv\"", 92fd4e5da5Sopenharmony_ci "OpName %fv \"fv\"", 93fd4e5da5Sopenharmony_ci "OpName %dv \"dv\"", 94fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 95fd4e5da5Sopenharmony_ci "%10 = OpTypeFunction %void", 96fd4e5da5Sopenharmony_ci "%bool = OpTypeBool", 97fd4e5da5Sopenharmony_ci "%_ptr_Function_bool = OpTypePointer Function %bool", 98fd4e5da5Sopenharmony_ci "%true = OpConstantTrue %bool", 99fd4e5da5Sopenharmony_ci "%false = OpConstantFalse %bool", 100fd4e5da5Sopenharmony_ci "%int = OpTypeInt 32 1", 101fd4e5da5Sopenharmony_ci "%_ptr_Function_int = OpTypePointer Function %int", 102fd4e5da5Sopenharmony_ci "%int_1 = OpConstant %int 1", 103fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 104fd4e5da5Sopenharmony_ci "%_ptr_Function_uint = OpTypePointer Function %uint", 105fd4e5da5Sopenharmony_ci "%uint_2 = OpConstant %uint 2", 106fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 107fd4e5da5Sopenharmony_ci "%_ptr_Function_float = OpTypePointer Function %float", 108fd4e5da5Sopenharmony_ci "%float_3_1415 = OpConstant %float 3.1415", 109fd4e5da5Sopenharmony_ci "%double = OpTypeFloat 64", 110fd4e5da5Sopenharmony_ci "%_ptr_Function_double = OpTypePointer Function %double", 111fd4e5da5Sopenharmony_ci "%double_3_14159265358979 = OpConstant %double 3.14159265358979", 112fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %10", 113fd4e5da5Sopenharmony_ci "%27 = OpLabel", 114fd4e5da5Sopenharmony_ci "%btv = OpVariable %_ptr_Function_bool Function", 115fd4e5da5Sopenharmony_ci "%bfv = OpVariable %_ptr_Function_bool Function", 116fd4e5da5Sopenharmony_ci "%iv = OpVariable %_ptr_Function_int Function", 117fd4e5da5Sopenharmony_ci "%uv = OpVariable %_ptr_Function_uint Function", 118fd4e5da5Sopenharmony_ci "%fv = OpVariable %_ptr_Function_float Function", 119fd4e5da5Sopenharmony_ci "%dv = OpVariable %_ptr_Function_double Function", 120fd4e5da5Sopenharmony_ci "OpStore %btv %true", 121fd4e5da5Sopenharmony_ci "OpStore %bfv %false", 122fd4e5da5Sopenharmony_ci "OpStore %iv %int_1", 123fd4e5da5Sopenharmony_ci "OpStore %uv %uint_2", 124fd4e5da5Sopenharmony_ci "OpStore %fv %float_3_1415", 125fd4e5da5Sopenharmony_ci "OpStore %dv %double_3_14159265358979", 126fd4e5da5Sopenharmony_ci "OpReturn", 127fd4e5da5Sopenharmony_ci "OpFunctionEnd", 128fd4e5da5Sopenharmony_ci // clang-format on 129fd4e5da5Sopenharmony_ci }; 130fd4e5da5Sopenharmony_ci // All constants are used, so none of them should be eliminated. 131fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<EliminateDeadConstantPass>( 132fd4e5da5Sopenharmony_ci JoinAllInsts(text), JoinAllInsts(text), /* skip_nop = */ true); 133fd4e5da5Sopenharmony_ci} 134fd4e5da5Sopenharmony_ci 135fd4e5da5Sopenharmony_cistruct EliminateDeadConstantTestCase { 136fd4e5da5Sopenharmony_ci // Type declarations and constants that should be kept. 137fd4e5da5Sopenharmony_ci std::vector<std::string> used_consts; 138fd4e5da5Sopenharmony_ci // Instructions that refer to constants, this is added to create uses for 139fd4e5da5Sopenharmony_ci // some constants so they won't be treated as dead constants. 140fd4e5da5Sopenharmony_ci std::vector<std::string> main_insts; 141fd4e5da5Sopenharmony_ci // Dead constants that should be removed. 142fd4e5da5Sopenharmony_ci std::vector<std::string> dead_consts; 143fd4e5da5Sopenharmony_ci}; 144fd4e5da5Sopenharmony_ci 145fd4e5da5Sopenharmony_ci// All types that are potentially required in EliminateDeadConstantTest. 146fd4e5da5Sopenharmony_ciconst std::vector<std::string> CommonTypes = { 147fd4e5da5Sopenharmony_ci // clang-format off 148fd4e5da5Sopenharmony_ci // scalar types 149fd4e5da5Sopenharmony_ci "%bool = OpTypeBool", 150fd4e5da5Sopenharmony_ci "%uint = OpTypeInt 32 0", 151fd4e5da5Sopenharmony_ci "%int = OpTypeInt 32 1", 152fd4e5da5Sopenharmony_ci "%float = OpTypeFloat 32", 153fd4e5da5Sopenharmony_ci "%double = OpTypeFloat 64", 154fd4e5da5Sopenharmony_ci // vector types 155fd4e5da5Sopenharmony_ci "%v2bool = OpTypeVector %bool 2", 156fd4e5da5Sopenharmony_ci "%v2uint = OpTypeVector %uint 2", 157fd4e5da5Sopenharmony_ci "%v2int = OpTypeVector %int 2", 158fd4e5da5Sopenharmony_ci "%v3int = OpTypeVector %int 3", 159fd4e5da5Sopenharmony_ci "%v4int = OpTypeVector %int 4", 160fd4e5da5Sopenharmony_ci "%v2float = OpTypeVector %float 2", 161fd4e5da5Sopenharmony_ci "%v3float = OpTypeVector %float 3", 162fd4e5da5Sopenharmony_ci "%v2double = OpTypeVector %double 2", 163fd4e5da5Sopenharmony_ci // variable pointer types 164fd4e5da5Sopenharmony_ci "%_pf_bool = OpTypePointer Function %bool", 165fd4e5da5Sopenharmony_ci "%_pf_uint = OpTypePointer Function %uint", 166fd4e5da5Sopenharmony_ci "%_pf_int = OpTypePointer Function %int", 167fd4e5da5Sopenharmony_ci "%_pf_float = OpTypePointer Function %float", 168fd4e5da5Sopenharmony_ci "%_pf_double = OpTypePointer Function %double", 169fd4e5da5Sopenharmony_ci "%_pf_v2int = OpTypePointer Function %v2int", 170fd4e5da5Sopenharmony_ci "%_pf_v3int = OpTypePointer Function %v3int", 171fd4e5da5Sopenharmony_ci "%_pf_v2float = OpTypePointer Function %v2float", 172fd4e5da5Sopenharmony_ci "%_pf_v3float = OpTypePointer Function %v3float", 173fd4e5da5Sopenharmony_ci "%_pf_v2double = OpTypePointer Function %v2double", 174fd4e5da5Sopenharmony_ci // struct types 175fd4e5da5Sopenharmony_ci "%inner_struct = OpTypeStruct %bool %int %float %double", 176fd4e5da5Sopenharmony_ci "%outer_struct = OpTypeStruct %inner_struct %int %double", 177fd4e5da5Sopenharmony_ci "%flat_struct = OpTypeStruct %bool %int %float %double", 178fd4e5da5Sopenharmony_ci // clang-format on 179fd4e5da5Sopenharmony_ci}; 180fd4e5da5Sopenharmony_ci 181fd4e5da5Sopenharmony_ciusing EliminateDeadConstantTest = 182fd4e5da5Sopenharmony_ci PassTest<::testing::TestWithParam<EliminateDeadConstantTestCase>>; 183fd4e5da5Sopenharmony_ci 184fd4e5da5Sopenharmony_ciTEST_P(EliminateDeadConstantTest, Custom) { 185fd4e5da5Sopenharmony_ci auto& tc = GetParam(); 186fd4e5da5Sopenharmony_ci AssemblyBuilder builder; 187fd4e5da5Sopenharmony_ci builder.AppendTypesConstantsGlobals(CommonTypes) 188fd4e5da5Sopenharmony_ci .AppendTypesConstantsGlobals(tc.used_consts) 189fd4e5da5Sopenharmony_ci .AppendInMain(tc.main_insts); 190fd4e5da5Sopenharmony_ci const std::string expected = builder.GetCode(); 191fd4e5da5Sopenharmony_ci builder.AppendTypesConstantsGlobals(tc.dead_consts); 192fd4e5da5Sopenharmony_ci const std::string assembly_with_dead_const = builder.GetCode(); 193fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<EliminateDeadConstantPass>( 194fd4e5da5Sopenharmony_ci assembly_with_dead_const, expected, /* skip_nop = */ true); 195fd4e5da5Sopenharmony_ci} 196fd4e5da5Sopenharmony_ci 197fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 198fd4e5da5Sopenharmony_ci ScalarTypeConstants, EliminateDeadConstantTest, 199fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EliminateDeadConstantTestCase>({ 200fd4e5da5Sopenharmony_ci // clang-format off 201fd4e5da5Sopenharmony_ci // Scalar type constants, one dead constant and one used constant. 202fd4e5da5Sopenharmony_ci { 203fd4e5da5Sopenharmony_ci /* .used_consts = */ 204fd4e5da5Sopenharmony_ci { 205fd4e5da5Sopenharmony_ci "%used_const_int = OpConstant %int 1", 206fd4e5da5Sopenharmony_ci }, 207fd4e5da5Sopenharmony_ci /* .main_insts = */ 208fd4e5da5Sopenharmony_ci { 209fd4e5da5Sopenharmony_ci "%int_var = OpVariable %_pf_int Function", 210fd4e5da5Sopenharmony_ci "OpStore %int_var %used_const_int", 211fd4e5da5Sopenharmony_ci }, 212fd4e5da5Sopenharmony_ci /* .dead_consts = */ 213fd4e5da5Sopenharmony_ci { 214fd4e5da5Sopenharmony_ci "%dead_const_int = OpConstant %int 1", 215fd4e5da5Sopenharmony_ci }, 216fd4e5da5Sopenharmony_ci }, 217fd4e5da5Sopenharmony_ci { 218fd4e5da5Sopenharmony_ci /* .used_consts = */ 219fd4e5da5Sopenharmony_ci { 220fd4e5da5Sopenharmony_ci "%used_const_uint = OpConstant %uint 1", 221fd4e5da5Sopenharmony_ci }, 222fd4e5da5Sopenharmony_ci /* .main_insts = */ 223fd4e5da5Sopenharmony_ci { 224fd4e5da5Sopenharmony_ci "%uint_var = OpVariable %_pf_uint Function", 225fd4e5da5Sopenharmony_ci "OpStore %uint_var %used_const_uint", 226fd4e5da5Sopenharmony_ci }, 227fd4e5da5Sopenharmony_ci /* .dead_consts = */ 228fd4e5da5Sopenharmony_ci { 229fd4e5da5Sopenharmony_ci "%dead_const_uint = OpConstant %uint 1", 230fd4e5da5Sopenharmony_ci }, 231fd4e5da5Sopenharmony_ci }, 232fd4e5da5Sopenharmony_ci { 233fd4e5da5Sopenharmony_ci /* .used_consts = */ 234fd4e5da5Sopenharmony_ci { 235fd4e5da5Sopenharmony_ci "%used_const_float = OpConstant %float 3.1415", 236fd4e5da5Sopenharmony_ci }, 237fd4e5da5Sopenharmony_ci /* .main_insts = */ 238fd4e5da5Sopenharmony_ci { 239fd4e5da5Sopenharmony_ci "%float_var = OpVariable %_pf_float Function", 240fd4e5da5Sopenharmony_ci "OpStore %float_var %used_const_float", 241fd4e5da5Sopenharmony_ci }, 242fd4e5da5Sopenharmony_ci /* .dead_consts = */ 243fd4e5da5Sopenharmony_ci { 244fd4e5da5Sopenharmony_ci "%dead_const_float = OpConstant %float 3.1415", 245fd4e5da5Sopenharmony_ci }, 246fd4e5da5Sopenharmony_ci }, 247fd4e5da5Sopenharmony_ci { 248fd4e5da5Sopenharmony_ci /* .used_consts = */ 249fd4e5da5Sopenharmony_ci { 250fd4e5da5Sopenharmony_ci "%used_const_double = OpConstant %double 3.141592653", 251fd4e5da5Sopenharmony_ci }, 252fd4e5da5Sopenharmony_ci /* .main_insts = */ 253fd4e5da5Sopenharmony_ci { 254fd4e5da5Sopenharmony_ci "%double_var = OpVariable %_pf_double Function", 255fd4e5da5Sopenharmony_ci "OpStore %double_var %used_const_double", 256fd4e5da5Sopenharmony_ci }, 257fd4e5da5Sopenharmony_ci /* .dead_consts = */ 258fd4e5da5Sopenharmony_ci { 259fd4e5da5Sopenharmony_ci "%dead_const_double = OpConstant %double 3.141592653", 260fd4e5da5Sopenharmony_ci }, 261fd4e5da5Sopenharmony_ci }, 262fd4e5da5Sopenharmony_ci // clang-format on 263fd4e5da5Sopenharmony_ci }))); 264fd4e5da5Sopenharmony_ci 265fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 266fd4e5da5Sopenharmony_ci VectorTypeConstants, EliminateDeadConstantTest, 267fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EliminateDeadConstantTestCase>({ 268fd4e5da5Sopenharmony_ci // clang-format off 269fd4e5da5Sopenharmony_ci // Tests eliminating dead constant type ivec2. One dead constant vector 270fd4e5da5Sopenharmony_ci // and one used constant vector, each built from its own group of 271fd4e5da5Sopenharmony_ci // scalar constants. 272fd4e5da5Sopenharmony_ci { 273fd4e5da5Sopenharmony_ci /* .used_consts = */ 274fd4e5da5Sopenharmony_ci { 275fd4e5da5Sopenharmony_ci "%used_int_x = OpConstant %int 1", 276fd4e5da5Sopenharmony_ci "%used_int_y = OpConstant %int 2", 277fd4e5da5Sopenharmony_ci "%used_v2int = OpConstantComposite %v2int %used_int_x %used_int_y", 278fd4e5da5Sopenharmony_ci }, 279fd4e5da5Sopenharmony_ci /* .main_insts = */ 280fd4e5da5Sopenharmony_ci { 281fd4e5da5Sopenharmony_ci "%v2int_var = OpVariable %_pf_v2int Function", 282fd4e5da5Sopenharmony_ci "OpStore %v2int_var %used_v2int", 283fd4e5da5Sopenharmony_ci }, 284fd4e5da5Sopenharmony_ci /* .dead_consts = */ 285fd4e5da5Sopenharmony_ci { 286fd4e5da5Sopenharmony_ci "%dead_int_x = OpConstant %int 1", 287fd4e5da5Sopenharmony_ci "%dead_int_y = OpConstant %int 2", 288fd4e5da5Sopenharmony_ci "%dead_v2int = OpConstantComposite %v2int %dead_int_x %dead_int_y", 289fd4e5da5Sopenharmony_ci }, 290fd4e5da5Sopenharmony_ci }, 291fd4e5da5Sopenharmony_ci // Tests eliminating dead constant ivec2. One dead constant vector and 292fd4e5da5Sopenharmony_ci // one used constant vector. But both built from a same group of 293fd4e5da5Sopenharmony_ci // scalar constants. 294fd4e5da5Sopenharmony_ci { 295fd4e5da5Sopenharmony_ci /* .used_consts = */ 296fd4e5da5Sopenharmony_ci { 297fd4e5da5Sopenharmony_ci "%used_int_x = OpConstant %int 1", 298fd4e5da5Sopenharmony_ci "%used_int_y = OpConstant %int 2", 299fd4e5da5Sopenharmony_ci "%used_int_z = OpConstant %int 3", 300fd4e5da5Sopenharmony_ci "%used_v3int = OpConstantComposite %v3int %used_int_x %used_int_y %used_int_z", 301fd4e5da5Sopenharmony_ci }, 302fd4e5da5Sopenharmony_ci /* .main_insts = */ 303fd4e5da5Sopenharmony_ci { 304fd4e5da5Sopenharmony_ci "%v3int_var = OpVariable %_pf_v3int Function", 305fd4e5da5Sopenharmony_ci "OpStore %v3int_var %used_v3int", 306fd4e5da5Sopenharmony_ci }, 307fd4e5da5Sopenharmony_ci /* .dead_consts = */ 308fd4e5da5Sopenharmony_ci { 309fd4e5da5Sopenharmony_ci "%dead_v3int = OpConstantComposite %v3int %used_int_x %used_int_y %used_int_z", 310fd4e5da5Sopenharmony_ci }, 311fd4e5da5Sopenharmony_ci }, 312fd4e5da5Sopenharmony_ci // Tests eliminating dead cosntant vec2. One dead constant vector and 313fd4e5da5Sopenharmony_ci // one used constant vector. Each built from its own group of scalar 314fd4e5da5Sopenharmony_ci // constants. 315fd4e5da5Sopenharmony_ci { 316fd4e5da5Sopenharmony_ci /* .used_consts = */ 317fd4e5da5Sopenharmony_ci { 318fd4e5da5Sopenharmony_ci "%used_float_x = OpConstant %float 3.1415", 319fd4e5da5Sopenharmony_ci "%used_float_y = OpConstant %float 4.25", 320fd4e5da5Sopenharmony_ci "%used_v2float = OpConstantComposite %v2float %used_float_x %used_float_y", 321fd4e5da5Sopenharmony_ci }, 322fd4e5da5Sopenharmony_ci /* .main_insts = */ 323fd4e5da5Sopenharmony_ci { 324fd4e5da5Sopenharmony_ci "%v2float_var = OpVariable %_pf_v2float Function", 325fd4e5da5Sopenharmony_ci "OpStore %v2float_var %used_v2float", 326fd4e5da5Sopenharmony_ci }, 327fd4e5da5Sopenharmony_ci /* .dead_consts = */ 328fd4e5da5Sopenharmony_ci { 329fd4e5da5Sopenharmony_ci "%dead_float_x = OpConstant %float 3.1415", 330fd4e5da5Sopenharmony_ci "%dead_float_y = OpConstant %float 4.25", 331fd4e5da5Sopenharmony_ci "%dead_v2float = OpConstantComposite %v2float %dead_float_x %dead_float_y", 332fd4e5da5Sopenharmony_ci }, 333fd4e5da5Sopenharmony_ci }, 334fd4e5da5Sopenharmony_ci // Tests eliminating dead cosntant vec2. One dead constant vector and 335fd4e5da5Sopenharmony_ci // one used constant vector. Both built from a same group of scalar 336fd4e5da5Sopenharmony_ci // constants. 337fd4e5da5Sopenharmony_ci { 338fd4e5da5Sopenharmony_ci /* .used_consts = */ 339fd4e5da5Sopenharmony_ci { 340fd4e5da5Sopenharmony_ci "%used_float_x = OpConstant %float 3.1415", 341fd4e5da5Sopenharmony_ci "%used_float_y = OpConstant %float 4.25", 342fd4e5da5Sopenharmony_ci "%used_float_z = OpConstant %float 4.75", 343fd4e5da5Sopenharmony_ci "%used_v3float = OpConstantComposite %v3float %used_float_x %used_float_y %used_float_z", 344fd4e5da5Sopenharmony_ci }, 345fd4e5da5Sopenharmony_ci /* .main_insts = */ 346fd4e5da5Sopenharmony_ci { 347fd4e5da5Sopenharmony_ci "%v3float_var = OpVariable %_pf_v3float Function", 348fd4e5da5Sopenharmony_ci "OpStore %v3float_var %used_v3float", 349fd4e5da5Sopenharmony_ci }, 350fd4e5da5Sopenharmony_ci /* .dead_consts = */ 351fd4e5da5Sopenharmony_ci { 352fd4e5da5Sopenharmony_ci "%dead_v3float = OpConstantComposite %v3float %used_float_x %used_float_y %used_float_z", 353fd4e5da5Sopenharmony_ci }, 354fd4e5da5Sopenharmony_ci }, 355fd4e5da5Sopenharmony_ci // clang-format on 356fd4e5da5Sopenharmony_ci }))); 357fd4e5da5Sopenharmony_ci 358fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 359fd4e5da5Sopenharmony_ci StructTypeConstants, EliminateDeadConstantTest, 360fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EliminateDeadConstantTestCase>({ 361fd4e5da5Sopenharmony_ci // clang-format off 362fd4e5da5Sopenharmony_ci // A plain struct type dead constants. All of its components are dead 363fd4e5da5Sopenharmony_ci // constants too. 364fd4e5da5Sopenharmony_ci { 365fd4e5da5Sopenharmony_ci /* .used_consts = */ {}, 366fd4e5da5Sopenharmony_ci /* .main_insts = */ {}, 367fd4e5da5Sopenharmony_ci /* .dead_consts = */ 368fd4e5da5Sopenharmony_ci { 369fd4e5da5Sopenharmony_ci "%dead_bool = OpConstantTrue %bool", 370fd4e5da5Sopenharmony_ci "%dead_int = OpConstant %int 1", 371fd4e5da5Sopenharmony_ci "%dead_float = OpConstant %float 2.5", 372fd4e5da5Sopenharmony_ci "%dead_double = OpConstant %double 3.14159265358979", 373fd4e5da5Sopenharmony_ci "%dead_struct = OpConstantComposite %flat_struct %dead_bool %dead_int %dead_float %dead_double", 374fd4e5da5Sopenharmony_ci }, 375fd4e5da5Sopenharmony_ci }, 376fd4e5da5Sopenharmony_ci // A plain struct type dead constants. Some of its components are dead 377fd4e5da5Sopenharmony_ci // constants while others are not. 378fd4e5da5Sopenharmony_ci { 379fd4e5da5Sopenharmony_ci /* .used_consts = */ 380fd4e5da5Sopenharmony_ci { 381fd4e5da5Sopenharmony_ci "%used_int = OpConstant %int 1", 382fd4e5da5Sopenharmony_ci "%used_double = OpConstant %double 3.14159265358979", 383fd4e5da5Sopenharmony_ci }, 384fd4e5da5Sopenharmony_ci /* .main_insts = */ 385fd4e5da5Sopenharmony_ci { 386fd4e5da5Sopenharmony_ci "%int_var = OpVariable %_pf_int Function", 387fd4e5da5Sopenharmony_ci "OpStore %int_var %used_int", 388fd4e5da5Sopenharmony_ci "%double_var = OpVariable %_pf_double Function", 389fd4e5da5Sopenharmony_ci "OpStore %double_var %used_double", 390fd4e5da5Sopenharmony_ci }, 391fd4e5da5Sopenharmony_ci /* .dead_consts = */ 392fd4e5da5Sopenharmony_ci { 393fd4e5da5Sopenharmony_ci "%dead_bool = OpConstantTrue %bool", 394fd4e5da5Sopenharmony_ci "%dead_float = OpConstant %float 2.5", 395fd4e5da5Sopenharmony_ci "%dead_struct = OpConstantComposite %flat_struct %dead_bool %used_int %dead_float %used_double", 396fd4e5da5Sopenharmony_ci }, 397fd4e5da5Sopenharmony_ci }, 398fd4e5da5Sopenharmony_ci // A nesting struct type dead constants. All components of both outer 399fd4e5da5Sopenharmony_ci // and inner structs are dead and should be removed after dead constant 400fd4e5da5Sopenharmony_ci // elimination. 401fd4e5da5Sopenharmony_ci { 402fd4e5da5Sopenharmony_ci /* .used_consts = */ {}, 403fd4e5da5Sopenharmony_ci /* .main_insts = */ {}, 404fd4e5da5Sopenharmony_ci /* .dead_consts = */ 405fd4e5da5Sopenharmony_ci { 406fd4e5da5Sopenharmony_ci "%dead_bool = OpConstantTrue %bool", 407fd4e5da5Sopenharmony_ci "%dead_int = OpConstant %int 1", 408fd4e5da5Sopenharmony_ci "%dead_float = OpConstant %float 2.5", 409fd4e5da5Sopenharmony_ci "%dead_double = OpConstant %double 3.1415926535", 410fd4e5da5Sopenharmony_ci "%dead_inner_struct = OpConstantComposite %inner_struct %dead_bool %dead_int %dead_float %dead_double", 411fd4e5da5Sopenharmony_ci "%dead_int2 = OpConstant %int 2", 412fd4e5da5Sopenharmony_ci "%dead_double2 = OpConstant %double 1.428571428514", 413fd4e5da5Sopenharmony_ci "%dead_outer_struct = OpConstantComposite %outer_struct %dead_inner_struct %dead_int2 %dead_double2", 414fd4e5da5Sopenharmony_ci }, 415fd4e5da5Sopenharmony_ci }, 416fd4e5da5Sopenharmony_ci // A nesting struct type dead constants. Some of its components are 417fd4e5da5Sopenharmony_ci // dead constants while others are not. 418fd4e5da5Sopenharmony_ci { 419fd4e5da5Sopenharmony_ci /* .used_consts = */ 420fd4e5da5Sopenharmony_ci { 421fd4e5da5Sopenharmony_ci "%used_int = OpConstant %int 1", 422fd4e5da5Sopenharmony_ci "%used_double = OpConstant %double 3.14159265358979", 423fd4e5da5Sopenharmony_ci }, 424fd4e5da5Sopenharmony_ci /* .main_insts = */ 425fd4e5da5Sopenharmony_ci { 426fd4e5da5Sopenharmony_ci "%int_var = OpVariable %_pf_int Function", 427fd4e5da5Sopenharmony_ci "OpStore %int_var %used_int", 428fd4e5da5Sopenharmony_ci "%double_var = OpVariable %_pf_double Function", 429fd4e5da5Sopenharmony_ci "OpStore %double_var %used_double", 430fd4e5da5Sopenharmony_ci }, 431fd4e5da5Sopenharmony_ci /* .dead_consts = */ 432fd4e5da5Sopenharmony_ci { 433fd4e5da5Sopenharmony_ci "%dead_bool = OpConstantTrue %bool", 434fd4e5da5Sopenharmony_ci "%dead_float = OpConstant %float 2.5", 435fd4e5da5Sopenharmony_ci "%dead_inner_struct = OpConstantComposite %inner_struct %dead_bool %used_int %dead_float %used_double", 436fd4e5da5Sopenharmony_ci "%dead_int = OpConstant %int 2", 437fd4e5da5Sopenharmony_ci "%dead_outer_struct = OpConstantComposite %outer_struct %dead_inner_struct %dead_int %used_double", 438fd4e5da5Sopenharmony_ci }, 439fd4e5da5Sopenharmony_ci }, 440fd4e5da5Sopenharmony_ci // A nesting struct case. The inner struct is used while the outer struct is not 441fd4e5da5Sopenharmony_ci { 442fd4e5da5Sopenharmony_ci /* .used_const = */ 443fd4e5da5Sopenharmony_ci { 444fd4e5da5Sopenharmony_ci "%used_bool = OpConstantTrue %bool", 445fd4e5da5Sopenharmony_ci "%used_int = OpConstant %int 1", 446fd4e5da5Sopenharmony_ci "%used_float = OpConstant %float 1.25", 447fd4e5da5Sopenharmony_ci "%used_double = OpConstant %double 1.23456789012345", 448fd4e5da5Sopenharmony_ci "%used_inner_struct = OpConstantComposite %inner_struct %used_bool %used_int %used_float %used_double", 449fd4e5da5Sopenharmony_ci }, 450fd4e5da5Sopenharmony_ci /* .main_insts = */ 451fd4e5da5Sopenharmony_ci { 452fd4e5da5Sopenharmony_ci "%bool_var = OpVariable %_pf_bool Function", 453fd4e5da5Sopenharmony_ci "%bool_from_inner_struct = OpCompositeExtract %bool %used_inner_struct 0", 454fd4e5da5Sopenharmony_ci "OpStore %bool_var %bool_from_inner_struct", 455fd4e5da5Sopenharmony_ci }, 456fd4e5da5Sopenharmony_ci /* .dead_consts = */ 457fd4e5da5Sopenharmony_ci { 458fd4e5da5Sopenharmony_ci "%dead_int = OpConstant %int 2", 459fd4e5da5Sopenharmony_ci "%dead_outer_struct = OpConstantComposite %outer_struct %used_inner_struct %dead_int %used_double" 460fd4e5da5Sopenharmony_ci }, 461fd4e5da5Sopenharmony_ci }, 462fd4e5da5Sopenharmony_ci // A nesting struct case. The outer struct is used, so the inner struct should not 463fd4e5da5Sopenharmony_ci // be removed even though it is not used anywhere. 464fd4e5da5Sopenharmony_ci { 465fd4e5da5Sopenharmony_ci /* .used_const = */ 466fd4e5da5Sopenharmony_ci { 467fd4e5da5Sopenharmony_ci "%used_bool = OpConstantTrue %bool", 468fd4e5da5Sopenharmony_ci "%used_int = OpConstant %int 1", 469fd4e5da5Sopenharmony_ci "%used_float = OpConstant %float 1.25", 470fd4e5da5Sopenharmony_ci "%used_double = OpConstant %double 1.23456789012345", 471fd4e5da5Sopenharmony_ci "%used_inner_struct = OpConstantComposite %inner_struct %used_bool %used_int %used_float %used_double", 472fd4e5da5Sopenharmony_ci "%used_outer_struct = OpConstantComposite %outer_struct %used_inner_struct %used_int %used_double" 473fd4e5da5Sopenharmony_ci }, 474fd4e5da5Sopenharmony_ci /* .main_insts = */ 475fd4e5da5Sopenharmony_ci { 476fd4e5da5Sopenharmony_ci "%int_var = OpVariable %_pf_int Function", 477fd4e5da5Sopenharmony_ci "%int_from_outer_struct = OpCompositeExtract %int %used_outer_struct 1", 478fd4e5da5Sopenharmony_ci "OpStore %int_var %int_from_outer_struct", 479fd4e5da5Sopenharmony_ci }, 480fd4e5da5Sopenharmony_ci /* .dead_consts = */ {}, 481fd4e5da5Sopenharmony_ci }, 482fd4e5da5Sopenharmony_ci // clang-format on 483fd4e5da5Sopenharmony_ci }))); 484fd4e5da5Sopenharmony_ci 485fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 486fd4e5da5Sopenharmony_ci ScalarTypeSpecConstants, EliminateDeadConstantTest, 487fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EliminateDeadConstantTestCase>({ 488fd4e5da5Sopenharmony_ci // clang-format off 489fd4e5da5Sopenharmony_ci // All scalar type spec constants. 490fd4e5da5Sopenharmony_ci { 491fd4e5da5Sopenharmony_ci /* .used_consts = */ 492fd4e5da5Sopenharmony_ci { 493fd4e5da5Sopenharmony_ci "%used_bool = OpSpecConstantTrue %bool", 494fd4e5da5Sopenharmony_ci "%used_uint = OpSpecConstant %uint 2", 495fd4e5da5Sopenharmony_ci "%used_int = OpSpecConstant %int 2", 496fd4e5da5Sopenharmony_ci "%used_float = OpSpecConstant %float 2.5", 497fd4e5da5Sopenharmony_ci "%used_double = OpSpecConstant %double 1.42857142851", 498fd4e5da5Sopenharmony_ci }, 499fd4e5da5Sopenharmony_ci /* .main_insts = */ 500fd4e5da5Sopenharmony_ci { 501fd4e5da5Sopenharmony_ci "%bool_var = OpVariable %_pf_bool Function", 502fd4e5da5Sopenharmony_ci "%uint_var = OpVariable %_pf_uint Function", 503fd4e5da5Sopenharmony_ci "%int_var = OpVariable %_pf_int Function", 504fd4e5da5Sopenharmony_ci "%float_var = OpVariable %_pf_float Function", 505fd4e5da5Sopenharmony_ci "%double_var = OpVariable %_pf_double Function", 506fd4e5da5Sopenharmony_ci "OpStore %bool_var %used_bool", "OpStore %uint_var %used_uint", 507fd4e5da5Sopenharmony_ci "OpStore %int_var %used_int", "OpStore %float_var %used_float", 508fd4e5da5Sopenharmony_ci "OpStore %double_var %used_double", 509fd4e5da5Sopenharmony_ci }, 510fd4e5da5Sopenharmony_ci /* .dead_consts = */ 511fd4e5da5Sopenharmony_ci { 512fd4e5da5Sopenharmony_ci "%dead_bool = OpSpecConstantTrue %bool", 513fd4e5da5Sopenharmony_ci "%dead_uint = OpSpecConstant %uint 2", 514fd4e5da5Sopenharmony_ci "%dead_int = OpSpecConstant %int 2", 515fd4e5da5Sopenharmony_ci "%dead_float = OpSpecConstant %float 2.5", 516fd4e5da5Sopenharmony_ci "%dead_double = OpSpecConstant %double 1.42857142851", 517fd4e5da5Sopenharmony_ci }, 518fd4e5da5Sopenharmony_ci }, 519fd4e5da5Sopenharmony_ci // clang-format on 520fd4e5da5Sopenharmony_ci }))); 521fd4e5da5Sopenharmony_ci 522fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 523fd4e5da5Sopenharmony_ci VectorTypeSpecConstants, EliminateDeadConstantTest, 524fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EliminateDeadConstantTestCase>({ 525fd4e5da5Sopenharmony_ci // clang-format off 526fd4e5da5Sopenharmony_ci // Bool vector type spec constants. One vector has all component dead, 527fd4e5da5Sopenharmony_ci // another vector has one dead boolean and one used boolean. 528fd4e5da5Sopenharmony_ci { 529fd4e5da5Sopenharmony_ci /* .used_consts = */ 530fd4e5da5Sopenharmony_ci { 531fd4e5da5Sopenharmony_ci "%used_bool = OpSpecConstantTrue %bool", 532fd4e5da5Sopenharmony_ci }, 533fd4e5da5Sopenharmony_ci /* .main_insts = */ 534fd4e5da5Sopenharmony_ci { 535fd4e5da5Sopenharmony_ci "%bool_var = OpVariable %_pf_bool Function", 536fd4e5da5Sopenharmony_ci "OpStore %bool_var %used_bool", 537fd4e5da5Sopenharmony_ci }, 538fd4e5da5Sopenharmony_ci /* .dead_consts = */ 539fd4e5da5Sopenharmony_ci { 540fd4e5da5Sopenharmony_ci "%dead_bool = OpSpecConstantFalse %bool", 541fd4e5da5Sopenharmony_ci "%dead_bool_vec1 = OpSpecConstantComposite %v2bool %dead_bool %dead_bool", 542fd4e5da5Sopenharmony_ci "%dead_bool_vec2 = OpSpecConstantComposite %v2bool %dead_bool %used_bool", 543fd4e5da5Sopenharmony_ci }, 544fd4e5da5Sopenharmony_ci }, 545fd4e5da5Sopenharmony_ci 546fd4e5da5Sopenharmony_ci // Uint vector type spec constants. One vector has all component dead, 547fd4e5da5Sopenharmony_ci // another vector has one dead unsigned integer and one used unsigned 548fd4e5da5Sopenharmony_ci // integer. 549fd4e5da5Sopenharmony_ci { 550fd4e5da5Sopenharmony_ci /* .used_consts = */ 551fd4e5da5Sopenharmony_ci { 552fd4e5da5Sopenharmony_ci "%used_uint = OpSpecConstant %uint 3", 553fd4e5da5Sopenharmony_ci }, 554fd4e5da5Sopenharmony_ci /* .main_insts = */ 555fd4e5da5Sopenharmony_ci { 556fd4e5da5Sopenharmony_ci "%uint_var = OpVariable %_pf_uint Function", 557fd4e5da5Sopenharmony_ci "OpStore %uint_var %used_uint", 558fd4e5da5Sopenharmony_ci }, 559fd4e5da5Sopenharmony_ci /* .dead_consts = */ 560fd4e5da5Sopenharmony_ci { 561fd4e5da5Sopenharmony_ci "%dead_uint = OpSpecConstant %uint 1", 562fd4e5da5Sopenharmony_ci "%dead_uint_vec1 = OpSpecConstantComposite %v2uint %dead_uint %dead_uint", 563fd4e5da5Sopenharmony_ci "%dead_uint_vec2 = OpSpecConstantComposite %v2uint %dead_uint %used_uint", 564fd4e5da5Sopenharmony_ci }, 565fd4e5da5Sopenharmony_ci }, 566fd4e5da5Sopenharmony_ci 567fd4e5da5Sopenharmony_ci // Int vector type spec constants. One vector has all component dead, 568fd4e5da5Sopenharmony_ci // another vector has one dead integer and one used integer. 569fd4e5da5Sopenharmony_ci { 570fd4e5da5Sopenharmony_ci /* .used_consts = */ 571fd4e5da5Sopenharmony_ci { 572fd4e5da5Sopenharmony_ci "%used_int = OpSpecConstant %int 3", 573fd4e5da5Sopenharmony_ci }, 574fd4e5da5Sopenharmony_ci /* .main_insts = */ 575fd4e5da5Sopenharmony_ci { 576fd4e5da5Sopenharmony_ci "%int_var = OpVariable %_pf_int Function", 577fd4e5da5Sopenharmony_ci "OpStore %int_var %used_int", 578fd4e5da5Sopenharmony_ci }, 579fd4e5da5Sopenharmony_ci /* .dead_consts = */ 580fd4e5da5Sopenharmony_ci { 581fd4e5da5Sopenharmony_ci "%dead_int = OpSpecConstant %int 1", 582fd4e5da5Sopenharmony_ci "%dead_int_vec1 = OpSpecConstantComposite %v2int %dead_int %dead_int", 583fd4e5da5Sopenharmony_ci "%dead_int_vec2 = OpSpecConstantComposite %v2int %dead_int %used_int", 584fd4e5da5Sopenharmony_ci }, 585fd4e5da5Sopenharmony_ci }, 586fd4e5da5Sopenharmony_ci 587fd4e5da5Sopenharmony_ci // Int vector type spec constants built with both spec constants and 588fd4e5da5Sopenharmony_ci // front-end constants. 589fd4e5da5Sopenharmony_ci { 590fd4e5da5Sopenharmony_ci /* .used_consts = */ 591fd4e5da5Sopenharmony_ci { 592fd4e5da5Sopenharmony_ci "%used_spec_int = OpSpecConstant %int 3", 593fd4e5da5Sopenharmony_ci "%used_front_end_int = OpConstant %int 3", 594fd4e5da5Sopenharmony_ci }, 595fd4e5da5Sopenharmony_ci /* .main_insts = */ 596fd4e5da5Sopenharmony_ci { 597fd4e5da5Sopenharmony_ci "%int_var1 = OpVariable %_pf_int Function", 598fd4e5da5Sopenharmony_ci "OpStore %int_var1 %used_spec_int", 599fd4e5da5Sopenharmony_ci "%int_var2 = OpVariable %_pf_int Function", 600fd4e5da5Sopenharmony_ci "OpStore %int_var2 %used_front_end_int", 601fd4e5da5Sopenharmony_ci }, 602fd4e5da5Sopenharmony_ci /* .dead_consts = */ 603fd4e5da5Sopenharmony_ci { 604fd4e5da5Sopenharmony_ci "%dead_spec_int = OpSpecConstant %int 1", 605fd4e5da5Sopenharmony_ci "%dead_front_end_int = OpConstant %int 1", 606fd4e5da5Sopenharmony_ci // Dead front-end and dead spec constants 607fd4e5da5Sopenharmony_ci "%dead_int_vec1 = OpSpecConstantComposite %v2int %dead_spec_int %dead_front_end_int", 608fd4e5da5Sopenharmony_ci // Used front-end and dead spec constants 609fd4e5da5Sopenharmony_ci "%dead_int_vec2 = OpSpecConstantComposite %v2int %dead_spec_int %used_front_end_int", 610fd4e5da5Sopenharmony_ci // Dead front-end and used spec constants 611fd4e5da5Sopenharmony_ci "%dead_int_vec3 = OpSpecConstantComposite %v2int %dead_front_end_int %used_spec_int", 612fd4e5da5Sopenharmony_ci }, 613fd4e5da5Sopenharmony_ci }, 614fd4e5da5Sopenharmony_ci // clang-format on 615fd4e5da5Sopenharmony_ci }))); 616fd4e5da5Sopenharmony_ci 617fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 618fd4e5da5Sopenharmony_ci SpecConstantOp, EliminateDeadConstantTest, 619fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EliminateDeadConstantTestCase>({ 620fd4e5da5Sopenharmony_ci // clang-format off 621fd4e5da5Sopenharmony_ci // Cast operations: uint <-> int <-> bool 622fd4e5da5Sopenharmony_ci { 623fd4e5da5Sopenharmony_ci /* .used_consts = */ {}, 624fd4e5da5Sopenharmony_ci /* .main_insts = */ {}, 625fd4e5da5Sopenharmony_ci /* .dead_consts = */ 626fd4e5da5Sopenharmony_ci { 627fd4e5da5Sopenharmony_ci // Assistant constants, only used in dead spec constant 628fd4e5da5Sopenharmony_ci // operations. 629fd4e5da5Sopenharmony_ci "%signed_zero = OpConstant %int 0", 630fd4e5da5Sopenharmony_ci "%signed_zero_vec = OpConstantComposite %v2int %signed_zero %signed_zero", 631fd4e5da5Sopenharmony_ci "%unsigned_zero = OpConstant %uint 0", 632fd4e5da5Sopenharmony_ci "%unsigned_zero_vec = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero", 633fd4e5da5Sopenharmony_ci "%signed_one = OpConstant %int 1", 634fd4e5da5Sopenharmony_ci "%signed_one_vec = OpConstantComposite %v2int %signed_one %signed_one", 635fd4e5da5Sopenharmony_ci "%unsigned_one = OpConstant %uint 1", 636fd4e5da5Sopenharmony_ci "%unsigned_one_vec = OpConstantComposite %v2uint %unsigned_one %unsigned_one", 637fd4e5da5Sopenharmony_ci 638fd4e5da5Sopenharmony_ci // Spec constants that support casting to each other. 639fd4e5da5Sopenharmony_ci "%dead_bool = OpSpecConstantTrue %bool", 640fd4e5da5Sopenharmony_ci "%dead_uint = OpSpecConstant %uint 1", 641fd4e5da5Sopenharmony_ci "%dead_int = OpSpecConstant %int 2", 642fd4e5da5Sopenharmony_ci "%dead_bool_vec = OpSpecConstantComposite %v2bool %dead_bool %dead_bool", 643fd4e5da5Sopenharmony_ci "%dead_uint_vec = OpSpecConstantComposite %v2uint %dead_uint %dead_uint", 644fd4e5da5Sopenharmony_ci "%dead_int_vec = OpSpecConstantComposite %v2int %dead_int %dead_int", 645fd4e5da5Sopenharmony_ci 646fd4e5da5Sopenharmony_ci // Scalar cast to boolean spec constant. 647fd4e5da5Sopenharmony_ci "%int_to_bool = OpSpecConstantOp %bool INotEqual %dead_int %signed_zero", 648fd4e5da5Sopenharmony_ci "%uint_to_bool = OpSpecConstantOp %bool INotEqual %dead_uint %unsigned_zero", 649fd4e5da5Sopenharmony_ci 650fd4e5da5Sopenharmony_ci // Vector cast to boolean spec constant. 651fd4e5da5Sopenharmony_ci "%int_to_bool_vec = OpSpecConstantOp %v2bool INotEqual %dead_int_vec %signed_zero_vec", 652fd4e5da5Sopenharmony_ci "%uint_to_bool_vec = OpSpecConstantOp %v2bool INotEqual %dead_uint_vec %unsigned_zero_vec", 653fd4e5da5Sopenharmony_ci 654fd4e5da5Sopenharmony_ci // Scalar cast to int spec constant. 655fd4e5da5Sopenharmony_ci "%bool_to_int = OpSpecConstantOp %int Select %dead_bool %signed_one %signed_zero", 656fd4e5da5Sopenharmony_ci "%uint_to_int = OpSpecConstantOp %uint IAdd %dead_uint %unsigned_zero", 657fd4e5da5Sopenharmony_ci 658fd4e5da5Sopenharmony_ci // Vector cast to int spec constant. 659fd4e5da5Sopenharmony_ci "%bool_to_int_vec = OpSpecConstantOp %v2int Select %dead_bool_vec %signed_one_vec %signed_zero_vec", 660fd4e5da5Sopenharmony_ci "%uint_to_int_vec = OpSpecConstantOp %v2uint IAdd %dead_uint_vec %unsigned_zero_vec", 661fd4e5da5Sopenharmony_ci 662fd4e5da5Sopenharmony_ci // Scalar cast to uint spec constant. 663fd4e5da5Sopenharmony_ci "%bool_to_uint = OpSpecConstantOp %uint Select %dead_bool %unsigned_one %unsigned_zero", 664fd4e5da5Sopenharmony_ci "%int_to_uint_vec = OpSpecConstantOp %uint IAdd %dead_int %signed_zero", 665fd4e5da5Sopenharmony_ci 666fd4e5da5Sopenharmony_ci // Vector cast to uint spec constant. 667fd4e5da5Sopenharmony_ci "%bool_to_uint_vec = OpSpecConstantOp %v2uint Select %dead_bool_vec %unsigned_one_vec %unsigned_zero_vec", 668fd4e5da5Sopenharmony_ci "%int_to_uint = OpSpecConstantOp %v2uint IAdd %dead_int_vec %signed_zero_vec", 669fd4e5da5Sopenharmony_ci }, 670fd4e5da5Sopenharmony_ci }, 671fd4e5da5Sopenharmony_ci 672fd4e5da5Sopenharmony_ci // Add, sub, mul, div, rem. 673fd4e5da5Sopenharmony_ci { 674fd4e5da5Sopenharmony_ci /* .used_consts = */ {}, 675fd4e5da5Sopenharmony_ci /* .main_insts = */ {}, 676fd4e5da5Sopenharmony_ci /* .dead_consts = */ 677fd4e5da5Sopenharmony_ci { 678fd4e5da5Sopenharmony_ci "%dead_spec_int_a = OpSpecConstant %int 1", 679fd4e5da5Sopenharmony_ci "%dead_spec_int_a_vec = OpSpecConstantComposite %v2int %dead_spec_int_a %dead_spec_int_a", 680fd4e5da5Sopenharmony_ci 681fd4e5da5Sopenharmony_ci "%dead_spec_int_b = OpSpecConstant %int 2", 682fd4e5da5Sopenharmony_ci "%dead_spec_int_b_vec = OpSpecConstantComposite %v2int %dead_spec_int_b %dead_spec_int_b", 683fd4e5da5Sopenharmony_ci 684fd4e5da5Sopenharmony_ci "%dead_const_int_c = OpConstant %int 3", 685fd4e5da5Sopenharmony_ci "%dead_const_int_c_vec = OpConstantComposite %v2int %dead_const_int_c %dead_const_int_c", 686fd4e5da5Sopenharmony_ci 687fd4e5da5Sopenharmony_ci // Add 688fd4e5da5Sopenharmony_ci "%add_a_b = OpSpecConstantOp %int IAdd %dead_spec_int_a %dead_spec_int_b", 689fd4e5da5Sopenharmony_ci "%add_a_b_vec = OpSpecConstantOp %v2int IAdd %dead_spec_int_a_vec %dead_spec_int_b_vec", 690fd4e5da5Sopenharmony_ci 691fd4e5da5Sopenharmony_ci // Sub 692fd4e5da5Sopenharmony_ci "%sub_a_b = OpSpecConstantOp %int ISub %dead_spec_int_a %dead_spec_int_b", 693fd4e5da5Sopenharmony_ci "%sub_a_b_vec = OpSpecConstantOp %v2int ISub %dead_spec_int_a_vec %dead_spec_int_b_vec", 694fd4e5da5Sopenharmony_ci 695fd4e5da5Sopenharmony_ci // Mul 696fd4e5da5Sopenharmony_ci "%mul_a_b = OpSpecConstantOp %int IMul %dead_spec_int_a %dead_spec_int_b", 697fd4e5da5Sopenharmony_ci "%mul_a_b_vec = OpSpecConstantOp %v2int IMul %dead_spec_int_a_vec %dead_spec_int_b_vec", 698fd4e5da5Sopenharmony_ci 699fd4e5da5Sopenharmony_ci // Div 700fd4e5da5Sopenharmony_ci "%div_a_b = OpSpecConstantOp %int SDiv %dead_spec_int_a %dead_spec_int_b", 701fd4e5da5Sopenharmony_ci "%div_a_b_vec = OpSpecConstantOp %v2int SDiv %dead_spec_int_a_vec %dead_spec_int_b_vec", 702fd4e5da5Sopenharmony_ci 703fd4e5da5Sopenharmony_ci // Bitwise Xor 704fd4e5da5Sopenharmony_ci "%xor_a_b = OpSpecConstantOp %int BitwiseXor %dead_spec_int_a %dead_spec_int_b", 705fd4e5da5Sopenharmony_ci "%xor_a_b_vec = OpSpecConstantOp %v2int BitwiseXor %dead_spec_int_a_vec %dead_spec_int_b_vec", 706fd4e5da5Sopenharmony_ci 707fd4e5da5Sopenharmony_ci // Scalar Comparison 708fd4e5da5Sopenharmony_ci "%less_a_b = OpSpecConstantOp %bool SLessThan %dead_spec_int_a %dead_spec_int_b", 709fd4e5da5Sopenharmony_ci }, 710fd4e5da5Sopenharmony_ci }, 711fd4e5da5Sopenharmony_ci 712fd4e5da5Sopenharmony_ci // Vectors without used swizzles should be removed. 713fd4e5da5Sopenharmony_ci { 714fd4e5da5Sopenharmony_ci /* .used_consts = */ 715fd4e5da5Sopenharmony_ci { 716fd4e5da5Sopenharmony_ci "%used_int = OpConstant %int 3", 717fd4e5da5Sopenharmony_ci }, 718fd4e5da5Sopenharmony_ci /* .main_insts = */ 719fd4e5da5Sopenharmony_ci { 720fd4e5da5Sopenharmony_ci "%int_var = OpVariable %_pf_int Function", 721fd4e5da5Sopenharmony_ci "OpStore %int_var %used_int", 722fd4e5da5Sopenharmony_ci }, 723fd4e5da5Sopenharmony_ci /* .dead_consts = */ 724fd4e5da5Sopenharmony_ci { 725fd4e5da5Sopenharmony_ci "%dead_int = OpConstant %int 3", 726fd4e5da5Sopenharmony_ci 727fd4e5da5Sopenharmony_ci "%dead_spec_int_a = OpSpecConstant %int 1", 728fd4e5da5Sopenharmony_ci "%vec_a = OpSpecConstantComposite %v4int %dead_spec_int_a %dead_spec_int_a %dead_int %dead_int", 729fd4e5da5Sopenharmony_ci 730fd4e5da5Sopenharmony_ci "%dead_spec_int_b = OpSpecConstant %int 2", 731fd4e5da5Sopenharmony_ci "%vec_b = OpSpecConstantComposite %v4int %dead_spec_int_b %dead_spec_int_b %used_int %used_int", 732fd4e5da5Sopenharmony_ci 733fd4e5da5Sopenharmony_ci // Extract scalar 734fd4e5da5Sopenharmony_ci "%a_x = OpSpecConstantOp %int CompositeExtract %vec_a 0", 735fd4e5da5Sopenharmony_ci "%b_x = OpSpecConstantOp %int CompositeExtract %vec_b 0", 736fd4e5da5Sopenharmony_ci 737fd4e5da5Sopenharmony_ci // Extract vector 738fd4e5da5Sopenharmony_ci "%a_xy = OpSpecConstantOp %v2int VectorShuffle %vec_a %vec_a 0 1", 739fd4e5da5Sopenharmony_ci "%b_xy = OpSpecConstantOp %v2int VectorShuffle %vec_b %vec_b 0 1", 740fd4e5da5Sopenharmony_ci }, 741fd4e5da5Sopenharmony_ci }, 742fd4e5da5Sopenharmony_ci // Vectors with used swizzles should not be removed. 743fd4e5da5Sopenharmony_ci { 744fd4e5da5Sopenharmony_ci /* .used_consts = */ 745fd4e5da5Sopenharmony_ci { 746fd4e5da5Sopenharmony_ci "%used_int = OpConstant %int 3", 747fd4e5da5Sopenharmony_ci "%used_spec_int_a = OpSpecConstant %int 1", 748fd4e5da5Sopenharmony_ci "%used_spec_int_b = OpSpecConstant %int 2", 749fd4e5da5Sopenharmony_ci // Create vectors 750fd4e5da5Sopenharmony_ci "%vec_a = OpSpecConstantComposite %v4int %used_spec_int_a %used_spec_int_a %used_int %used_int", 751fd4e5da5Sopenharmony_ci "%vec_b = OpSpecConstantComposite %v4int %used_spec_int_b %used_spec_int_b %used_int %used_int", 752fd4e5da5Sopenharmony_ci // Extract vector 753fd4e5da5Sopenharmony_ci "%a_xy = OpSpecConstantOp %v2int VectorShuffle %vec_a %vec_a 0 1", 754fd4e5da5Sopenharmony_ci "%b_xy = OpSpecConstantOp %v2int VectorShuffle %vec_b %vec_b 0 1", 755fd4e5da5Sopenharmony_ci }, 756fd4e5da5Sopenharmony_ci /* .main_insts = */ 757fd4e5da5Sopenharmony_ci { 758fd4e5da5Sopenharmony_ci "%v2int_var_a = OpVariable %_pf_v2int Function", 759fd4e5da5Sopenharmony_ci "%v2int_var_b = OpVariable %_pf_v2int Function", 760fd4e5da5Sopenharmony_ci "OpStore %v2int_var_a %a_xy", 761fd4e5da5Sopenharmony_ci "OpStore %v2int_var_b %b_xy", 762fd4e5da5Sopenharmony_ci }, 763fd4e5da5Sopenharmony_ci /* .dead_consts = */ {}, 764fd4e5da5Sopenharmony_ci }, 765fd4e5da5Sopenharmony_ci // clang-format on 766fd4e5da5Sopenharmony_ci }))); 767fd4e5da5Sopenharmony_ci 768fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 769fd4e5da5Sopenharmony_ci LongDefUseChain, EliminateDeadConstantTest, 770fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EliminateDeadConstantTestCase>({ 771fd4e5da5Sopenharmony_ci // clang-format off 772fd4e5da5Sopenharmony_ci // Long Def-Use chain with binary operations. 773fd4e5da5Sopenharmony_ci { 774fd4e5da5Sopenharmony_ci /* .used_consts = */ 775fd4e5da5Sopenharmony_ci { 776fd4e5da5Sopenharmony_ci "%array_size = OpConstant %int 4", 777fd4e5da5Sopenharmony_ci "%type_arr_int_4 = OpTypeArray %int %array_size", 778fd4e5da5Sopenharmony_ci "%used_int_0 = OpConstant %int 100", 779fd4e5da5Sopenharmony_ci "%used_int_1 = OpConstant %int 1", 780fd4e5da5Sopenharmony_ci "%used_int_2 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_1", 781fd4e5da5Sopenharmony_ci "%used_int_3 = OpSpecConstantOp %int ISub %used_int_0 %used_int_2", 782fd4e5da5Sopenharmony_ci "%used_int_4 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_3", 783fd4e5da5Sopenharmony_ci "%used_int_5 = OpSpecConstantOp %int ISub %used_int_0 %used_int_4", 784fd4e5da5Sopenharmony_ci "%used_int_6 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_5", 785fd4e5da5Sopenharmony_ci "%used_int_7 = OpSpecConstantOp %int ISub %used_int_0 %used_int_6", 786fd4e5da5Sopenharmony_ci "%used_int_8 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_7", 787fd4e5da5Sopenharmony_ci "%used_int_9 = OpSpecConstantOp %int ISub %used_int_0 %used_int_8", 788fd4e5da5Sopenharmony_ci "%used_int_10 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_9", 789fd4e5da5Sopenharmony_ci "%used_int_11 = OpSpecConstantOp %int ISub %used_int_0 %used_int_10", 790fd4e5da5Sopenharmony_ci "%used_int_12 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_11", 791fd4e5da5Sopenharmony_ci "%used_int_13 = OpSpecConstantOp %int ISub %used_int_0 %used_int_12", 792fd4e5da5Sopenharmony_ci "%used_int_14 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_13", 793fd4e5da5Sopenharmony_ci "%used_int_15 = OpSpecConstantOp %int ISub %used_int_0 %used_int_14", 794fd4e5da5Sopenharmony_ci "%used_int_16 = OpSpecConstantOp %int ISub %used_int_0 %used_int_15", 795fd4e5da5Sopenharmony_ci "%used_int_17 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_16", 796fd4e5da5Sopenharmony_ci "%used_int_18 = OpSpecConstantOp %int ISub %used_int_0 %used_int_17", 797fd4e5da5Sopenharmony_ci "%used_int_19 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_18", 798fd4e5da5Sopenharmony_ci "%used_int_20 = OpSpecConstantOp %int ISub %used_int_0 %used_int_19", 799fd4e5da5Sopenharmony_ci "%used_vec_a = OpSpecConstantComposite %v2int %used_int_18 %used_int_19", 800fd4e5da5Sopenharmony_ci "%used_vec_b = OpSpecConstantOp %v2int IMul %used_vec_a %used_vec_a", 801fd4e5da5Sopenharmony_ci "%used_int_21 = OpSpecConstantOp %int CompositeExtract %used_vec_b 0", 802fd4e5da5Sopenharmony_ci "%used_array = OpConstantComposite %type_arr_int_4 %used_int_20 %used_int_20 %used_int_21 %used_int_21", 803fd4e5da5Sopenharmony_ci }, 804fd4e5da5Sopenharmony_ci /* .main_insts = */ 805fd4e5da5Sopenharmony_ci { 806fd4e5da5Sopenharmony_ci "%int_var = OpVariable %_pf_int Function", 807fd4e5da5Sopenharmony_ci "%used_array_2 = OpCompositeExtract %int %used_array 2", 808fd4e5da5Sopenharmony_ci "OpStore %int_var %used_array_2", 809fd4e5da5Sopenharmony_ci }, 810fd4e5da5Sopenharmony_ci /* .dead_consts = */ 811fd4e5da5Sopenharmony_ci { 812fd4e5da5Sopenharmony_ci "%dead_int_1 = OpConstant %int 2", 813fd4e5da5Sopenharmony_ci "%dead_int_2 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_1", 814fd4e5da5Sopenharmony_ci "%dead_int_3 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_2", 815fd4e5da5Sopenharmony_ci "%dead_int_4 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_3", 816fd4e5da5Sopenharmony_ci "%dead_int_5 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_4", 817fd4e5da5Sopenharmony_ci "%dead_int_6 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_5", 818fd4e5da5Sopenharmony_ci "%dead_int_7 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_6", 819fd4e5da5Sopenharmony_ci "%dead_int_8 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_7", 820fd4e5da5Sopenharmony_ci "%dead_int_9 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_8", 821fd4e5da5Sopenharmony_ci "%dead_int_10 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_9", 822fd4e5da5Sopenharmony_ci "%dead_int_11 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_10", 823fd4e5da5Sopenharmony_ci "%dead_int_12 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_11", 824fd4e5da5Sopenharmony_ci "%dead_int_13 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_12", 825fd4e5da5Sopenharmony_ci "%dead_int_14 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_13", 826fd4e5da5Sopenharmony_ci "%dead_int_15 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_14", 827fd4e5da5Sopenharmony_ci "%dead_int_16 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_15", 828fd4e5da5Sopenharmony_ci "%dead_int_17 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_16", 829fd4e5da5Sopenharmony_ci "%dead_int_18 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_17", 830fd4e5da5Sopenharmony_ci "%dead_int_19 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_18", 831fd4e5da5Sopenharmony_ci "%dead_int_20 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_19", 832fd4e5da5Sopenharmony_ci "%dead_vec_a = OpSpecConstantComposite %v2int %dead_int_18 %dead_int_19", 833fd4e5da5Sopenharmony_ci "%dead_vec_b = OpSpecConstantOp %v2int IMul %dead_vec_a %dead_vec_a", 834fd4e5da5Sopenharmony_ci "%dead_int_21 = OpSpecConstantOp %int CompositeExtract %dead_vec_b 0", 835fd4e5da5Sopenharmony_ci "%dead_array = OpConstantComposite %type_arr_int_4 %dead_int_20 %used_int_20 %dead_int_19 %used_int_19", 836fd4e5da5Sopenharmony_ci }, 837fd4e5da5Sopenharmony_ci }, 838fd4e5da5Sopenharmony_ci // Long Def-Use chain with swizzle 839fd4e5da5Sopenharmony_ci // clang-format on 840fd4e5da5Sopenharmony_ci }))); 841fd4e5da5Sopenharmony_ci 842fd4e5da5Sopenharmony_ci} // namespace 843fd4e5da5Sopenharmony_ci} // namespace opt 844fd4e5da5Sopenharmony_ci} // namespace spvtools 845