1fd4e5da5Sopenharmony_ci// Copyright (c) 2021 Alastair F. Donaldson 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 "source/fuzz/available_instructions.h" 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "gtest/gtest.h" 18fd4e5da5Sopenharmony_ci#include "source/fuzz/fuzzer_util.h" 19fd4e5da5Sopenharmony_ci#include "test/fuzz/fuzz_test_util.h" 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_cinamespace spvtools { 22fd4e5da5Sopenharmony_cinamespace fuzz { 23fd4e5da5Sopenharmony_cinamespace { 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_ciTEST(AvailableInstructionsTest, BasicTest) { 26fd4e5da5Sopenharmony_ci std::string shader = R"( 27fd4e5da5Sopenharmony_ci OpCapability Shader 28fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 29fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 30fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 31fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 32fd4e5da5Sopenharmony_ci OpSource ESSL 320 33fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 34fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 35fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 36fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 37fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 38fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 39fd4e5da5Sopenharmony_ci %10 = OpTypeFunction %6 %7 %9 40fd4e5da5Sopenharmony_ci %15 = OpTypeVector %8 2 41fd4e5da5Sopenharmony_ci %16 = OpTypePointer Private %15 42fd4e5da5Sopenharmony_ci %17 = OpVariable %16 Private 43fd4e5da5Sopenharmony_ci %18 = OpConstant %8 1 44fd4e5da5Sopenharmony_ci %19 = OpConstant %8 2 45fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %15 %18 %19 46fd4e5da5Sopenharmony_ci %21 = OpTypeVector %8 4 47fd4e5da5Sopenharmony_ci %22 = OpTypePointer Private %21 48fd4e5da5Sopenharmony_ci %23 = OpVariable %22 Private 49fd4e5da5Sopenharmony_ci %24 = OpConstant %8 10 50fd4e5da5Sopenharmony_ci %25 = OpConstant %8 20 51fd4e5da5Sopenharmony_ci %26 = OpConstant %8 30 52fd4e5da5Sopenharmony_ci %27 = OpConstant %8 40 53fd4e5da5Sopenharmony_ci %28 = OpConstantComposite %21 %24 %25 %26 %27 54fd4e5da5Sopenharmony_ci %31 = OpTypeInt 32 0 55fd4e5da5Sopenharmony_ci %32 = OpConstant %31 0 56fd4e5da5Sopenharmony_ci %33 = OpTypePointer Private %8 57fd4e5da5Sopenharmony_ci %41 = OpTypeBool 58fd4e5da5Sopenharmony_ci %46 = OpConstant %6 1 59fd4e5da5Sopenharmony_ci %54 = OpConstant %6 10 60fd4e5da5Sopenharmony_ci %57 = OpConstant %31 3 61fd4e5da5Sopenharmony_ci %61 = OpConstant %6 0 62fd4e5da5Sopenharmony_ci %66 = OpConstant %6 3 63fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 64fd4e5da5Sopenharmony_ci %5 = OpLabel 65fd4e5da5Sopenharmony_ci %55 = OpVariable %7 Function 66fd4e5da5Sopenharmony_ci %56 = OpVariable %9 Function 67fd4e5da5Sopenharmony_ci %65 = OpVariable %7 Function 68fd4e5da5Sopenharmony_ci %68 = OpVariable %7 Function 69fd4e5da5Sopenharmony_ci OpStore %17 %20 70fd4e5da5Sopenharmony_ci OpStore %23 %28 71fd4e5da5Sopenharmony_ci OpStore %55 %54 72fd4e5da5Sopenharmony_ci %58 = OpAccessChain %33 %23 %57 73fd4e5da5Sopenharmony_ci %59 = OpLoad %8 %58 74fd4e5da5Sopenharmony_ci OpStore %56 %59 75fd4e5da5Sopenharmony_ci %60 = OpFunctionCall %6 %13 %55 %56 76fd4e5da5Sopenharmony_ci %100 = OpCopyObject %21 %28 77fd4e5da5Sopenharmony_ci %62 = OpSGreaterThan %41 %60 %61 78fd4e5da5Sopenharmony_ci OpSelectionMerge %64 None 79fd4e5da5Sopenharmony_ci OpBranchConditional %62 %63 %67 80fd4e5da5Sopenharmony_ci %63 = OpLabel 81fd4e5da5Sopenharmony_ci OpStore %65 %66 82fd4e5da5Sopenharmony_ci %101 = OpCopyObject %21 %28 83fd4e5da5Sopenharmony_ci OpBranch %64 84fd4e5da5Sopenharmony_ci %67 = OpLabel 85fd4e5da5Sopenharmony_ci OpStore %68 %61 86fd4e5da5Sopenharmony_ci OpBranch %69 87fd4e5da5Sopenharmony_ci %69 = OpLabel 88fd4e5da5Sopenharmony_ci OpLoopMerge %71 %72 None 89fd4e5da5Sopenharmony_ci OpBranch %73 90fd4e5da5Sopenharmony_ci %73 = OpLabel 91fd4e5da5Sopenharmony_ci %74 = OpLoad %6 %68 92fd4e5da5Sopenharmony_ci %75 = OpSLessThan %41 %74 %54 93fd4e5da5Sopenharmony_ci OpBranchConditional %75 %70 %71 94fd4e5da5Sopenharmony_ci %70 = OpLabel 95fd4e5da5Sopenharmony_ci %76 = OpLoad %6 %65 96fd4e5da5Sopenharmony_ci %77 = OpIAdd %6 %76 %46 97fd4e5da5Sopenharmony_ci OpStore %65 %77 98fd4e5da5Sopenharmony_ci OpBranch %72 99fd4e5da5Sopenharmony_ci %72 = OpLabel 100fd4e5da5Sopenharmony_ci %78 = OpLoad %6 %68 101fd4e5da5Sopenharmony_ci %79 = OpIAdd %6 %78 %46 102fd4e5da5Sopenharmony_ci OpStore %68 %79 103fd4e5da5Sopenharmony_ci OpBranch %69 104fd4e5da5Sopenharmony_ci %71 = OpLabel 105fd4e5da5Sopenharmony_ci %102 = OpCopyObject %21 %28 106fd4e5da5Sopenharmony_ci OpBranch %64 107fd4e5da5Sopenharmony_ci %64 = OpLabel 108fd4e5da5Sopenharmony_ci OpReturn 109fd4e5da5Sopenharmony_ci OpFunctionEnd 110fd4e5da5Sopenharmony_ci %13 = OpFunction %6 None %10 111fd4e5da5Sopenharmony_ci %11 = OpFunctionParameter %7 112fd4e5da5Sopenharmony_ci %12 = OpFunctionParameter %9 113fd4e5da5Sopenharmony_ci %14 = OpLabel 114fd4e5da5Sopenharmony_ci %29 = OpVariable %7 Function 115fd4e5da5Sopenharmony_ci %30 = OpLoad %6 %11 116fd4e5da5Sopenharmony_ci %34 = OpAccessChain %33 %17 %32 117fd4e5da5Sopenharmony_ci %35 = OpLoad %8 %34 118fd4e5da5Sopenharmony_ci %36 = OpConvertFToS %6 %35 119fd4e5da5Sopenharmony_ci %37 = OpIAdd %6 %30 %36 120fd4e5da5Sopenharmony_ci OpStore %29 %37 121fd4e5da5Sopenharmony_ci %38 = OpLoad %6 %11 122fd4e5da5Sopenharmony_ci %39 = OpLoad %8 %12 123fd4e5da5Sopenharmony_ci %40 = OpConvertFToS %6 %39 124fd4e5da5Sopenharmony_ci %42 = OpSLessThan %41 %38 %40 125fd4e5da5Sopenharmony_ci %103 = OpCopyObject %21 %28 126fd4e5da5Sopenharmony_ci OpSelectionMerge %44 None 127fd4e5da5Sopenharmony_ci OpBranchConditional %42 %43 %48 128fd4e5da5Sopenharmony_ci %43 = OpLabel 129fd4e5da5Sopenharmony_ci %45 = OpLoad %6 %29 130fd4e5da5Sopenharmony_ci %47 = OpIAdd %6 %45 %46 131fd4e5da5Sopenharmony_ci OpStore %29 %47 132fd4e5da5Sopenharmony_ci OpBranch %44 133fd4e5da5Sopenharmony_ci %48 = OpLabel 134fd4e5da5Sopenharmony_ci %49 = OpLoad %6 %29 135fd4e5da5Sopenharmony_ci %50 = OpISub %6 %49 %46 136fd4e5da5Sopenharmony_ci OpStore %29 %50 137fd4e5da5Sopenharmony_ci OpBranch %44 138fd4e5da5Sopenharmony_ci %44 = OpLabel 139fd4e5da5Sopenharmony_ci %51 = OpLoad %6 %29 140fd4e5da5Sopenharmony_ci OpReturnValue %51 141fd4e5da5Sopenharmony_ci OpFunctionEnd 142fd4e5da5Sopenharmony_ci )"; 143fd4e5da5Sopenharmony_ci 144fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 145fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 146fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 147fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 148fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 149fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 150fd4e5da5Sopenharmony_ci 151fd4e5da5Sopenharmony_ci opt::Instruction* i1 = context->get_def_use_mgr()->GetDef(55); 152fd4e5da5Sopenharmony_ci opt::Instruction* i2 = context->get_def_use_mgr()->GetDef(101); 153fd4e5da5Sopenharmony_ci opt::Instruction* i3 = &*context->cfg()->block(67)->begin(); 154fd4e5da5Sopenharmony_ci opt::Instruction* i4 = context->get_def_use_mgr()->GetDef(74); 155fd4e5da5Sopenharmony_ci opt::Instruction* i5 = context->get_def_use_mgr()->GetDef(102); 156fd4e5da5Sopenharmony_ci opt::Instruction* i6 = context->get_def_use_mgr()->GetDef(30); 157fd4e5da5Sopenharmony_ci opt::Instruction* i7 = context->get_def_use_mgr()->GetDef(47); 158fd4e5da5Sopenharmony_ci opt::Instruction* i8 = context->get_def_use_mgr()->GetDef(50); 159fd4e5da5Sopenharmony_ci opt::Instruction* i9 = context->get_def_use_mgr()->GetDef(51); 160fd4e5da5Sopenharmony_ci 161fd4e5da5Sopenharmony_ci { 162fd4e5da5Sopenharmony_ci AvailableInstructions no_instructions( 163fd4e5da5Sopenharmony_ci context.get(), 164fd4e5da5Sopenharmony_ci [](opt::IRContext*, opt::Instruction*) -> bool { return false; }); 165fd4e5da5Sopenharmony_ci for (auto i : {i1, i2, i3, i4, i5, i6, i7, i8, i9}) { 166fd4e5da5Sopenharmony_ci auto available = no_instructions.GetAvailableBeforeInstruction(i); 167fd4e5da5Sopenharmony_ci ASSERT_EQ(0, available.size()); 168fd4e5da5Sopenharmony_ci ASSERT_TRUE(available.empty()); 169fd4e5da5Sopenharmony_ci } 170fd4e5da5Sopenharmony_ci } 171fd4e5da5Sopenharmony_ci { 172fd4e5da5Sopenharmony_ci AvailableInstructions all_instructions( 173fd4e5da5Sopenharmony_ci context.get(), 174fd4e5da5Sopenharmony_ci [](opt::IRContext*, opt::Instruction*) -> bool { return true; }); 175fd4e5da5Sopenharmony_ci { 176fd4e5da5Sopenharmony_ci auto available = all_instructions.GetAvailableBeforeInstruction(i1); 177fd4e5da5Sopenharmony_ci ASSERT_FALSE(available.empty()); 178fd4e5da5Sopenharmony_ci ASSERT_EQ(30, available.size()); 179fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpTypeVoid, available[0]->opcode()); 180fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpVariable, available[15]->opcode()); 181fd4e5da5Sopenharmony_ci } 182fd4e5da5Sopenharmony_ci { 183fd4e5da5Sopenharmony_ci auto available = all_instructions.GetAvailableBeforeInstruction(i2); 184fd4e5da5Sopenharmony_ci ASSERT_FALSE(available.empty()); 185fd4e5da5Sopenharmony_ci ASSERT_EQ(46, available.size()); 186fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpTypeVoid, available[0]->opcode()); 187fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpTypePointer, available[3]->opcode()); 188fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpVariable, available[15]->opcode()); 189fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpFunctionCall, available[40]->opcode()); 190fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpStore, available[45]->opcode()); 191fd4e5da5Sopenharmony_ci } 192fd4e5da5Sopenharmony_ci { 193fd4e5da5Sopenharmony_ci auto available = all_instructions.GetAvailableBeforeInstruction(i3); 194fd4e5da5Sopenharmony_ci ASSERT_FALSE(available.empty()); 195fd4e5da5Sopenharmony_ci ASSERT_EQ(45, available.size()); 196fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpTypeVoid, available[0]->opcode()); 197fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpTypePointer, available[3]->opcode()); 198fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpVariable, available[15]->opcode()); 199fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpFunctionCall, available[40]->opcode()); 200fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpBranchConditional, available[44]->opcode()); 201fd4e5da5Sopenharmony_ci } 202fd4e5da5Sopenharmony_ci { 203fd4e5da5Sopenharmony_ci auto available = all_instructions.GetAvailableBeforeInstruction(i6); 204fd4e5da5Sopenharmony_ci ASSERT_FALSE(available.empty()); 205fd4e5da5Sopenharmony_ci ASSERT_EQ(33, available.size()); 206fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpTypeVoid, available[0]->opcode()); 207fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpTypeFloat, available[4]->opcode()); 208fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpTypePointer, available[8]->opcode()); 209fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpConstantComposite, available[12]->opcode()); 210fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpConstant, available[16]->opcode()); 211fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpFunctionParameter, available[30]->opcode()); 212fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpFunctionParameter, available[31]->opcode()); 213fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpVariable, available[32]->opcode()); 214fd4e5da5Sopenharmony_ci } 215fd4e5da5Sopenharmony_ci } 216fd4e5da5Sopenharmony_ci { 217fd4e5da5Sopenharmony_ci AvailableInstructions vector_instructions( 218fd4e5da5Sopenharmony_ci context.get(), 219fd4e5da5Sopenharmony_ci [](opt::IRContext* ir_context, opt::Instruction* inst) -> bool { 220fd4e5da5Sopenharmony_ci return inst->type_id() != 0 && ir_context->get_type_mgr() 221fd4e5da5Sopenharmony_ci ->GetType(inst->type_id()) 222fd4e5da5Sopenharmony_ci ->AsVector() != nullptr; 223fd4e5da5Sopenharmony_ci }); 224fd4e5da5Sopenharmony_ci { 225fd4e5da5Sopenharmony_ci auto available = vector_instructions.GetAvailableBeforeInstruction(i4); 226fd4e5da5Sopenharmony_ci ASSERT_FALSE(available.empty()); 227fd4e5da5Sopenharmony_ci ASSERT_EQ(3, available.size()); 228fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpConstantComposite, available[0]->opcode()); 229fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpConstantComposite, available[1]->opcode()); 230fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpCopyObject, available[2]->opcode()); 231fd4e5da5Sopenharmony_ci } 232fd4e5da5Sopenharmony_ci { 233fd4e5da5Sopenharmony_ci auto available = vector_instructions.GetAvailableBeforeInstruction(i5); 234fd4e5da5Sopenharmony_ci ASSERT_FALSE(available.empty()); 235fd4e5da5Sopenharmony_ci ASSERT_EQ(3, available.size()); 236fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpConstantComposite, available[0]->opcode()); 237fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpConstantComposite, available[1]->opcode()); 238fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpCopyObject, available[2]->opcode()); 239fd4e5da5Sopenharmony_ci } 240fd4e5da5Sopenharmony_ci { 241fd4e5da5Sopenharmony_ci auto available = vector_instructions.GetAvailableBeforeInstruction(i6); 242fd4e5da5Sopenharmony_ci ASSERT_FALSE(available.empty()); 243fd4e5da5Sopenharmony_ci ASSERT_EQ(2, available.size()); 244fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpConstantComposite, available[0]->opcode()); 245fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpConstantComposite, available[1]->opcode()); 246fd4e5da5Sopenharmony_ci } 247fd4e5da5Sopenharmony_ci } 248fd4e5da5Sopenharmony_ci { 249fd4e5da5Sopenharmony_ci AvailableInstructions integer_add_instructions( 250fd4e5da5Sopenharmony_ci context.get(), [](opt::IRContext*, opt::Instruction* inst) -> bool { 251fd4e5da5Sopenharmony_ci return inst->opcode() == spv::Op::OpIAdd; 252fd4e5da5Sopenharmony_ci }); 253fd4e5da5Sopenharmony_ci { 254fd4e5da5Sopenharmony_ci auto available = 255fd4e5da5Sopenharmony_ci integer_add_instructions.GetAvailableBeforeInstruction(i7); 256fd4e5da5Sopenharmony_ci ASSERT_FALSE(available.empty()); 257fd4e5da5Sopenharmony_ci ASSERT_EQ(1, available.size()); 258fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpIAdd, available[0]->opcode()); 259fd4e5da5Sopenharmony_ci } 260fd4e5da5Sopenharmony_ci { 261fd4e5da5Sopenharmony_ci auto available = 262fd4e5da5Sopenharmony_ci integer_add_instructions.GetAvailableBeforeInstruction(i8); 263fd4e5da5Sopenharmony_ci ASSERT_FALSE(available.empty()); 264fd4e5da5Sopenharmony_ci ASSERT_EQ(1, available.size()); 265fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpIAdd, available[0]->opcode()); 266fd4e5da5Sopenharmony_ci } 267fd4e5da5Sopenharmony_ci { 268fd4e5da5Sopenharmony_ci auto available = 269fd4e5da5Sopenharmony_ci integer_add_instructions.GetAvailableBeforeInstruction(i9); 270fd4e5da5Sopenharmony_ci ASSERT_FALSE(available.empty()); 271fd4e5da5Sopenharmony_ci ASSERT_EQ(1, available.size()); 272fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpIAdd, available[0]->opcode()); 273fd4e5da5Sopenharmony_ci } 274fd4e5da5Sopenharmony_ci } 275fd4e5da5Sopenharmony_ci} 276fd4e5da5Sopenharmony_ci 277fd4e5da5Sopenharmony_ciTEST(AvailableInstructionsTest, UnreachableBlock) { 278fd4e5da5Sopenharmony_ci std::string shader = R"( 279fd4e5da5Sopenharmony_ci OpCapability Shader 280fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 281fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 282fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 283fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 284fd4e5da5Sopenharmony_ci OpSource ESSL 320 285fd4e5da5Sopenharmony_ci OpName %4 "main" 286fd4e5da5Sopenharmony_ci OpName %8 "x" 287fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 288fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 289fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 290fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 291fd4e5da5Sopenharmony_ci %9 = OpConstant %6 2 292fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 293fd4e5da5Sopenharmony_ci %5 = OpLabel 294fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 295fd4e5da5Sopenharmony_ci OpStore %8 %9 296fd4e5da5Sopenharmony_ci %12 = OpLoad %6 %8 297fd4e5da5Sopenharmony_ci OpReturn 298fd4e5da5Sopenharmony_ci %10 = OpLabel 299fd4e5da5Sopenharmony_ci %11 = OpLoad %6 %8 300fd4e5da5Sopenharmony_ci OpReturn 301fd4e5da5Sopenharmony_ci OpFunctionEnd 302fd4e5da5Sopenharmony_ci )"; 303fd4e5da5Sopenharmony_ci 304fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 305fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 306fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 307fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 308fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 309fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 310fd4e5da5Sopenharmony_ci 311fd4e5da5Sopenharmony_ci AvailableInstructions all_instructions( 312fd4e5da5Sopenharmony_ci context.get(), 313fd4e5da5Sopenharmony_ci [](opt::IRContext*, opt::Instruction*) -> bool { return true; }); 314fd4e5da5Sopenharmony_ci ASSERT_EQ(7, all_instructions 315fd4e5da5Sopenharmony_ci .GetAvailableBeforeInstruction( 316fd4e5da5Sopenharmony_ci context->get_def_use_mgr()->GetDef(12)) 317fd4e5da5Sopenharmony_ci .size()); 318fd4e5da5Sopenharmony_ci 319fd4e5da5Sopenharmony_ci#ifndef NDEBUG 320fd4e5da5Sopenharmony_ci ASSERT_DEATH(all_instructions.GetAvailableBeforeInstruction( 321fd4e5da5Sopenharmony_ci context->get_def_use_mgr()->GetDef(11)), 322fd4e5da5Sopenharmony_ci "Availability can only be queried for reachable instructions."); 323fd4e5da5Sopenharmony_ci#endif 324fd4e5da5Sopenharmony_ci} 325fd4e5da5Sopenharmony_ci 326fd4e5da5Sopenharmony_ci} // namespace 327fd4e5da5Sopenharmony_ci} // namespace fuzz 328fd4e5da5Sopenharmony_ci} // namespace spvtools 329