1fd4e5da5Sopenharmony_ci// Copyright (c) 2022 Google LLC 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 <iostream> 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 18fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 19fd4e5da5Sopenharmony_ci 20fd4e5da5Sopenharmony_cinamespace spvtools { 21fd4e5da5Sopenharmony_cinamespace opt { 22fd4e5da5Sopenharmony_cinamespace { 23fd4e5da5Sopenharmony_ci 24fd4e5da5Sopenharmony_ciusing InterfaceVariableScalarReplacementTest = PassTest<::testing::Test>; 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_ciTEST_F(InterfaceVariableScalarReplacementTest, 27fd4e5da5Sopenharmony_ci ReplaceInterfaceVarsWithScalars) { 28fd4e5da5Sopenharmony_ci const std::string spirv = R"( 29fd4e5da5Sopenharmony_ci OpCapability Shader 30fd4e5da5Sopenharmony_ci OpCapability Tessellation 31fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 32fd4e5da5Sopenharmony_ci OpEntryPoint TessellationControl %func "shader" %x %y %z %w %u %v 33fd4e5da5Sopenharmony_ci 34fd4e5da5Sopenharmony_ci; CHECK: OpName [[x:%\w+]] "x" 35fd4e5da5Sopenharmony_ci; CHECK-NOT: OpName {{%\w+}} "x" 36fd4e5da5Sopenharmony_ci; CHECK: OpName [[y:%\w+]] "y" 37fd4e5da5Sopenharmony_ci; CHECK-NOT: OpName {{%\w+}} "y" 38fd4e5da5Sopenharmony_ci; CHECK: OpName [[z0:%\w+]] "z" 39fd4e5da5Sopenharmony_ci; CHECK: OpName [[z1:%\w+]] "z" 40fd4e5da5Sopenharmony_ci; CHECK: OpName [[w0:%\w+]] "w" 41fd4e5da5Sopenharmony_ci; CHECK: OpName [[w1:%\w+]] "w" 42fd4e5da5Sopenharmony_ci; CHECK: OpName [[u0:%\w+]] "u" 43fd4e5da5Sopenharmony_ci; CHECK: OpName [[u1:%\w+]] "u" 44fd4e5da5Sopenharmony_ci; CHECK: OpName [[v0:%\w+]] "v" 45fd4e5da5Sopenharmony_ci; CHECK: OpName [[v1:%\w+]] "v" 46fd4e5da5Sopenharmony_ci; CHECK: OpName [[v2:%\w+]] "v" 47fd4e5da5Sopenharmony_ci; CHECK: OpName [[v3:%\w+]] "v" 48fd4e5da5Sopenharmony_ci; CHECK: OpName [[v4:%\w+]] "v" 49fd4e5da5Sopenharmony_ci; CHECK: OpName [[v5:%\w+]] "v" 50fd4e5da5Sopenharmony_ci OpName %x "x" 51fd4e5da5Sopenharmony_ci OpName %y "y" 52fd4e5da5Sopenharmony_ci OpName %z "z" 53fd4e5da5Sopenharmony_ci OpName %w "w" 54fd4e5da5Sopenharmony_ci OpName %u "u" 55fd4e5da5Sopenharmony_ci OpName %v "v" 56fd4e5da5Sopenharmony_ci 57fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[x]] Location 2 58fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[y]] Location 0 59fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[z0]] Location 0 60fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[z0]] Component 0 61fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[z1]] Location 1 62fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[z1]] Component 0 63fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[z0]] Patch 64fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[z1]] Patch 65fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[w0]] Location 2 66fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[w0]] Component 0 67fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[w1]] Location 3 68fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[w1]] Component 0 69fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[w0]] Patch 70fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[w1]] Patch 71fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[u0]] Location 3 72fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[u0]] Component 2 73fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[u1]] Location 4 74fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[u1]] Component 2 75fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v0]] Location 3 76fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v0]] Component 3 77fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v1]] Location 4 78fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v1]] Component 3 79fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v2]] Location 5 80fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v2]] Component 3 81fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v3]] Location 6 82fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v3]] Component 3 83fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v4]] Location 7 84fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v4]] Component 3 85fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v5]] Location 8 86fd4e5da5Sopenharmony_ci; CHECK-DAG: OpDecorate [[v5]] Component 3 87fd4e5da5Sopenharmony_ci OpDecorate %z Patch 88fd4e5da5Sopenharmony_ci OpDecorate %w Patch 89fd4e5da5Sopenharmony_ci OpDecorate %z Location 0 90fd4e5da5Sopenharmony_ci OpDecorate %x Location 2 91fd4e5da5Sopenharmony_ci OpDecorate %v Location 3 92fd4e5da5Sopenharmony_ci OpDecorate %v Component 3 93fd4e5da5Sopenharmony_ci OpDecorate %y Location 0 94fd4e5da5Sopenharmony_ci OpDecorate %w Location 2 95fd4e5da5Sopenharmony_ci OpDecorate %u Location 3 96fd4e5da5Sopenharmony_ci OpDecorate %u Component 2 97fd4e5da5Sopenharmony_ci 98fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 99fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 100fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 101fd4e5da5Sopenharmony_ci %uint_3 = OpConstant %uint 3 102fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 103fd4e5da5Sopenharmony_ci%_arr_uint_uint_2 = OpTypeArray %uint %uint_2 104fd4e5da5Sopenharmony_ci%_ptr_Output__arr_uint_uint_2 = OpTypePointer Output %_arr_uint_uint_2 105fd4e5da5Sopenharmony_ci%_ptr_Input__arr_uint_uint_2 = OpTypePointer Input %_arr_uint_uint_2 106fd4e5da5Sopenharmony_ci%_ptr_Input_uint = OpTypePointer Input %uint 107fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 108fd4e5da5Sopenharmony_ci%_arr_arr_uint_uint_2_3 = OpTypeArray %_arr_uint_uint_2 %uint_3 109fd4e5da5Sopenharmony_ci%_ptr_Input__arr_arr_uint_uint_2_3 = OpTypePointer Input %_arr_arr_uint_uint_2_3 110fd4e5da5Sopenharmony_ci%_arr_arr_arr_uint_uint_2_3_4 = OpTypeArray %_arr_arr_uint_uint_2_3 %uint_4 111fd4e5da5Sopenharmony_ci%_ptr_Output__arr_arr_arr_uint_uint_2_3_4 = OpTypePointer Output %_arr_arr_arr_uint_uint_2_3_4 112fd4e5da5Sopenharmony_ci%_ptr_Output__arr_arr_uint_uint_2_3 = OpTypePointer Output %_arr_arr_uint_uint_2_3 113fd4e5da5Sopenharmony_ci %z = OpVariable %_ptr_Output__arr_uint_uint_2 Output 114fd4e5da5Sopenharmony_ci %x = OpVariable %_ptr_Output__arr_uint_uint_2 Output 115fd4e5da5Sopenharmony_ci %y = OpVariable %_ptr_Input__arr_uint_uint_2 Input 116fd4e5da5Sopenharmony_ci %w = OpVariable %_ptr_Input__arr_uint_uint_2 Input 117fd4e5da5Sopenharmony_ci %u = OpVariable %_ptr_Input__arr_arr_uint_uint_2_3 Input 118fd4e5da5Sopenharmony_ci %v = OpVariable %_ptr_Output__arr_arr_arr_uint_uint_2_3_4 Output 119fd4e5da5Sopenharmony_ci 120fd4e5da5Sopenharmony_ci; CHECK-DAG: [[x]] = OpVariable %_ptr_Output__arr_uint_uint_2 Output 121fd4e5da5Sopenharmony_ci; CHECK-DAG: [[y]] = OpVariable %_ptr_Input__arr_uint_uint_2 Input 122fd4e5da5Sopenharmony_ci; CHECK-DAG: [[z0]] = OpVariable %_ptr_Output_uint Output 123fd4e5da5Sopenharmony_ci; CHECK-DAG: [[z1]] = OpVariable %_ptr_Output_uint Output 124fd4e5da5Sopenharmony_ci; CHECK-DAG: [[w0]] = OpVariable %_ptr_Input_uint Input 125fd4e5da5Sopenharmony_ci; CHECK-DAG: [[w1]] = OpVariable %_ptr_Input_uint Input 126fd4e5da5Sopenharmony_ci; CHECK-DAG: [[u0]] = OpVariable %_ptr_Input__arr_uint_uint_3 Input 127fd4e5da5Sopenharmony_ci; CHECK-DAG: [[u1]] = OpVariable %_ptr_Input__arr_uint_uint_3 Input 128fd4e5da5Sopenharmony_ci; CHECK-DAG: [[v0]] = OpVariable %_ptr_Output__arr_uint_uint_4 Output 129fd4e5da5Sopenharmony_ci; CHECK-DAG: [[v1]] = OpVariable %_ptr_Output__arr_uint_uint_4 Output 130fd4e5da5Sopenharmony_ci; CHECK-DAG: [[v2]] = OpVariable %_ptr_Output__arr_uint_uint_4 Output 131fd4e5da5Sopenharmony_ci; CHECK-DAG: [[v3]] = OpVariable %_ptr_Output__arr_uint_uint_4 Output 132fd4e5da5Sopenharmony_ci; CHECK-DAG: [[v4]] = OpVariable %_ptr_Output__arr_uint_uint_4 Output 133fd4e5da5Sopenharmony_ci; CHECK-DAG: [[v5]] = OpVariable %_ptr_Output__arr_uint_uint_4 Output 134fd4e5da5Sopenharmony_ci 135fd4e5da5Sopenharmony_ci %void = OpTypeVoid 136fd4e5da5Sopenharmony_ci %void_f = OpTypeFunction %void 137fd4e5da5Sopenharmony_ci %func = OpFunction %void None %void_f 138fd4e5da5Sopenharmony_ci %label = OpLabel 139fd4e5da5Sopenharmony_ci 140fd4e5da5Sopenharmony_ci; CHECK: [[w0_value:%\w+]] = OpLoad %uint [[w0]] 141fd4e5da5Sopenharmony_ci; CHECK: [[w1_value:%\w+]] = OpLoad %uint [[w1]] 142fd4e5da5Sopenharmony_ci; CHECK: [[w_value:%\w+]] = OpCompositeConstruct %_arr_uint_uint_2 [[w0_value]] [[w1_value]] 143fd4e5da5Sopenharmony_ci; CHECK: [[w0:%\w+]] = OpCompositeExtract %uint [[w_value]] 0 144fd4e5da5Sopenharmony_ci; CHECK: OpStore [[z0]] [[w0]] 145fd4e5da5Sopenharmony_ci; CHECK: [[w1:%\w+]] = OpCompositeExtract %uint [[w_value]] 1 146fd4e5da5Sopenharmony_ci; CHECK: OpStore [[z1]] [[w1]] 147fd4e5da5Sopenharmony_ci %w_value = OpLoad %_arr_uint_uint_2 %w 148fd4e5da5Sopenharmony_ci OpStore %z %w_value 149fd4e5da5Sopenharmony_ci 150fd4e5da5Sopenharmony_ci; CHECK: [[u00_ptr:%\w+]] = OpAccessChain %_ptr_Input_uint [[u0]] %uint_0 151fd4e5da5Sopenharmony_ci; CHECK: [[u00:%\w+]] = OpLoad %uint [[u00_ptr]] 152fd4e5da5Sopenharmony_ci; CHECK: [[u10_ptr:%\w+]] = OpAccessChain %_ptr_Input_uint [[u1]] %uint_0 153fd4e5da5Sopenharmony_ci; CHECK: [[u10:%\w+]] = OpLoad %uint [[u10_ptr]] 154fd4e5da5Sopenharmony_ci; CHECK: [[u01_ptr:%\w+]] = OpAccessChain %_ptr_Input_uint [[u0]] %uint_1 155fd4e5da5Sopenharmony_ci; CHECK: [[u01:%\w+]] = OpLoad %uint [[u01_ptr]] 156fd4e5da5Sopenharmony_ci; CHECK: [[u11_ptr:%\w+]] = OpAccessChain %_ptr_Input_uint [[u1]] %uint_1 157fd4e5da5Sopenharmony_ci; CHECK: [[u11:%\w+]] = OpLoad %uint [[u11_ptr]] 158fd4e5da5Sopenharmony_ci; CHECK: [[u02_ptr:%\w+]] = OpAccessChain %_ptr_Input_uint [[u0]] %uint_2 159fd4e5da5Sopenharmony_ci; CHECK: [[u02:%\w+]] = OpLoad %uint [[u02_ptr]] 160fd4e5da5Sopenharmony_ci; CHECK: [[u12_ptr:%\w+]] = OpAccessChain %_ptr_Input_uint [[u1]] %uint_2 161fd4e5da5Sopenharmony_ci; CHECK: [[u12:%\w+]] = OpLoad %uint [[u12_ptr]] 162fd4e5da5Sopenharmony_ci 163fd4e5da5Sopenharmony_ci; CHECK-DAG: [[u0_val:%\w+]] = OpCompositeConstruct %_arr_uint_uint_2 [[u00]] [[u10]] 164fd4e5da5Sopenharmony_ci; CHECK-DAG: [[u1_val:%\w+]] = OpCompositeConstruct %_arr_uint_uint_2 [[u01]] [[u11]] 165fd4e5da5Sopenharmony_ci; CHECK-DAG: [[u2_val:%\w+]] = OpCompositeConstruct %_arr_uint_uint_2 [[u02]] [[u12]] 166fd4e5da5Sopenharmony_ci 167fd4e5da5Sopenharmony_ci; CHECK: [[u_val:%\w+]] = OpCompositeConstruct %_arr__arr_uint_uint_2_uint_3 [[u0_val]] [[u1_val]] [[u2_val]] 168fd4e5da5Sopenharmony_ci 169fd4e5da5Sopenharmony_ci; CHECK: [[ptr:%\w+]] = OpAccessChain %_ptr_Output_uint [[v0]] %uint_1 170fd4e5da5Sopenharmony_ci; CHECK: [[val:%\w+]] = OpCompositeExtract %uint [[u_val]] 0 0 171fd4e5da5Sopenharmony_ci; CHECK: OpStore [[ptr]] [[val]] 172fd4e5da5Sopenharmony_ci; CHECK: [[ptr:%\w+]] = OpAccessChain %_ptr_Output_uint [[v1]] %uint_1 173fd4e5da5Sopenharmony_ci; CHECK: [[val:%\w+]] = OpCompositeExtract %uint [[u_val]] 0 1 174fd4e5da5Sopenharmony_ci; CHECK: OpStore [[ptr]] [[val]] 175fd4e5da5Sopenharmony_ci; CHECK: [[ptr:%\w+]] = OpAccessChain %_ptr_Output_uint [[v2]] %uint_1 176fd4e5da5Sopenharmony_ci; CHECK: [[val:%\w+]] = OpCompositeExtract %uint [[u_val]] 1 0 177fd4e5da5Sopenharmony_ci; CHECK: OpStore [[ptr]] [[val]] 178fd4e5da5Sopenharmony_ci; CHECK: [[ptr:%\w+]] = OpAccessChain %_ptr_Output_uint [[v3]] %uint_1 179fd4e5da5Sopenharmony_ci; CHECK: [[val:%\w+]] = OpCompositeExtract %uint [[u_val]] 1 1 180fd4e5da5Sopenharmony_ci; CHECK: OpStore [[ptr]] [[val]] 181fd4e5da5Sopenharmony_ci; CHECK: [[ptr:%\w+]] = OpAccessChain %_ptr_Output_uint [[v4]] %uint_1 182fd4e5da5Sopenharmony_ci; CHECK: [[val:%\w+]] = OpCompositeExtract %uint [[u_val]] 2 0 183fd4e5da5Sopenharmony_ci; CHECK: OpStore [[ptr]] [[val]] 184fd4e5da5Sopenharmony_ci; CHECK: [[ptr:%\w+]] = OpAccessChain %_ptr_Output_uint [[v5]] %uint_1 185fd4e5da5Sopenharmony_ci; CHECK: [[val:%\w+]] = OpCompositeExtract %uint [[u_val]] 2 1 186fd4e5da5Sopenharmony_ci; CHECK: OpStore [[ptr]] [[val]] 187fd4e5da5Sopenharmony_ci %v_ptr = OpAccessChain %_ptr_Output__arr_arr_uint_uint_2_3 %v %uint_1 188fd4e5da5Sopenharmony_ci %u_val = OpLoad %_arr_arr_uint_uint_2_3 %u 189fd4e5da5Sopenharmony_ci OpStore %v_ptr %u_val 190fd4e5da5Sopenharmony_ci 191fd4e5da5Sopenharmony_ci OpReturn 192fd4e5da5Sopenharmony_ci OpFunctionEnd 193fd4e5da5Sopenharmony_ci )"; 194fd4e5da5Sopenharmony_ci 195fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InterfaceVariableScalarReplacement>(spirv, true); 196fd4e5da5Sopenharmony_ci} 197fd4e5da5Sopenharmony_ci 198fd4e5da5Sopenharmony_ciTEST_F(InterfaceVariableScalarReplacementTest, 199fd4e5da5Sopenharmony_ci CheckPatchDecorationPreservation) { 200fd4e5da5Sopenharmony_ci // Make sure scalars for the variables with the extra arrayness have the extra 201fd4e5da5Sopenharmony_ci // arrayness after running the pass while others do not have it. 202fd4e5da5Sopenharmony_ci // Only "y" does not have the extra arrayness in the following SPIR-V. 203fd4e5da5Sopenharmony_ci const std::string spirv = R"( 204fd4e5da5Sopenharmony_ci OpCapability Shader 205fd4e5da5Sopenharmony_ci OpCapability Tessellation 206fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 207fd4e5da5Sopenharmony_ci OpEntryPoint TessellationEvaluation %func "shader" %x %y %z %w 208fd4e5da5Sopenharmony_ci OpDecorate %z Patch 209fd4e5da5Sopenharmony_ci OpDecorate %w Patch 210fd4e5da5Sopenharmony_ci OpDecorate %z Location 0 211fd4e5da5Sopenharmony_ci OpDecorate %x Location 2 212fd4e5da5Sopenharmony_ci OpDecorate %y Location 0 213fd4e5da5Sopenharmony_ci OpDecorate %w Location 1 214fd4e5da5Sopenharmony_ci OpName %x "x" 215fd4e5da5Sopenharmony_ci OpName %y "y" 216fd4e5da5Sopenharmony_ci OpName %z "z" 217fd4e5da5Sopenharmony_ci OpName %w "w" 218fd4e5da5Sopenharmony_ci 219fd4e5da5Sopenharmony_ci ; CHECK: OpName [[y:%\w+]] "y" 220fd4e5da5Sopenharmony_ci ; CHECK-NOT: OpName {{%\w+}} "y" 221fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[z0:%\w+]] "z" 222fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[z1:%\w+]] "z" 223fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[w0:%\w+]] "w" 224fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[w1:%\w+]] "w" 225fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[x0:%\w+]] "x" 226fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[x1:%\w+]] "x" 227fd4e5da5Sopenharmony_ci 228fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 229fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 230fd4e5da5Sopenharmony_ci%_arr_uint_uint_2 = OpTypeArray %uint %uint_2 231fd4e5da5Sopenharmony_ci%_ptr_Output__arr_uint_uint_2 = OpTypePointer Output %_arr_uint_uint_2 232fd4e5da5Sopenharmony_ci%_ptr_Input__arr_uint_uint_2 = OpTypePointer Input %_arr_uint_uint_2 233fd4e5da5Sopenharmony_ci %z = OpVariable %_ptr_Output__arr_uint_uint_2 Output 234fd4e5da5Sopenharmony_ci %x = OpVariable %_ptr_Output__arr_uint_uint_2 Output 235fd4e5da5Sopenharmony_ci %y = OpVariable %_ptr_Input__arr_uint_uint_2 Input 236fd4e5da5Sopenharmony_ci %w = OpVariable %_ptr_Input__arr_uint_uint_2 Input 237fd4e5da5Sopenharmony_ci 238fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[y]] = OpVariable %_ptr_Input__arr_uint_uint_2 Input 239fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[z0]] = OpVariable %_ptr_Output_uint Output 240fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[z1]] = OpVariable %_ptr_Output_uint Output 241fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[w0]] = OpVariable %_ptr_Input_uint Input 242fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[w1]] = OpVariable %_ptr_Input_uint Input 243fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[x0]] = OpVariable %_ptr_Output_uint Output 244fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[x1]] = OpVariable %_ptr_Output_uint Output 245fd4e5da5Sopenharmony_ci 246fd4e5da5Sopenharmony_ci %void = OpTypeVoid 247fd4e5da5Sopenharmony_ci %void_f = OpTypeFunction %void 248fd4e5da5Sopenharmony_ci %func = OpFunction %void None %void_f 249fd4e5da5Sopenharmony_ci %label = OpLabel 250fd4e5da5Sopenharmony_ci OpReturn 251fd4e5da5Sopenharmony_ci OpFunctionEnd 252fd4e5da5Sopenharmony_ci )"; 253fd4e5da5Sopenharmony_ci 254fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InterfaceVariableScalarReplacement>(spirv, true); 255fd4e5da5Sopenharmony_ci} 256fd4e5da5Sopenharmony_ci 257fd4e5da5Sopenharmony_ciTEST_F(InterfaceVariableScalarReplacementTest, 258fd4e5da5Sopenharmony_ci CheckEntryPointInterfaceOperands) { 259fd4e5da5Sopenharmony_ci const std::string spirv = R"( 260fd4e5da5Sopenharmony_ci OpCapability Shader 261fd4e5da5Sopenharmony_ci OpCapability Tessellation 262fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 263fd4e5da5Sopenharmony_ci OpEntryPoint TessellationEvaluation %tess "tess" %x %y 264fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %vert "vert" %w 265fd4e5da5Sopenharmony_ci OpDecorate %z Location 0 266fd4e5da5Sopenharmony_ci OpDecorate %x Location 2 267fd4e5da5Sopenharmony_ci OpDecorate %y Location 0 268fd4e5da5Sopenharmony_ci OpDecorate %w Location 1 269fd4e5da5Sopenharmony_ci OpName %x "x" 270fd4e5da5Sopenharmony_ci OpName %y "y" 271fd4e5da5Sopenharmony_ci OpName %z "z" 272fd4e5da5Sopenharmony_ci OpName %w "w" 273fd4e5da5Sopenharmony_ci 274fd4e5da5Sopenharmony_ci ; CHECK: OpName [[y:%\w+]] "y" 275fd4e5da5Sopenharmony_ci ; CHECK-NOT: OpName {{%\w+}} "y" 276fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[x0:%\w+]] "x" 277fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[x1:%\w+]] "x" 278fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[w0:%\w+]] "w" 279fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[w1:%\w+]] "w" 280fd4e5da5Sopenharmony_ci ; CHECK-DAG: OpName [[z:%\w+]] "z" 281fd4e5da5Sopenharmony_ci ; CHECK-NOT: OpName {{%\w+}} "z" 282fd4e5da5Sopenharmony_ci 283fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 284fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 285fd4e5da5Sopenharmony_ci%_arr_uint_uint_2 = OpTypeArray %uint %uint_2 286fd4e5da5Sopenharmony_ci%_ptr_Output__arr_uint_uint_2 = OpTypePointer Output %_arr_uint_uint_2 287fd4e5da5Sopenharmony_ci%_ptr_Input__arr_uint_uint_2 = OpTypePointer Input %_arr_uint_uint_2 288fd4e5da5Sopenharmony_ci %z = OpVariable %_ptr_Output__arr_uint_uint_2 Output 289fd4e5da5Sopenharmony_ci %x = OpVariable %_ptr_Output__arr_uint_uint_2 Output 290fd4e5da5Sopenharmony_ci %y = OpVariable %_ptr_Input__arr_uint_uint_2 Input 291fd4e5da5Sopenharmony_ci %w = OpVariable %_ptr_Input__arr_uint_uint_2 Input 292fd4e5da5Sopenharmony_ci 293fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[y]] = OpVariable %_ptr_Input__arr_uint_uint_2 Input 294fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[z]] = OpVariable %_ptr_Output__arr_uint_uint_2 Output 295fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[w0]] = OpVariable %_ptr_Input_uint Input 296fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[w1]] = OpVariable %_ptr_Input_uint Input 297fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[x0]] = OpVariable %_ptr_Output_uint Output 298fd4e5da5Sopenharmony_ci ; CHECK-DAG: [[x1]] = OpVariable %_ptr_Output_uint Output 299fd4e5da5Sopenharmony_ci 300fd4e5da5Sopenharmony_ci %void = OpTypeVoid 301fd4e5da5Sopenharmony_ci %void_f = OpTypeFunction %void 302fd4e5da5Sopenharmony_ci %tess = OpFunction %void None %void_f 303fd4e5da5Sopenharmony_ci %bb0 = OpLabel 304fd4e5da5Sopenharmony_ci OpReturn 305fd4e5da5Sopenharmony_ci OpFunctionEnd 306fd4e5da5Sopenharmony_ci %vert = OpFunction %void None %void_f 307fd4e5da5Sopenharmony_ci %bb1 = OpLabel 308fd4e5da5Sopenharmony_ci OpReturn 309fd4e5da5Sopenharmony_ci OpFunctionEnd 310fd4e5da5Sopenharmony_ci )"; 311fd4e5da5Sopenharmony_ci 312fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InterfaceVariableScalarReplacement>(spirv, true); 313fd4e5da5Sopenharmony_ci} 314fd4e5da5Sopenharmony_ci 315fd4e5da5Sopenharmony_ciclass InterfaceVarSROAErrorTest : public PassTest<::testing::Test> { 316fd4e5da5Sopenharmony_ci public: 317fd4e5da5Sopenharmony_ci InterfaceVarSROAErrorTest() 318fd4e5da5Sopenharmony_ci : consumer_([this](spv_message_level_t level, const char*, 319fd4e5da5Sopenharmony_ci const spv_position_t& position, const char* message) { 320fd4e5da5Sopenharmony_ci if (!error_message_.empty()) error_message_ += "\n"; 321fd4e5da5Sopenharmony_ci switch (level) { 322fd4e5da5Sopenharmony_ci case SPV_MSG_FATAL: 323fd4e5da5Sopenharmony_ci case SPV_MSG_INTERNAL_ERROR: 324fd4e5da5Sopenharmony_ci case SPV_MSG_ERROR: 325fd4e5da5Sopenharmony_ci error_message_ += "ERROR"; 326fd4e5da5Sopenharmony_ci break; 327fd4e5da5Sopenharmony_ci case SPV_MSG_WARNING: 328fd4e5da5Sopenharmony_ci error_message_ += "WARNING"; 329fd4e5da5Sopenharmony_ci break; 330fd4e5da5Sopenharmony_ci case SPV_MSG_INFO: 331fd4e5da5Sopenharmony_ci error_message_ += "INFO"; 332fd4e5da5Sopenharmony_ci break; 333fd4e5da5Sopenharmony_ci case SPV_MSG_DEBUG: 334fd4e5da5Sopenharmony_ci error_message_ += "DEBUG"; 335fd4e5da5Sopenharmony_ci break; 336fd4e5da5Sopenharmony_ci } 337fd4e5da5Sopenharmony_ci error_message_ += 338fd4e5da5Sopenharmony_ci ": " + std::to_string(position.index) + ": " + message; 339fd4e5da5Sopenharmony_ci }) {} 340fd4e5da5Sopenharmony_ci 341fd4e5da5Sopenharmony_ci Pass::Status RunPass(const std::string& text) { 342fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> context_ = 343fd4e5da5Sopenharmony_ci spvtools::BuildModule(SPV_ENV_UNIVERSAL_1_2, consumer_, text); 344fd4e5da5Sopenharmony_ci if (!context_.get()) return Pass::Status::Failure; 345fd4e5da5Sopenharmony_ci 346fd4e5da5Sopenharmony_ci PassManager manager; 347fd4e5da5Sopenharmony_ci manager.SetMessageConsumer(consumer_); 348fd4e5da5Sopenharmony_ci manager.AddPass<InterfaceVariableScalarReplacement>(); 349fd4e5da5Sopenharmony_ci 350fd4e5da5Sopenharmony_ci return manager.Run(context_.get()); 351fd4e5da5Sopenharmony_ci } 352fd4e5da5Sopenharmony_ci 353fd4e5da5Sopenharmony_ci std::string GetErrorMessage() const { return error_message_; } 354fd4e5da5Sopenharmony_ci 355fd4e5da5Sopenharmony_ci void TearDown() override { error_message_.clear(); } 356fd4e5da5Sopenharmony_ci 357fd4e5da5Sopenharmony_ci private: 358fd4e5da5Sopenharmony_ci spvtools::MessageConsumer consumer_; 359fd4e5da5Sopenharmony_ci std::string error_message_; 360fd4e5da5Sopenharmony_ci}; 361fd4e5da5Sopenharmony_ci 362fd4e5da5Sopenharmony_ciTEST_F(InterfaceVarSROAErrorTest, CheckConflictOfExtraArraynessBetweenEntries) { 363fd4e5da5Sopenharmony_ci const std::string spirv = R"( 364fd4e5da5Sopenharmony_ci OpCapability Shader 365fd4e5da5Sopenharmony_ci OpCapability Tessellation 366fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 367fd4e5da5Sopenharmony_ci OpEntryPoint TessellationControl %tess "tess" %x %y %z 368fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %vert "vert" %z %w 369fd4e5da5Sopenharmony_ci OpDecorate %z Location 0 370fd4e5da5Sopenharmony_ci OpDecorate %x Location 2 371fd4e5da5Sopenharmony_ci OpDecorate %y Location 0 372fd4e5da5Sopenharmony_ci OpDecorate %w Location 1 373fd4e5da5Sopenharmony_ci OpName %x "x" 374fd4e5da5Sopenharmony_ci OpName %y "y" 375fd4e5da5Sopenharmony_ci OpName %z "z" 376fd4e5da5Sopenharmony_ci OpName %w "w" 377fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 378fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 379fd4e5da5Sopenharmony_ci%_arr_uint_uint_2 = OpTypeArray %uint %uint_2 380fd4e5da5Sopenharmony_ci%_ptr_Output__arr_uint_uint_2 = OpTypePointer Output %_arr_uint_uint_2 381fd4e5da5Sopenharmony_ci%_ptr_Input__arr_uint_uint_2 = OpTypePointer Input %_arr_uint_uint_2 382fd4e5da5Sopenharmony_ci %z = OpVariable %_ptr_Output__arr_uint_uint_2 Output 383fd4e5da5Sopenharmony_ci %x = OpVariable %_ptr_Output__arr_uint_uint_2 Output 384fd4e5da5Sopenharmony_ci %y = OpVariable %_ptr_Input__arr_uint_uint_2 Input 385fd4e5da5Sopenharmony_ci %w = OpVariable %_ptr_Input__arr_uint_uint_2 Input 386fd4e5da5Sopenharmony_ci %void = OpTypeVoid 387fd4e5da5Sopenharmony_ci %void_f = OpTypeFunction %void 388fd4e5da5Sopenharmony_ci %tess = OpFunction %void None %void_f 389fd4e5da5Sopenharmony_ci %bb0 = OpLabel 390fd4e5da5Sopenharmony_ci OpReturn 391fd4e5da5Sopenharmony_ci OpFunctionEnd 392fd4e5da5Sopenharmony_ci %vert = OpFunction %void None %void_f 393fd4e5da5Sopenharmony_ci %bb1 = OpLabel 394fd4e5da5Sopenharmony_ci OpReturn 395fd4e5da5Sopenharmony_ci OpFunctionEnd 396fd4e5da5Sopenharmony_ci )"; 397fd4e5da5Sopenharmony_ci 398fd4e5da5Sopenharmony_ci EXPECT_EQ(RunPass(spirv), Pass::Status::Failure); 399fd4e5da5Sopenharmony_ci const char expected_error[] = 400fd4e5da5Sopenharmony_ci "ERROR: 0: A variable is arrayed for an entry point but it is not " 401fd4e5da5Sopenharmony_ci "arrayed for another entry point\n" 402fd4e5da5Sopenharmony_ci " %z = OpVariable %_ptr_Output__arr_uint_uint_2 Output"; 403fd4e5da5Sopenharmony_ci EXPECT_STREQ(GetErrorMessage().c_str(), expected_error); 404fd4e5da5Sopenharmony_ci} 405fd4e5da5Sopenharmony_ci 406fd4e5da5Sopenharmony_ci} // namespace 407fd4e5da5Sopenharmony_ci} // namespace opt 408fd4e5da5Sopenharmony_ci} // namespace spvtools 409