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 "gmock/gmock.h" 18fd4e5da5Sopenharmony_ci#include "source/opt/build_module.h" 19fd4e5da5Sopenharmony_ci#include "source/opt/value_number_table.h" 20fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 21fd4e5da5Sopenharmony_ci 22fd4e5da5Sopenharmony_cinamespace spvtools { 23fd4e5da5Sopenharmony_cinamespace opt { 24fd4e5da5Sopenharmony_cinamespace { 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 27fd4e5da5Sopenharmony_ciusing ::testing::MatchesRegex; 28fd4e5da5Sopenharmony_ciusing ValueTableTest = PassTest<::testing::Test>; 29fd4e5da5Sopenharmony_ci 30fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, SameInstructionSameValue) { 31fd4e5da5Sopenharmony_ci const std::string text = R"( 32fd4e5da5Sopenharmony_ci OpCapability Shader 33fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 34fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 35fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 36fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 37fd4e5da5Sopenharmony_ci OpSource GLSL 430 38fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 39fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 40fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 41fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 42fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 43fd4e5da5Sopenharmony_ci %7 = OpLabel 44fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Function 45fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 46fd4e5da5Sopenharmony_ci %10 = OpFAdd %5 %9 %9 47fd4e5da5Sopenharmony_ci OpReturn 48fd4e5da5Sopenharmony_ci OpFunctionEnd 49fd4e5da5Sopenharmony_ci )"; 50fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 51fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 52fd4e5da5Sopenharmony_ci Instruction* inst = context->get_def_use_mgr()->GetDef(10); 53fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst), vtable.GetValueNumber(inst)); 54fd4e5da5Sopenharmony_ci} 55fd4e5da5Sopenharmony_ci 56fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentInstructionSameValue) { 57fd4e5da5Sopenharmony_ci const std::string text = R"( 58fd4e5da5Sopenharmony_ci OpCapability Shader 59fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 60fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 61fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 62fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 63fd4e5da5Sopenharmony_ci OpSource GLSL 430 64fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 65fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 66fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 67fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 68fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 69fd4e5da5Sopenharmony_ci %7 = OpLabel 70fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Function 71fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 72fd4e5da5Sopenharmony_ci %10 = OpFAdd %5 %9 %9 73fd4e5da5Sopenharmony_ci %11 = OpFAdd %5 %9 %9 74fd4e5da5Sopenharmony_ci OpReturn 75fd4e5da5Sopenharmony_ci OpFunctionEnd 76fd4e5da5Sopenharmony_ci )"; 77fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 78fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 79fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(10); 80fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(11); 81fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 82fd4e5da5Sopenharmony_ci} 83fd4e5da5Sopenharmony_ci 84fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, SameValueDifferentBlock) { 85fd4e5da5Sopenharmony_ci const std::string text = R"( 86fd4e5da5Sopenharmony_ci OpCapability Shader 87fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 88fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 89fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 90fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 91fd4e5da5Sopenharmony_ci OpSource GLSL 430 92fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 93fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 94fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 95fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 96fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 97fd4e5da5Sopenharmony_ci %7 = OpLabel 98fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Function 99fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 100fd4e5da5Sopenharmony_ci %10 = OpFAdd %5 %9 %9 101fd4e5da5Sopenharmony_ci OpBranch %11 102fd4e5da5Sopenharmony_ci %11 = OpLabel 103fd4e5da5Sopenharmony_ci %12 = OpFAdd %5 %9 %9 104fd4e5da5Sopenharmony_ci OpReturn 105fd4e5da5Sopenharmony_ci OpFunctionEnd 106fd4e5da5Sopenharmony_ci )"; 107fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 108fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 109fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(10); 110fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(12); 111fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 112fd4e5da5Sopenharmony_ci} 113fd4e5da5Sopenharmony_ci 114fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentValue) { 115fd4e5da5Sopenharmony_ci const std::string text = R"( 116fd4e5da5Sopenharmony_ci OpCapability Shader 117fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 118fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 119fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 120fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 121fd4e5da5Sopenharmony_ci OpSource GLSL 430 122fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 123fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 124fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 125fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 126fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 127fd4e5da5Sopenharmony_ci %7 = OpLabel 128fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Function 129fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 130fd4e5da5Sopenharmony_ci %10 = OpFAdd %5 %9 %9 131fd4e5da5Sopenharmony_ci %11 = OpFAdd %5 %9 %10 132fd4e5da5Sopenharmony_ci OpReturn 133fd4e5da5Sopenharmony_ci OpFunctionEnd 134fd4e5da5Sopenharmony_ci )"; 135fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 136fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 137fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(10); 138fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(11); 139fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 140fd4e5da5Sopenharmony_ci} 141fd4e5da5Sopenharmony_ci 142fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentValueDifferentBlock) { 143fd4e5da5Sopenharmony_ci const std::string text = R"( 144fd4e5da5Sopenharmony_ci OpCapability Shader 145fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 146fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 147fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 148fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 149fd4e5da5Sopenharmony_ci OpSource GLSL 430 150fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 151fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 152fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 153fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 154fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 155fd4e5da5Sopenharmony_ci %7 = OpLabel 156fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Function 157fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 158fd4e5da5Sopenharmony_ci %10 = OpFAdd %5 %9 %9 159fd4e5da5Sopenharmony_ci OpBranch %11 160fd4e5da5Sopenharmony_ci %11 = OpLabel 161fd4e5da5Sopenharmony_ci %12 = OpFAdd %5 %9 %10 162fd4e5da5Sopenharmony_ci OpReturn 163fd4e5da5Sopenharmony_ci OpFunctionEnd 164fd4e5da5Sopenharmony_ci )"; 165fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 166fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 167fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(10); 168fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(12); 169fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 170fd4e5da5Sopenharmony_ci} 171fd4e5da5Sopenharmony_ci 172fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, SameLoad) { 173fd4e5da5Sopenharmony_ci const std::string text = R"( 174fd4e5da5Sopenharmony_ci OpCapability Shader 175fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 176fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 177fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 178fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 179fd4e5da5Sopenharmony_ci OpSource GLSL 430 180fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 181fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 182fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 183fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 184fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 185fd4e5da5Sopenharmony_ci %7 = OpLabel 186fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Function 187fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 188fd4e5da5Sopenharmony_ci OpReturn 189fd4e5da5Sopenharmony_ci OpFunctionEnd 190fd4e5da5Sopenharmony_ci )"; 191fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 192fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 193fd4e5da5Sopenharmony_ci Instruction* inst = context->get_def_use_mgr()->GetDef(9); 194fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst), vtable.GetValueNumber(inst)); 195fd4e5da5Sopenharmony_ci} 196fd4e5da5Sopenharmony_ci 197fd4e5da5Sopenharmony_ci// Two different loads, even from the same memory, must given different value 198fd4e5da5Sopenharmony_ci// numbers if the memory is not read-only. 199fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentFunctionLoad) { 200fd4e5da5Sopenharmony_ci const std::string text = R"( 201fd4e5da5Sopenharmony_ci OpCapability Shader 202fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 203fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 204fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 205fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 206fd4e5da5Sopenharmony_ci OpSource GLSL 430 207fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 208fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 209fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 210fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 211fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 212fd4e5da5Sopenharmony_ci %7 = OpLabel 213fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Function 214fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 215fd4e5da5Sopenharmony_ci %10 = OpLoad %5 %8 216fd4e5da5Sopenharmony_ci OpReturn 217fd4e5da5Sopenharmony_ci OpFunctionEnd 218fd4e5da5Sopenharmony_ci )"; 219fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 220fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 221fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(9); 222fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(10); 223fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 224fd4e5da5Sopenharmony_ci} 225fd4e5da5Sopenharmony_ci 226fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentUniformLoad) { 227fd4e5da5Sopenharmony_ci const std::string text = R"( 228fd4e5da5Sopenharmony_ci OpCapability Shader 229fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 230fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 231fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 232fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 233fd4e5da5Sopenharmony_ci OpSource GLSL 430 234fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 235fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 236fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 237fd4e5da5Sopenharmony_ci %6 = OpTypePointer Uniform %5 238fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Uniform 239fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 240fd4e5da5Sopenharmony_ci %7 = OpLabel 241fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 242fd4e5da5Sopenharmony_ci %10 = OpLoad %5 %8 243fd4e5da5Sopenharmony_ci OpReturn 244fd4e5da5Sopenharmony_ci OpFunctionEnd 245fd4e5da5Sopenharmony_ci )"; 246fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 247fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 248fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(9); 249fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(10); 250fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 251fd4e5da5Sopenharmony_ci} 252fd4e5da5Sopenharmony_ci 253fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentInputLoad) { 254fd4e5da5Sopenharmony_ci const std::string text = R"( 255fd4e5da5Sopenharmony_ci OpCapability Shader 256fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 257fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 258fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 259fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 260fd4e5da5Sopenharmony_ci OpSource GLSL 430 261fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 262fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 263fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 264fd4e5da5Sopenharmony_ci %6 = OpTypePointer Input %5 265fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Input 266fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 267fd4e5da5Sopenharmony_ci %7 = OpLabel 268fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 269fd4e5da5Sopenharmony_ci %10 = OpLoad %5 %8 270fd4e5da5Sopenharmony_ci OpReturn 271fd4e5da5Sopenharmony_ci OpFunctionEnd 272fd4e5da5Sopenharmony_ci )"; 273fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 274fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 275fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(9); 276fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(10); 277fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 278fd4e5da5Sopenharmony_ci} 279fd4e5da5Sopenharmony_ci 280fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentUniformConstantLoad) { 281fd4e5da5Sopenharmony_ci const std::string text = R"( 282fd4e5da5Sopenharmony_ci OpCapability Shader 283fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 284fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 285fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 286fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 287fd4e5da5Sopenharmony_ci OpSource GLSL 430 288fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 289fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 290fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 291fd4e5da5Sopenharmony_ci %6 = OpTypePointer UniformConstant %5 292fd4e5da5Sopenharmony_ci %8 = OpVariable %6 UniformConstant 293fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 294fd4e5da5Sopenharmony_ci %7 = OpLabel 295fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 296fd4e5da5Sopenharmony_ci %10 = OpLoad %5 %8 297fd4e5da5Sopenharmony_ci OpReturn 298fd4e5da5Sopenharmony_ci OpFunctionEnd 299fd4e5da5Sopenharmony_ci )"; 300fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 301fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 302fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(9); 303fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(10); 304fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 305fd4e5da5Sopenharmony_ci} 306fd4e5da5Sopenharmony_ci 307fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentPushConstantLoad) { 308fd4e5da5Sopenharmony_ci const std::string text = R"( 309fd4e5da5Sopenharmony_ci OpCapability Shader 310fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 311fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 312fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 313fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 314fd4e5da5Sopenharmony_ci OpSource GLSL 430 315fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 316fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 317fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 318fd4e5da5Sopenharmony_ci %6 = OpTypePointer PushConstant %5 319fd4e5da5Sopenharmony_ci %8 = OpVariable %6 PushConstant 320fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 321fd4e5da5Sopenharmony_ci %7 = OpLabel 322fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 323fd4e5da5Sopenharmony_ci %10 = OpLoad %5 %8 324fd4e5da5Sopenharmony_ci OpReturn 325fd4e5da5Sopenharmony_ci OpFunctionEnd 326fd4e5da5Sopenharmony_ci )"; 327fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 328fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 329fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(9); 330fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(10); 331fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 332fd4e5da5Sopenharmony_ci} 333fd4e5da5Sopenharmony_ci 334fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, SameCall) { 335fd4e5da5Sopenharmony_ci const std::string text = R"( 336fd4e5da5Sopenharmony_ci OpCapability Shader 337fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 338fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 339fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 340fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 341fd4e5da5Sopenharmony_ci OpSource GLSL 430 342fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 343fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 344fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 345fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %5 346fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %5 347fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Private 348fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 349fd4e5da5Sopenharmony_ci %9 = OpLabel 350fd4e5da5Sopenharmony_ci %10 = OpFunctionCall %5 %11 351fd4e5da5Sopenharmony_ci OpReturn 352fd4e5da5Sopenharmony_ci OpFunctionEnd 353fd4e5da5Sopenharmony_ci %11 = OpFunction %5 None %6 354fd4e5da5Sopenharmony_ci %12 = OpLabel 355fd4e5da5Sopenharmony_ci %13 = OpLoad %5 %8 356fd4e5da5Sopenharmony_ci OpReturnValue %13 357fd4e5da5Sopenharmony_ci OpFunctionEnd 358fd4e5da5Sopenharmony_ci )"; 359fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 360fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 361fd4e5da5Sopenharmony_ci Instruction* inst = context->get_def_use_mgr()->GetDef(10); 362fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst), vtable.GetValueNumber(inst)); 363fd4e5da5Sopenharmony_ci} 364fd4e5da5Sopenharmony_ci 365fd4e5da5Sopenharmony_ci// Function calls should be given a new value number, even if they are the same. 366fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentCall) { 367fd4e5da5Sopenharmony_ci const std::string text = R"( 368fd4e5da5Sopenharmony_ci OpCapability Shader 369fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 370fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 371fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 372fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 373fd4e5da5Sopenharmony_ci OpSource GLSL 430 374fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 375fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 376fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 377fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %5 378fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %5 379fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Private 380fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 381fd4e5da5Sopenharmony_ci %9 = OpLabel 382fd4e5da5Sopenharmony_ci %10 = OpFunctionCall %5 %11 383fd4e5da5Sopenharmony_ci %12 = OpFunctionCall %5 %11 384fd4e5da5Sopenharmony_ci OpReturn 385fd4e5da5Sopenharmony_ci OpFunctionEnd 386fd4e5da5Sopenharmony_ci %11 = OpFunction %5 None %6 387fd4e5da5Sopenharmony_ci %13 = OpLabel 388fd4e5da5Sopenharmony_ci %14 = OpLoad %5 %8 389fd4e5da5Sopenharmony_ci OpReturnValue %14 390fd4e5da5Sopenharmony_ci OpFunctionEnd 391fd4e5da5Sopenharmony_ci )"; 392fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 393fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 394fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(10); 395fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(12); 396fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 397fd4e5da5Sopenharmony_ci} 398fd4e5da5Sopenharmony_ci 399fd4e5da5Sopenharmony_ci// It is possible to have two instruction that compute the same numerical value, 400fd4e5da5Sopenharmony_ci// but with different types. They should have different value numbers. 401fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentTypes) { 402fd4e5da5Sopenharmony_ci const std::string text = R"( 403fd4e5da5Sopenharmony_ci OpCapability Shader 404fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 405fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 406fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 407fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 408fd4e5da5Sopenharmony_ci OpSource GLSL 430 409fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 410fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 411fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 0 412fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 413fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %5 414fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 415fd4e5da5Sopenharmony_ci %8 = OpLabel 416fd4e5da5Sopenharmony_ci %9 = OpVariable %7 Function 417fd4e5da5Sopenharmony_ci %10 = OpLoad %5 %9 418fd4e5da5Sopenharmony_ci %11 = OpIAdd %5 %10 %10 419fd4e5da5Sopenharmony_ci %12 = OpIAdd %6 %10 %10 420fd4e5da5Sopenharmony_ci OpReturn 421fd4e5da5Sopenharmony_ci OpFunctionEnd 422fd4e5da5Sopenharmony_ci )"; 423fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 424fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 425fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(11); 426fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(12); 427fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 428fd4e5da5Sopenharmony_ci} 429fd4e5da5Sopenharmony_ci 430fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, CopyObject) { 431fd4e5da5Sopenharmony_ci const std::string text = R"( 432fd4e5da5Sopenharmony_ci OpCapability Shader 433fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 434fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 435fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 436fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 437fd4e5da5Sopenharmony_ci OpSource GLSL 430 438fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 439fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 440fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 441fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 442fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 443fd4e5da5Sopenharmony_ci %7 = OpLabel 444fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Function 445fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 446fd4e5da5Sopenharmony_ci %10 = OpCopyObject %5 %9 447fd4e5da5Sopenharmony_ci OpReturn 448fd4e5da5Sopenharmony_ci OpFunctionEnd 449fd4e5da5Sopenharmony_ci )"; 450fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 451fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 452fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(9); 453fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(10); 454fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 455fd4e5da5Sopenharmony_ci} 456fd4e5da5Sopenharmony_ci 457fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, CopyObjectWitDecoration) { 458fd4e5da5Sopenharmony_ci const std::string text = R"( 459fd4e5da5Sopenharmony_ci OpCapability Shader 460fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 461fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 462fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 463fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 464fd4e5da5Sopenharmony_ci OpSource GLSL 430 465fd4e5da5Sopenharmony_ci OpDecorate %3 NonUniformEXT 466fd4e5da5Sopenharmony_ci %4 = OpTypeVoid 467fd4e5da5Sopenharmony_ci %5 = OpTypeFunction %4 468fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 469fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 470fd4e5da5Sopenharmony_ci %2 = OpFunction %4 None %5 471fd4e5da5Sopenharmony_ci %8 = OpLabel 472fd4e5da5Sopenharmony_ci %9 = OpVariable %7 Function 473fd4e5da5Sopenharmony_ci %10 = OpLoad %6 %9 474fd4e5da5Sopenharmony_ci %3 = OpCopyObject %6 %10 475fd4e5da5Sopenharmony_ci OpReturn 476fd4e5da5Sopenharmony_ci OpFunctionEnd 477fd4e5da5Sopenharmony_ci )"; 478fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 479fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 480fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(10); 481fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(3); 482fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 483fd4e5da5Sopenharmony_ci} 484fd4e5da5Sopenharmony_ci 485fd4e5da5Sopenharmony_ci// Test that a phi where the operands have the same value assigned that value 486fd4e5da5Sopenharmony_ci// to the result of the phi. 487fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, PhiTest1) { 488fd4e5da5Sopenharmony_ci const std::string text = R"( 489fd4e5da5Sopenharmony_ci OpCapability Shader 490fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 491fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 492fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 493fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 494fd4e5da5Sopenharmony_ci OpSource GLSL 430 495fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 496fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 497fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 498fd4e5da5Sopenharmony_ci %6 = OpTypePointer Uniform %5 499fd4e5da5Sopenharmony_ci %7 = OpTypeBool 500fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 501fd4e5da5Sopenharmony_ci %9 = OpVariable %6 Uniform 502fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 503fd4e5da5Sopenharmony_ci %10 = OpLabel 504fd4e5da5Sopenharmony_ci OpBranchConditional %8 %11 %12 505fd4e5da5Sopenharmony_ci %11 = OpLabel 506fd4e5da5Sopenharmony_ci %13 = OpLoad %5 %9 507fd4e5da5Sopenharmony_ci OpBranch %14 508fd4e5da5Sopenharmony_ci %12 = OpLabel 509fd4e5da5Sopenharmony_ci %15 = OpLoad %5 %9 510fd4e5da5Sopenharmony_ci OpBranch %14 511fd4e5da5Sopenharmony_ci %14 = OpLabel 512fd4e5da5Sopenharmony_ci %16 = OpPhi %5 %13 %11 %15 %12 513fd4e5da5Sopenharmony_ci OpReturn 514fd4e5da5Sopenharmony_ci OpFunctionEnd 515fd4e5da5Sopenharmony_ci )"; 516fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 517fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 518fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(13); 519fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(15); 520fd4e5da5Sopenharmony_ci Instruction* phi = context->get_def_use_mgr()->GetDef(16); 521fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 522fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(phi)); 523fd4e5da5Sopenharmony_ci} 524fd4e5da5Sopenharmony_ci 525fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, PhiTest1WithDecoration) { 526fd4e5da5Sopenharmony_ci const std::string text = R"( 527fd4e5da5Sopenharmony_ci OpCapability Shader 528fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 529fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 530fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 531fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 532fd4e5da5Sopenharmony_ci OpSource GLSL 430 533fd4e5da5Sopenharmony_ci OpDecorate %3 NonUniformEXT 534fd4e5da5Sopenharmony_ci %4 = OpTypeVoid 535fd4e5da5Sopenharmony_ci %5 = OpTypeFunction %5 536fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 537fd4e5da5Sopenharmony_ci %7 = OpTypePointer Uniform %6 538fd4e5da5Sopenharmony_ci %8 = OpTypeBool 539fd4e5da5Sopenharmony_ci %9 = OpConstantTrue %8 540fd4e5da5Sopenharmony_ci %10 = OpVariable %7 Uniform 541fd4e5da5Sopenharmony_ci %2 = OpFunction %4 None %5 542fd4e5da5Sopenharmony_ci %11 = OpLabel 543fd4e5da5Sopenharmony_ci OpBranchConditional %9 %12 %13 544fd4e5da5Sopenharmony_ci %12 = OpLabel 545fd4e5da5Sopenharmony_ci %14 = OpLoad %6 %10 546fd4e5da5Sopenharmony_ci OpBranch %15 547fd4e5da5Sopenharmony_ci %13 = OpLabel 548fd4e5da5Sopenharmony_ci %16 = OpLoad %6 %10 549fd4e5da5Sopenharmony_ci OpBranch %15 550fd4e5da5Sopenharmony_ci %15 = OpLabel 551fd4e5da5Sopenharmony_ci %3 = OpPhi %6 %14 %12 %16 %13 552fd4e5da5Sopenharmony_ci OpReturn 553fd4e5da5Sopenharmony_ci OpFunctionEnd 554fd4e5da5Sopenharmony_ci )"; 555fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 556fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 557fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(14); 558fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(16); 559fd4e5da5Sopenharmony_ci Instruction* phi = context->get_def_use_mgr()->GetDef(3); 560fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 561fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(phi)); 562fd4e5da5Sopenharmony_ci} 563fd4e5da5Sopenharmony_ci 564fd4e5da5Sopenharmony_ci// When the values for the inputs to a phi do not match, then the phi should 565fd4e5da5Sopenharmony_ci// have its own value number. 566fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, PhiTest2) { 567fd4e5da5Sopenharmony_ci const std::string text = R"( 568fd4e5da5Sopenharmony_ci OpCapability Shader 569fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 570fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 571fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 572fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 573fd4e5da5Sopenharmony_ci OpSource GLSL 430 574fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 575fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 576fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 577fd4e5da5Sopenharmony_ci %6 = OpTypePointer Uniform %5 578fd4e5da5Sopenharmony_ci %7 = OpTypeBool 579fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 580fd4e5da5Sopenharmony_ci %9 = OpVariable %6 Uniform 581fd4e5da5Sopenharmony_ci %10 = OpVariable %6 Uniform 582fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 583fd4e5da5Sopenharmony_ci %11 = OpLabel 584fd4e5da5Sopenharmony_ci OpBranchConditional %8 %12 %13 585fd4e5da5Sopenharmony_ci %12 = OpLabel 586fd4e5da5Sopenharmony_ci %14 = OpLoad %5 %9 587fd4e5da5Sopenharmony_ci OpBranch %15 588fd4e5da5Sopenharmony_ci %13 = OpLabel 589fd4e5da5Sopenharmony_ci %16 = OpLoad %5 %10 590fd4e5da5Sopenharmony_ci OpBranch %15 591fd4e5da5Sopenharmony_ci %15 = OpLabel 592fd4e5da5Sopenharmony_ci %17 = OpPhi %14 %12 %16 %13 593fd4e5da5Sopenharmony_ci OpReturn 594fd4e5da5Sopenharmony_ci OpFunctionEnd 595fd4e5da5Sopenharmony_ci )"; 596fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 597fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 598fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(14); 599fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(16); 600fd4e5da5Sopenharmony_ci Instruction* phi = context->get_def_use_mgr()->GetDef(17); 601fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 602fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(phi)); 603fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst2), vtable.GetValueNumber(phi)); 604fd4e5da5Sopenharmony_ci} 605fd4e5da5Sopenharmony_ci 606fd4e5da5Sopenharmony_ci// Test that a phi node in a loop header gets a new value because one of its 607fd4e5da5Sopenharmony_ci// inputs comes from later in the loop. 608fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, PhiLoopTest) { 609fd4e5da5Sopenharmony_ci const std::string text = R"( 610fd4e5da5Sopenharmony_ci OpCapability Shader 611fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 612fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 613fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 614fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 615fd4e5da5Sopenharmony_ci OpSource GLSL 430 616fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 617fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 618fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 619fd4e5da5Sopenharmony_ci %6 = OpTypePointer Uniform %5 620fd4e5da5Sopenharmony_ci %7 = OpTypeBool 621fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 622fd4e5da5Sopenharmony_ci %9 = OpVariable %6 Uniform 623fd4e5da5Sopenharmony_ci %10 = OpVariable %6 Uniform 624fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 625fd4e5da5Sopenharmony_ci %11 = OpLabel 626fd4e5da5Sopenharmony_ci %12 = OpLoad %5 %9 627fd4e5da5Sopenharmony_ci OpSelectionMerge %13 None 628fd4e5da5Sopenharmony_ci OpBranchConditional %8 %14 %13 629fd4e5da5Sopenharmony_ci %14 = OpLabel 630fd4e5da5Sopenharmony_ci %15 = OpPhi %5 %12 %11 %16 %14 631fd4e5da5Sopenharmony_ci %16 = OpLoad %5 %9 632fd4e5da5Sopenharmony_ci OpLoopMerge %17 %14 None 633fd4e5da5Sopenharmony_ci OpBranchConditional %8 %14 %17 634fd4e5da5Sopenharmony_ci %17 = OpLabel 635fd4e5da5Sopenharmony_ci OpBranch %13 636fd4e5da5Sopenharmony_ci %13 = OpLabel 637fd4e5da5Sopenharmony_ci %18 = OpPhi %5 %12 %11 %16 %17 638fd4e5da5Sopenharmony_ci OpReturn 639fd4e5da5Sopenharmony_ci OpFunctionEnd 640fd4e5da5Sopenharmony_ci )"; 641fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 642fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 643fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(12); 644fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(16); 645fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 646fd4e5da5Sopenharmony_ci 647fd4e5da5Sopenharmony_ci Instruction* phi1 = context->get_def_use_mgr()->GetDef(15); 648fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(phi1)); 649fd4e5da5Sopenharmony_ci 650fd4e5da5Sopenharmony_ci Instruction* phi2 = context->get_def_use_mgr()->GetDef(18); 651fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(phi2)); 652fd4e5da5Sopenharmony_ci EXPECT_NE(vtable.GetValueNumber(phi1), vtable.GetValueNumber(phi2)); 653fd4e5da5Sopenharmony_ci} 654fd4e5da5Sopenharmony_ci 655fd4e5da5Sopenharmony_ci// Test to make sure that OpPhi instructions with no in operands are handled 656fd4e5da5Sopenharmony_ci// correctly. 657fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, EmptyPhiTest) { 658fd4e5da5Sopenharmony_ci const std::string text = R"( 659fd4e5da5Sopenharmony_ci OpCapability Shader 660fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 661fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 662fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 663fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 664fd4e5da5Sopenharmony_ci OpSource GLSL 430 665fd4e5da5Sopenharmony_ci %void = OpTypeVoid 666fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %void 667fd4e5da5Sopenharmony_ci %bool = OpTypeBool 668fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 669fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %4 670fd4e5da5Sopenharmony_ci %7 = OpLabel 671fd4e5da5Sopenharmony_ci OpSelectionMerge %8 None 672fd4e5da5Sopenharmony_ci OpBranchConditional %true %9 %8 673fd4e5da5Sopenharmony_ci %9 = OpLabel 674fd4e5da5Sopenharmony_ci OpKill 675fd4e5da5Sopenharmony_ci %8 = OpLabel 676fd4e5da5Sopenharmony_ci %10 = OpPhi %bool 677fd4e5da5Sopenharmony_ci OpReturn 678fd4e5da5Sopenharmony_ci OpFunctionEnd 679fd4e5da5Sopenharmony_ci )"; 680fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 681fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 682fd4e5da5Sopenharmony_ci Instruction* inst = context->get_def_use_mgr()->GetDef(10); 683fd4e5da5Sopenharmony_ci vtable.GetValueNumber(inst); 684fd4e5da5Sopenharmony_ci} 685fd4e5da5Sopenharmony_ci 686fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, RedundantSampledImageLoad) { 687fd4e5da5Sopenharmony_ci const std::string text = R"( 688fd4e5da5Sopenharmony_ci OpCapability Shader 689fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 690fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 691fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %gl_FragColor 692fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginLowerLeft 693fd4e5da5Sopenharmony_ci OpSource GLSL 330 694fd4e5da5Sopenharmony_ci OpName %main "main" 695fd4e5da5Sopenharmony_ci OpName %tex0 "tex0" 696fd4e5da5Sopenharmony_ci OpName %gl_FragColor "gl_FragColor" 697fd4e5da5Sopenharmony_ci OpDecorate %tex0 Location 0 698fd4e5da5Sopenharmony_ci OpDecorate %tex0 DescriptorSet 0 699fd4e5da5Sopenharmony_ci OpDecorate %tex0 Binding 0 700fd4e5da5Sopenharmony_ci OpDecorate %gl_FragColor Location 0 701fd4e5da5Sopenharmony_ci %void = OpTypeVoid 702fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %void 703fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 704fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 705fd4e5da5Sopenharmony_ci %9 = OpTypeImage %float 2D 0 0 0 1 Unknown 706fd4e5da5Sopenharmony_ci %10 = OpTypeSampledImage %9 707fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 708fd4e5da5Sopenharmony_ci %tex0 = OpVariable %_ptr_UniformConstant_10 UniformConstant 709fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 710fd4e5da5Sopenharmony_ci %13 = OpConstantNull %v4float 711fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 712fd4e5da5Sopenharmony_ci %14 = OpUndef %v4float 713fd4e5da5Sopenharmony_ci %main = OpFunction %void None %6 714fd4e5da5Sopenharmony_ci %15 = OpLabel 715fd4e5da5Sopenharmony_ci %16 = OpLoad %10 %tex0 716fd4e5da5Sopenharmony_ci %17 = OpImageSampleProjImplicitLod %v4float %16 %13 717fd4e5da5Sopenharmony_ci %18 = OpImageSampleProjImplicitLod %v4float %16 %13 718fd4e5da5Sopenharmony_ci %19 = OpFAdd %v4float %18 %17 719fd4e5da5Sopenharmony_ci OpStore %gl_FragColor %19 720fd4e5da5Sopenharmony_ci OpReturn 721fd4e5da5Sopenharmony_ci OpFunctionEnd 722fd4e5da5Sopenharmony_ci )"; 723fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 724fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 725fd4e5da5Sopenharmony_ci Instruction* load1 = context->get_def_use_mgr()->GetDef(17); 726fd4e5da5Sopenharmony_ci Instruction* load2 = context->get_def_use_mgr()->GetDef(18); 727fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(load1), vtable.GetValueNumber(load2)); 728fd4e5da5Sopenharmony_ci} 729fd4e5da5Sopenharmony_ci 730fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentDebugLocalVariableSameValue) { 731fd4e5da5Sopenharmony_ci const std::string text = R"( 732fd4e5da5Sopenharmony_ci OpCapability Shader 733fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 734fd4e5da5Sopenharmony_ci %2 = OpExtInstImport "OpenCL.DebugInfo.100" 735fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 736fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %3 "main" 737fd4e5da5Sopenharmony_ci OpExecutionMode %3 OriginUpperLeft 738fd4e5da5Sopenharmony_ci OpSource GLSL 430 739fd4e5da5Sopenharmony_ci %4 = OpString "test" 740fd4e5da5Sopenharmony_ci %5 = OpTypeVoid 741fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %5 742fd4e5da5Sopenharmony_ci %7 = OpTypeInt 32 0 743fd4e5da5Sopenharmony_ci %8 = OpConstant %7 32 744fd4e5da5Sopenharmony_ci %9 = OpExtInst %5 %2 DebugSource %4 745fd4e5da5Sopenharmony_ci %10 = OpExtInst %5 %2 DebugCompilationUnit 1 4 %9 HLSL 746fd4e5da5Sopenharmony_ci %11 = OpExtInst %5 %2 DebugTypeBasic %4 %8 Float 747fd4e5da5Sopenharmony_ci %12 = OpExtInst %5 %2 DebugLocalVariable %4 %11 %9 0 0 %10 FlagIsLocal 748fd4e5da5Sopenharmony_ci %13 = OpExtInst %5 %2 DebugLocalVariable %4 %11 %9 0 0 %10 FlagIsLocal 749fd4e5da5Sopenharmony_ci %3 = OpFunction %5 None %6 750fd4e5da5Sopenharmony_ci %14 = OpLabel 751fd4e5da5Sopenharmony_ci OpReturn 752fd4e5da5Sopenharmony_ci OpFunctionEnd 753fd4e5da5Sopenharmony_ci )"; 754fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 755fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 756fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(12); 757fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(13); 758fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 759fd4e5da5Sopenharmony_ci} 760fd4e5da5Sopenharmony_ci 761fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentDebugValueSameValue) { 762fd4e5da5Sopenharmony_ci const std::string text = R"( 763fd4e5da5Sopenharmony_ci OpCapability Shader 764fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 765fd4e5da5Sopenharmony_ci %2 = OpExtInstImport "OpenCL.DebugInfo.100" 766fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 767fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %3 "main" 768fd4e5da5Sopenharmony_ci OpExecutionMode %3 OriginUpperLeft 769fd4e5da5Sopenharmony_ci OpSource GLSL 430 770fd4e5da5Sopenharmony_ci %4 = OpString "test" 771fd4e5da5Sopenharmony_ci %5 = OpTypeVoid 772fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %5 773fd4e5da5Sopenharmony_ci %7 = OpTypeInt 32 0 774fd4e5da5Sopenharmony_ci %8 = OpConstant %7 32 775fd4e5da5Sopenharmony_ci %9 = OpExtInst %5 %2 DebugSource %4 776fd4e5da5Sopenharmony_ci %10 = OpExtInst %5 %2 DebugCompilationUnit 1 4 %9 HLSL 777fd4e5da5Sopenharmony_ci %11 = OpExtInst %5 %2 DebugTypeBasic %4 %8 Float 778fd4e5da5Sopenharmony_ci %12 = OpExtInst %5 %2 DebugLocalVariable %4 %11 %9 0 0 %10 FlagIsLocal 779fd4e5da5Sopenharmony_ci %13 = OpExtInst %5 %2 DebugExpression 780fd4e5da5Sopenharmony_ci %3 = OpFunction %5 None %6 781fd4e5da5Sopenharmony_ci %14 = OpLabel 782fd4e5da5Sopenharmony_ci %15 = OpExtInst %5 %2 DebugValue %12 %8 %13 783fd4e5da5Sopenharmony_ci %16 = OpExtInst %5 %2 DebugValue %12 %8 %13 784fd4e5da5Sopenharmony_ci OpReturn 785fd4e5da5Sopenharmony_ci OpFunctionEnd 786fd4e5da5Sopenharmony_ci )"; 787fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 788fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 789fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(15); 790fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(16); 791fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 792fd4e5da5Sopenharmony_ci} 793fd4e5da5Sopenharmony_ci 794fd4e5da5Sopenharmony_ciTEST_F(ValueTableTest, DifferentDebugDeclareSameValue) { 795fd4e5da5Sopenharmony_ci const std::string text = R"( 796fd4e5da5Sopenharmony_ci OpCapability Shader 797fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 798fd4e5da5Sopenharmony_ci %2 = OpExtInstImport "OpenCL.DebugInfo.100" 799fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 800fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %3 "main" 801fd4e5da5Sopenharmony_ci OpExecutionMode %3 OriginUpperLeft 802fd4e5da5Sopenharmony_ci OpSource GLSL 430 803fd4e5da5Sopenharmony_ci %4 = OpString "test" 804fd4e5da5Sopenharmony_ci %void = OpTypeVoid 805fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %void 806fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 807fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint 808fd4e5da5Sopenharmony_ci %uint_32 = OpConstant %uint 32 809fd4e5da5Sopenharmony_ci %10 = OpExtInst %void %2 DebugSource %4 810fd4e5da5Sopenharmony_ci %11 = OpExtInst %void %2 DebugCompilationUnit 1 4 %10 HLSL 811fd4e5da5Sopenharmony_ci %12 = OpExtInst %void %2 DebugTypeBasic %4 %uint_32 Float 812fd4e5da5Sopenharmony_ci %13 = OpExtInst %void %2 DebugLocalVariable %4 %12 %10 0 0 %11 FlagIsLocal 813fd4e5da5Sopenharmony_ci %14 = OpExtInst %void %2 DebugExpression 814fd4e5da5Sopenharmony_ci %3 = OpFunction %void None %6 815fd4e5da5Sopenharmony_ci %15 = OpLabel 816fd4e5da5Sopenharmony_ci %16 = OpVariable %_ptr_Function_uint Function 817fd4e5da5Sopenharmony_ci %17 = OpExtInst %void %2 DebugDeclare %13 %16 %14 818fd4e5da5Sopenharmony_ci %18 = OpExtInst %void %2 DebugDeclare %13 %16 %14 819fd4e5da5Sopenharmony_ci OpReturn 820fd4e5da5Sopenharmony_ci OpFunctionEnd 821fd4e5da5Sopenharmony_ci )"; 822fd4e5da5Sopenharmony_ci auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); 823fd4e5da5Sopenharmony_ci ValueNumberTable vtable(context.get()); 824fd4e5da5Sopenharmony_ci Instruction* inst1 = context->get_def_use_mgr()->GetDef(17); 825fd4e5da5Sopenharmony_ci Instruction* inst2 = context->get_def_use_mgr()->GetDef(18); 826fd4e5da5Sopenharmony_ci EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2)); 827fd4e5da5Sopenharmony_ci} 828fd4e5da5Sopenharmony_ci 829fd4e5da5Sopenharmony_ci} // namespace 830fd4e5da5Sopenharmony_ci} // namespace opt 831fd4e5da5Sopenharmony_ci} // namespace spvtools 832