1// Copyright (c) 2017 Google Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#include <memory> 16#include <vector> 17 18#include "gmock/gmock.h" 19#include "source/opt/dominator_analysis.h" 20#include "source/opt/pass.h" 21#include "test/opt/assembly_builder.h" 22#include "test/opt/function_utils.h" 23#include "test/opt/pass_fixture.h" 24#include "test/opt/pass_utils.h" 25 26namespace spvtools { 27namespace opt { 28namespace { 29 30using ::testing::UnorderedElementsAre; 31using PassClassTest = PassTest<::testing::Test>; 32 33/* 34 Generated from the following GLSL 35#version 330 core 36layout(location = 0) out vec4 v; 37void main(){ 38 if (true) { 39 if (true) { 40 v = vec4(1,1,1,1); 41 } else { 42 v = vec4(2,2,2,2); 43 } 44 } else { 45 if (true) { 46 v = vec4(3,3,3,3); 47 } else { 48 v = vec4(4,4,4,4); 49 } 50 } 51} 52*/ 53TEST_F(PassClassTest, UnreachableNestedIfs) { 54 const std::string text = R"( 55 OpCapability Shader 56 %1 = OpExtInstImport "GLSL.std.450" 57 OpMemoryModel Logical GLSL450 58 OpEntryPoint Fragment %4 "main" %15 59 OpExecutionMode %4 OriginUpperLeft 60 OpSource GLSL 330 61 OpName %4 "main" 62 OpName %15 "v" 63 OpDecorate %15 Location 0 64 %2 = OpTypeVoid 65 %3 = OpTypeFunction %2 66 %6 = OpTypeBool 67 %7 = OpConstantTrue %6 68 %12 = OpTypeFloat 32 69 %13 = OpTypeVector %12 4 70 %14 = OpTypePointer Output %13 71 %15 = OpVariable %14 Output 72 %16 = OpConstant %12 1 73 %17 = OpConstantComposite %13 %16 %16 %16 %16 74 %19 = OpConstant %12 2 75 %20 = OpConstantComposite %13 %19 %19 %19 %19 76 %24 = OpConstant %12 3 77 %25 = OpConstantComposite %13 %24 %24 %24 %24 78 %27 = OpConstant %12 4 79 %28 = OpConstantComposite %13 %27 %27 %27 %27 80 %4 = OpFunction %2 None %3 81 %5 = OpLabel 82 OpSelectionMerge %9 None 83 OpBranchConditional %7 %8 %21 84 %8 = OpLabel 85 OpSelectionMerge %11 None 86 OpBranchConditional %7 %10 %18 87 %10 = OpLabel 88 OpStore %15 %17 89 OpBranch %11 90 %18 = OpLabel 91 OpStore %15 %20 92 OpBranch %11 93 %11 = OpLabel 94 OpBranch %9 95 %21 = OpLabel 96 OpSelectionMerge %23 None 97 OpBranchConditional %7 %22 %26 98 %22 = OpLabel 99 OpStore %15 %25 100 OpBranch %23 101 %26 = OpLabel 102 OpStore %15 %28 103 OpBranch %23 104 %23 = OpLabel 105 OpBranch %9 106 %9 = OpLabel 107 OpReturn 108 OpFunctionEnd 109)"; 110 // clang-format on 111 std::unique_ptr<IRContext> context = 112 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text, 113 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 114 Module* module = context->module(); 115 EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n" 116 << text << std::endl; 117 118 const Function* f = spvtest::GetFunction(module, 4); 119 120 DominatorAnalysis* analysis = context->GetDominatorAnalysis(f); 121 122 EXPECT_TRUE(analysis->Dominates(5, 8)); 123 EXPECT_TRUE(analysis->Dominates(5, 9)); 124 EXPECT_TRUE(analysis->Dominates(5, 21)); 125 EXPECT_TRUE(analysis->Dominates(5, 18)); 126 EXPECT_TRUE(analysis->Dominates(5, 10)); 127 EXPECT_TRUE(analysis->Dominates(5, 11)); 128 EXPECT_TRUE(analysis->Dominates(5, 23)); 129 EXPECT_TRUE(analysis->Dominates(5, 22)); 130 EXPECT_TRUE(analysis->Dominates(5, 26)); 131 EXPECT_TRUE(analysis->Dominates(8, 18)); 132 EXPECT_TRUE(analysis->Dominates(8, 10)); 133 EXPECT_TRUE(analysis->Dominates(8, 11)); 134 EXPECT_TRUE(analysis->Dominates(21, 23)); 135 EXPECT_TRUE(analysis->Dominates(21, 22)); 136 EXPECT_TRUE(analysis->Dominates(21, 26)); 137 138 EXPECT_TRUE(analysis->StrictlyDominates(5, 8)); 139 EXPECT_TRUE(analysis->StrictlyDominates(5, 9)); 140 EXPECT_TRUE(analysis->StrictlyDominates(5, 21)); 141 EXPECT_TRUE(analysis->StrictlyDominates(8, 18)); 142 EXPECT_TRUE(analysis->StrictlyDominates(8, 10)); 143 EXPECT_TRUE(analysis->StrictlyDominates(8, 11)); 144 EXPECT_TRUE(analysis->StrictlyDominates(21, 23)); 145 EXPECT_TRUE(analysis->StrictlyDominates(21, 22)); 146 EXPECT_TRUE(analysis->StrictlyDominates(21, 26)); 147} 148 149} // namespace 150} // namespace opt 151} // namespace spvtools 152