1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2018 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <gtest/gtest.h> 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "nir.h" 27bf215546Sopenharmony_ci#include "nir_builder.h" 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_cinamespace { 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ciclass nir_vars_test : public ::testing::Test { 32bf215546Sopenharmony_ciprotected: 33bf215546Sopenharmony_ci nir_vars_test(); 34bf215546Sopenharmony_ci ~nir_vars_test(); 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci nir_variable *create_var(nir_variable_mode mode, const glsl_type *type, 37bf215546Sopenharmony_ci const char *name) { 38bf215546Sopenharmony_ci if (mode == nir_var_function_temp) 39bf215546Sopenharmony_ci return nir_local_variable_create(b->impl, type, name); 40bf215546Sopenharmony_ci else 41bf215546Sopenharmony_ci return nir_variable_create(b->shader, mode, type, name); 42bf215546Sopenharmony_ci } 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci nir_variable *create_int(nir_variable_mode mode, const char *name) { 45bf215546Sopenharmony_ci return create_var(mode, glsl_int_type(), name); 46bf215546Sopenharmony_ci } 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci nir_variable *create_ivec2(nir_variable_mode mode, const char *name) { 49bf215546Sopenharmony_ci return create_var(mode, glsl_vector_type(GLSL_TYPE_INT, 2), name); 50bf215546Sopenharmony_ci } 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci nir_variable *create_ivec4(nir_variable_mode mode, const char *name) { 53bf215546Sopenharmony_ci return create_var(mode, glsl_vector_type(GLSL_TYPE_INT, 4), name); 54bf215546Sopenharmony_ci } 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci nir_variable **create_many_int(nir_variable_mode mode, const char *prefix, unsigned count) { 57bf215546Sopenharmony_ci nir_variable **result = (nir_variable **)linear_alloc_child(lin_ctx, sizeof(nir_variable *) * count); 58bf215546Sopenharmony_ci for (unsigned i = 0; i < count; i++) 59bf215546Sopenharmony_ci result[i] = create_int(mode, linear_asprintf(lin_ctx, "%s%u", prefix, i)); 60bf215546Sopenharmony_ci return result; 61bf215546Sopenharmony_ci } 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci nir_variable **create_many_ivec2(nir_variable_mode mode, const char *prefix, unsigned count) { 64bf215546Sopenharmony_ci nir_variable **result = (nir_variable **)linear_alloc_child(lin_ctx, sizeof(nir_variable *) * count); 65bf215546Sopenharmony_ci for (unsigned i = 0; i < count; i++) 66bf215546Sopenharmony_ci result[i] = create_ivec2(mode, linear_asprintf(lin_ctx, "%s%u", prefix, i)); 67bf215546Sopenharmony_ci return result; 68bf215546Sopenharmony_ci } 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci nir_variable **create_many_ivec4(nir_variable_mode mode, const char *prefix, unsigned count) { 71bf215546Sopenharmony_ci nir_variable **result = (nir_variable **)linear_alloc_child(lin_ctx, sizeof(nir_variable *) * count); 72bf215546Sopenharmony_ci for (unsigned i = 0; i < count; i++) 73bf215546Sopenharmony_ci result[i] = create_ivec4(mode, linear_asprintf(lin_ctx, "%s%u", prefix, i)); 74bf215546Sopenharmony_ci return result; 75bf215546Sopenharmony_ci } 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci unsigned count_derefs(nir_deref_type deref_type); 78bf215546Sopenharmony_ci unsigned count_intrinsics(nir_intrinsic_op intrinsic); 79bf215546Sopenharmony_ci unsigned count_function_temp_vars(void) { 80bf215546Sopenharmony_ci return exec_list_length(&b->impl->locals); 81bf215546Sopenharmony_ci } 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci unsigned count_shader_temp_vars(void) { 84bf215546Sopenharmony_ci unsigned count = 0; 85bf215546Sopenharmony_ci nir_foreach_variable_with_modes(var, b->shader, nir_var_shader_temp) 86bf215546Sopenharmony_ci count++; 87bf215546Sopenharmony_ci return count; 88bf215546Sopenharmony_ci } 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci nir_intrinsic_instr *get_intrinsic(nir_intrinsic_op intrinsic, 91bf215546Sopenharmony_ci unsigned index); 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci nir_deref_instr *get_deref(nir_deref_type deref_type, 94bf215546Sopenharmony_ci unsigned index); 95bf215546Sopenharmony_ci void *lin_ctx; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci nir_builder *b, _b; 98bf215546Sopenharmony_ci}; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_cinir_vars_test::nir_vars_test() 101bf215546Sopenharmony_ci{ 102bf215546Sopenharmony_ci glsl_type_singleton_init_or_ref(); 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci static const nir_shader_compiler_options options = { }; 105bf215546Sopenharmony_ci _b = nir_builder_init_simple_shader(MESA_SHADER_COMPUTE, &options, 106bf215546Sopenharmony_ci "vars test"); 107bf215546Sopenharmony_ci b = &_b; 108bf215546Sopenharmony_ci lin_ctx = linear_alloc_parent(b->shader, 0); 109bf215546Sopenharmony_ci} 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_cinir_vars_test::~nir_vars_test() 112bf215546Sopenharmony_ci{ 113bf215546Sopenharmony_ci if (HasFailure()) { 114bf215546Sopenharmony_ci printf("\nShader from the failed test:\n\n"); 115bf215546Sopenharmony_ci nir_print_shader(b->shader, stdout); 116bf215546Sopenharmony_ci } 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci ralloc_free(b->shader); 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci glsl_type_singleton_decref(); 121bf215546Sopenharmony_ci} 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ciunsigned 124bf215546Sopenharmony_cinir_vars_test::count_intrinsics(nir_intrinsic_op intrinsic) 125bf215546Sopenharmony_ci{ 126bf215546Sopenharmony_ci unsigned count = 0; 127bf215546Sopenharmony_ci nir_foreach_block(block, b->impl) { 128bf215546Sopenharmony_ci nir_foreach_instr(instr, block) { 129bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 130bf215546Sopenharmony_ci continue; 131bf215546Sopenharmony_ci nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 132bf215546Sopenharmony_ci if (intrin->intrinsic == intrinsic) 133bf215546Sopenharmony_ci count++; 134bf215546Sopenharmony_ci } 135bf215546Sopenharmony_ci } 136bf215546Sopenharmony_ci return count; 137bf215546Sopenharmony_ci} 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ciunsigned 140bf215546Sopenharmony_cinir_vars_test::count_derefs(nir_deref_type deref_type) 141bf215546Sopenharmony_ci{ 142bf215546Sopenharmony_ci unsigned count = 0; 143bf215546Sopenharmony_ci nir_foreach_block(block, b->impl) { 144bf215546Sopenharmony_ci nir_foreach_instr(instr, block) { 145bf215546Sopenharmony_ci if (instr->type != nir_instr_type_deref) 146bf215546Sopenharmony_ci continue; 147bf215546Sopenharmony_ci nir_deref_instr *intrin = nir_instr_as_deref(instr); 148bf215546Sopenharmony_ci if (intrin->deref_type == deref_type) 149bf215546Sopenharmony_ci count++; 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci return count; 153bf215546Sopenharmony_ci} 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_cinir_intrinsic_instr * 156bf215546Sopenharmony_cinir_vars_test::get_intrinsic(nir_intrinsic_op intrinsic, 157bf215546Sopenharmony_ci unsigned index) 158bf215546Sopenharmony_ci{ 159bf215546Sopenharmony_ci nir_foreach_block(block, b->impl) { 160bf215546Sopenharmony_ci nir_foreach_instr(instr, block) { 161bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 162bf215546Sopenharmony_ci continue; 163bf215546Sopenharmony_ci nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 164bf215546Sopenharmony_ci if (intrin->intrinsic == intrinsic) { 165bf215546Sopenharmony_ci if (index == 0) 166bf215546Sopenharmony_ci return intrin; 167bf215546Sopenharmony_ci index--; 168bf215546Sopenharmony_ci } 169bf215546Sopenharmony_ci } 170bf215546Sopenharmony_ci } 171bf215546Sopenharmony_ci return NULL; 172bf215546Sopenharmony_ci} 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_cinir_deref_instr * 175bf215546Sopenharmony_cinir_vars_test::get_deref(nir_deref_type deref_type, 176bf215546Sopenharmony_ci unsigned index) 177bf215546Sopenharmony_ci{ 178bf215546Sopenharmony_ci nir_foreach_block(block, b->impl) { 179bf215546Sopenharmony_ci nir_foreach_instr(instr, block) { 180bf215546Sopenharmony_ci if (instr->type != nir_instr_type_deref) 181bf215546Sopenharmony_ci continue; 182bf215546Sopenharmony_ci nir_deref_instr *deref = nir_instr_as_deref(instr); 183bf215546Sopenharmony_ci if (deref->deref_type == deref_type) { 184bf215546Sopenharmony_ci if (index == 0) 185bf215546Sopenharmony_ci return deref; 186bf215546Sopenharmony_ci index--; 187bf215546Sopenharmony_ci } 188bf215546Sopenharmony_ci } 189bf215546Sopenharmony_ci } 190bf215546Sopenharmony_ci return NULL; 191bf215546Sopenharmony_ci} 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci/* Allow grouping the tests while still sharing the helpers. */ 194bf215546Sopenharmony_ciclass nir_redundant_load_vars_test : public nir_vars_test {}; 195bf215546Sopenharmony_ciclass nir_copy_prop_vars_test : public nir_vars_test {}; 196bf215546Sopenharmony_ciclass nir_dead_write_vars_test : public nir_vars_test {}; 197bf215546Sopenharmony_ciclass nir_combine_stores_test : public nir_vars_test {}; 198bf215546Sopenharmony_ciclass nir_split_vars_test : public nir_vars_test {}; 199bf215546Sopenharmony_ciclass nir_remove_dead_variables_test : public nir_vars_test {}; 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci} // namespace 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_cistatic nir_ssa_def * 204bf215546Sopenharmony_cinir_load_var_volatile(nir_builder *b, nir_variable *var) 205bf215546Sopenharmony_ci{ 206bf215546Sopenharmony_ci return nir_load_deref_with_access(b, nir_build_deref_var(b, var), 207bf215546Sopenharmony_ci ACCESS_VOLATILE); 208bf215546Sopenharmony_ci} 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_cistatic void 211bf215546Sopenharmony_cinir_store_var_volatile(nir_builder *b, nir_variable *var, 212bf215546Sopenharmony_ci nir_ssa_def *value, nir_component_mask_t writemask) 213bf215546Sopenharmony_ci{ 214bf215546Sopenharmony_ci nir_store_deref_with_access(b, nir_build_deref_var(b, var), 215bf215546Sopenharmony_ci value, writemask, ACCESS_VOLATILE); 216bf215546Sopenharmony_ci} 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, duplicated_load) 219bf215546Sopenharmony_ci{ 220bf215546Sopenharmony_ci /* Load a variable twice in the same block. One should be removed. */ 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci nir_variable *in = create_int(nir_var_mem_global, "in"); 223bf215546Sopenharmony_ci nir_variable **out = create_many_int(nir_var_shader_out, "out", 2); 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci nir_store_var(b, out[0], nir_load_var(b, in), 1); 226bf215546Sopenharmony_ci nir_store_var(b, out[1], nir_load_var(b, in), 1); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 2); 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 233bf215546Sopenharmony_ci EXPECT_TRUE(progress); 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 238bf215546Sopenharmony_ci} 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, duplicated_load_volatile) 241bf215546Sopenharmony_ci{ 242bf215546Sopenharmony_ci /* Load a variable twice in the same block. One should be removed. */ 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci nir_variable *in = create_int(nir_var_mem_global, "in"); 245bf215546Sopenharmony_ci nir_variable **out = create_many_int(nir_var_shader_out, "out", 3); 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci /* Volatile prevents us from eliminating a load by combining it with 248bf215546Sopenharmony_ci * another. It shouldn't however, prevent us from combing other 249bf215546Sopenharmony_ci * non-volatile loads. 250bf215546Sopenharmony_ci */ 251bf215546Sopenharmony_ci nir_store_var(b, out[0], nir_load_var(b, in), 1); 252bf215546Sopenharmony_ci nir_store_var(b, out[1], nir_load_var_volatile(b, in), 1); 253bf215546Sopenharmony_ci nir_store_var(b, out[2], nir_load_var(b, in), 1); 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 3); 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 260bf215546Sopenharmony_ci EXPECT_TRUE(progress); 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 2); 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci nir_intrinsic_instr *first_store = get_intrinsic(nir_intrinsic_store_deref, 0); 267bf215546Sopenharmony_ci ASSERT_TRUE(first_store->src[1].is_ssa); 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci nir_intrinsic_instr *third_store = get_intrinsic(nir_intrinsic_store_deref, 2); 270bf215546Sopenharmony_ci ASSERT_TRUE(third_store->src[1].is_ssa); 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci EXPECT_EQ(first_store->src[1].ssa, third_store->src[1].ssa); 273bf215546Sopenharmony_ci} 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, duplicated_load_in_two_blocks) 276bf215546Sopenharmony_ci{ 277bf215546Sopenharmony_ci /* Load a variable twice in different blocks. One should be removed. */ 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci nir_variable *in = create_int(nir_var_mem_global, "in"); 280bf215546Sopenharmony_ci nir_variable **out = create_many_int(nir_var_shader_out, "out", 2); 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci nir_store_var(b, out[0], nir_load_var(b, in), 1); 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci /* Forces the stores to be in different blocks. */ 285bf215546Sopenharmony_ci nir_pop_if(b, nir_push_if(b, nir_imm_int(b, 0))); 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci nir_store_var(b, out[1], nir_load_var(b, in), 1); 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 2); 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 294bf215546Sopenharmony_ci EXPECT_TRUE(progress); 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 299bf215546Sopenharmony_ci} 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, invalidate_inside_if_block) 302bf215546Sopenharmony_ci{ 303bf215546Sopenharmony_ci /* Load variables, then write to some of then in different branches of the 304bf215546Sopenharmony_ci * if statement. They should be invalidated accordingly. 305bf215546Sopenharmony_ci */ 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci nir_variable **g = create_many_int(nir_var_shader_temp, "g", 3); 308bf215546Sopenharmony_ci nir_variable **out = create_many_int(nir_var_shader_out, "out", 3); 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci nir_load_var(b, g[0]); 311bf215546Sopenharmony_ci nir_load_var(b, g[1]); 312bf215546Sopenharmony_ci nir_load_var(b, g[2]); 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci nir_if *if_stmt = nir_push_if(b, nir_imm_int(b, 0)); 315bf215546Sopenharmony_ci nir_store_var(b, g[0], nir_imm_int(b, 10), 1); 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci nir_push_else(b, if_stmt); 318bf215546Sopenharmony_ci nir_store_var(b, g[1], nir_imm_int(b, 20), 1); 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci nir_pop_if(b, if_stmt); 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci nir_store_var(b, out[0], nir_load_var(b, g[0]), 1); 323bf215546Sopenharmony_ci nir_store_var(b, out[1], nir_load_var(b, g[1]), 1); 324bf215546Sopenharmony_ci nir_store_var(b, out[2], nir_load_var(b, g[2]), 1); 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 329bf215546Sopenharmony_ci EXPECT_TRUE(progress); 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci /* There are 3 initial loads, plus 2 loads for the values invalidated 332bf215546Sopenharmony_ci * inside the if statement. 333bf215546Sopenharmony_ci */ 334bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 5); 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci /* We only load g[2] once. */ 337bf215546Sopenharmony_ci unsigned g2_load_count = 0; 338bf215546Sopenharmony_ci for (int i = 0; i < 5; i++) { 339bf215546Sopenharmony_ci nir_intrinsic_instr *load = get_intrinsic(nir_intrinsic_load_deref, i); 340bf215546Sopenharmony_ci if (nir_intrinsic_get_var(load, 0) == g[2]) 341bf215546Sopenharmony_ci g2_load_count++; 342bf215546Sopenharmony_ci } 343bf215546Sopenharmony_ci EXPECT_EQ(g2_load_count, 1); 344bf215546Sopenharmony_ci} 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, invalidate_live_load_in_the_end_of_loop) 347bf215546Sopenharmony_ci{ 348bf215546Sopenharmony_ci /* Invalidating a load in the end of loop body will apply to the whole loop 349bf215546Sopenharmony_ci * body. 350bf215546Sopenharmony_ci */ 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci nir_variable *v = create_int(nir_var_mem_global, "v"); 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci nir_load_var(b, v); 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci nir_loop *loop = nir_push_loop(b); 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci nir_if *if_stmt = nir_push_if(b, nir_imm_int(b, 0)); 359bf215546Sopenharmony_ci nir_jump(b, nir_jump_break); 360bf215546Sopenharmony_ci nir_pop_if(b, if_stmt); 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci nir_load_var(b, v); 363bf215546Sopenharmony_ci nir_store_var(b, v, nir_imm_int(b, 10), 1); 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci nir_pop_loop(b, loop); 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 368bf215546Sopenharmony_ci ASSERT_FALSE(progress); 369bf215546Sopenharmony_ci} 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, simple_copies) 372bf215546Sopenharmony_ci{ 373bf215546Sopenharmony_ci nir_variable *in = create_int(nir_var_shader_in, "in"); 374bf215546Sopenharmony_ci nir_variable *temp = create_int(nir_var_function_temp, "temp"); 375bf215546Sopenharmony_ci nir_variable *out = create_int(nir_var_shader_out, "out"); 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci nir_copy_var(b, temp, in); 378bf215546Sopenharmony_ci nir_copy_var(b, out, temp); 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 383bf215546Sopenharmony_ci EXPECT_TRUE(progress); 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_copy_deref), 2); 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci nir_intrinsic_instr *first_copy = get_intrinsic(nir_intrinsic_copy_deref, 0); 390bf215546Sopenharmony_ci ASSERT_TRUE(first_copy->src[1].is_ssa); 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci nir_intrinsic_instr *second_copy = get_intrinsic(nir_intrinsic_copy_deref, 1); 393bf215546Sopenharmony_ci ASSERT_TRUE(second_copy->src[1].is_ssa); 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci EXPECT_EQ(first_copy->src[1].ssa, second_copy->src[1].ssa); 396bf215546Sopenharmony_ci} 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, self_copy) 399bf215546Sopenharmony_ci{ 400bf215546Sopenharmony_ci nir_variable *v = create_int(nir_var_mem_global, "v"); 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci nir_copy_var(b, v, v); 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 407bf215546Sopenharmony_ci EXPECT_TRUE(progress); 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_copy_deref), 0); 412bf215546Sopenharmony_ci} 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, simple_store_load) 415bf215546Sopenharmony_ci{ 416bf215546Sopenharmony_ci nir_variable **v = create_many_ivec2(nir_var_function_temp, "v", 2); 417bf215546Sopenharmony_ci unsigned mask = 1 | 2; 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci nir_ssa_def *stored_value = nir_imm_ivec2(b, 10, 20); 420bf215546Sopenharmony_ci nir_store_var(b, v[0], stored_value, mask); 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci nir_ssa_def *read_value = nir_load_var(b, v[0]); 423bf215546Sopenharmony_ci nir_store_var(b, v[1], read_value, mask); 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 428bf215546Sopenharmony_ci EXPECT_TRUE(progress); 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 2); 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci for (int i = 0; i < 2; i++) { 435bf215546Sopenharmony_ci nir_intrinsic_instr *store = get_intrinsic(nir_intrinsic_store_deref, i); 436bf215546Sopenharmony_ci ASSERT_TRUE(store->src[1].is_ssa); 437bf215546Sopenharmony_ci EXPECT_EQ(store->src[1].ssa, stored_value); 438bf215546Sopenharmony_ci } 439bf215546Sopenharmony_ci} 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, store_store_load) 442bf215546Sopenharmony_ci{ 443bf215546Sopenharmony_ci nir_variable **v = create_many_ivec2(nir_var_function_temp, "v", 2); 444bf215546Sopenharmony_ci unsigned mask = 1 | 2; 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci nir_ssa_def *first_value = nir_imm_ivec2(b, 10, 20); 447bf215546Sopenharmony_ci nir_store_var(b, v[0], first_value, mask); 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci nir_ssa_def *second_value = nir_imm_ivec2(b, 30, 40); 450bf215546Sopenharmony_ci nir_store_var(b, v[0], second_value, mask); 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci nir_ssa_def *read_value = nir_load_var(b, v[0]); 453bf215546Sopenharmony_ci nir_store_var(b, v[1], read_value, mask); 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 458bf215546Sopenharmony_ci EXPECT_TRUE(progress); 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci /* Store to v[1] should use second_value directly. */ 465bf215546Sopenharmony_ci nir_intrinsic_instr *store_to_v1 = get_intrinsic(nir_intrinsic_store_deref, 2); 466bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store_to_v1, 0), v[1]); 467bf215546Sopenharmony_ci ASSERT_TRUE(store_to_v1->src[1].is_ssa); 468bf215546Sopenharmony_ci EXPECT_EQ(store_to_v1->src[1].ssa, second_value); 469bf215546Sopenharmony_ci} 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, store_store_load_different_components) 472bf215546Sopenharmony_ci{ 473bf215546Sopenharmony_ci nir_variable **v = create_many_ivec2(nir_var_function_temp, "v", 2); 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci nir_ssa_def *first_value = nir_imm_ivec2(b, 10, 20); 476bf215546Sopenharmony_ci nir_store_var(b, v[0], first_value, 1 << 1); 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_ci nir_ssa_def *second_value = nir_imm_ivec2(b, 30, 40); 479bf215546Sopenharmony_ci nir_store_var(b, v[0], second_value, 1 << 0); 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_ci nir_ssa_def *read_value = nir_load_var(b, v[0]); 482bf215546Sopenharmony_ci nir_store_var(b, v[1], read_value, 1 << 1); 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 487bf215546Sopenharmony_ci EXPECT_TRUE(progress); 488bf215546Sopenharmony_ci 489bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci nir_opt_constant_folding(b->shader); 492bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci /* Store to v[1] should use first_value directly. The write of 497bf215546Sopenharmony_ci * second_value did not overwrite the component it uses. 498bf215546Sopenharmony_ci */ 499bf215546Sopenharmony_ci nir_intrinsic_instr *store_to_v1 = get_intrinsic(nir_intrinsic_store_deref, 2); 500bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store_to_v1, 0), v[1]); 501bf215546Sopenharmony_ci ASSERT_EQ(nir_src_comp_as_uint(store_to_v1->src[1], 1), 20); 502bf215546Sopenharmony_ci} 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, store_store_load_different_components_in_many_blocks) 505bf215546Sopenharmony_ci{ 506bf215546Sopenharmony_ci nir_variable **v = create_many_ivec2(nir_var_function_temp, "v", 2); 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci nir_ssa_def *first_value = nir_imm_ivec2(b, 10, 20); 509bf215546Sopenharmony_ci nir_store_var(b, v[0], first_value, 1 << 1); 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci /* Adding an if statement will cause blocks to be created. */ 512bf215546Sopenharmony_ci nir_pop_if(b, nir_push_if(b, nir_imm_int(b, 0))); 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci nir_ssa_def *second_value = nir_imm_ivec2(b, 30, 40); 515bf215546Sopenharmony_ci nir_store_var(b, v[0], second_value, 1 << 0); 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci /* Adding an if statement will cause blocks to be created. */ 518bf215546Sopenharmony_ci nir_pop_if(b, nir_push_if(b, nir_imm_int(b, 0))); 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci nir_ssa_def *read_value = nir_load_var(b, v[0]); 521bf215546Sopenharmony_ci nir_store_var(b, v[1], read_value, 1 << 1); 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 526bf215546Sopenharmony_ci EXPECT_TRUE(progress); 527bf215546Sopenharmony_ci 528bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_ci nir_opt_constant_folding(b->shader); 531bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 534bf215546Sopenharmony_ci 535bf215546Sopenharmony_ci /* Store to v[1] should use first_value directly. The write of 536bf215546Sopenharmony_ci * second_value did not overwrite the component it uses. 537bf215546Sopenharmony_ci */ 538bf215546Sopenharmony_ci nir_intrinsic_instr *store_to_v1 = get_intrinsic(nir_intrinsic_store_deref, 2); 539bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store_to_v1, 0), v[1]); 540bf215546Sopenharmony_ci ASSERT_EQ(nir_src_comp_as_uint(store_to_v1->src[1], 1), 20); 541bf215546Sopenharmony_ci} 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, store_volatile) 544bf215546Sopenharmony_ci{ 545bf215546Sopenharmony_ci nir_variable **v = create_many_ivec2(nir_var_function_temp, "v", 2); 546bf215546Sopenharmony_ci unsigned mask = 1 | 2; 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci nir_ssa_def *first_value = nir_imm_ivec2(b, 10, 20); 549bf215546Sopenharmony_ci nir_store_var(b, v[0], first_value, mask); 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci nir_ssa_def *second_value = nir_imm_ivec2(b, 30, 40); 552bf215546Sopenharmony_ci nir_store_var_volatile(b, v[0], second_value, mask); 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ci nir_ssa_def *third_value = nir_imm_ivec2(b, 50, 60); 555bf215546Sopenharmony_ci nir_store_var(b, v[0], third_value, mask); 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci nir_ssa_def *read_value = nir_load_var(b, v[0]); 558bf215546Sopenharmony_ci nir_store_var(b, v[1], read_value, mask); 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 561bf215546Sopenharmony_ci 562bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 563bf215546Sopenharmony_ci EXPECT_TRUE(progress); 564bf215546Sopenharmony_ci 565bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 4); 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci /* Our approach here is a bit scorched-earth. We expect the volatile store 570bf215546Sopenharmony_ci * in the middle to cause both that store and the one before it to be kept. 571bf215546Sopenharmony_ci * Technically, volatile only prevents combining the volatile store with 572bf215546Sopenharmony_ci * another store and one could argue that the store before the volatile and 573bf215546Sopenharmony_ci * the one after it could be combined. However, it seems safer to just 574bf215546Sopenharmony_ci * treat a volatile store like an atomic and prevent any combining across 575bf215546Sopenharmony_ci * it. 576bf215546Sopenharmony_ci */ 577bf215546Sopenharmony_ci nir_intrinsic_instr *store_to_v1 = get_intrinsic(nir_intrinsic_store_deref, 3); 578bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store_to_v1, 0), v[1]); 579bf215546Sopenharmony_ci ASSERT_TRUE(store_to_v1->src[1].is_ssa); 580bf215546Sopenharmony_ci EXPECT_EQ(store_to_v1->src[1].ssa, third_value); 581bf215546Sopenharmony_ci} 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, self_copy_volatile) 584bf215546Sopenharmony_ci{ 585bf215546Sopenharmony_ci nir_variable *v = create_int(nir_var_mem_global, "v"); 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_ci nir_copy_var(b, v, v); 588bf215546Sopenharmony_ci nir_copy_deref_with_access(b, nir_build_deref_var(b, v), 589bf215546Sopenharmony_ci nir_build_deref_var(b, v), 590bf215546Sopenharmony_ci (gl_access_qualifier)0, ACCESS_VOLATILE); 591bf215546Sopenharmony_ci nir_copy_deref_with_access(b, nir_build_deref_var(b, v), 592bf215546Sopenharmony_ci nir_build_deref_var(b, v), 593bf215546Sopenharmony_ci ACCESS_VOLATILE, (gl_access_qualifier)0); 594bf215546Sopenharmony_ci nir_copy_var(b, v, v); 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 599bf215546Sopenharmony_ci EXPECT_TRUE(progress); 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_copy_deref), 2); 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci /* Store to v[1] should use second_value directly. */ 606bf215546Sopenharmony_ci nir_intrinsic_instr *first = get_intrinsic(nir_intrinsic_copy_deref, 0); 607bf215546Sopenharmony_ci nir_intrinsic_instr *second = get_intrinsic(nir_intrinsic_copy_deref, 1); 608bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_src_access(first), ACCESS_VOLATILE); 609bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_dst_access(first), (gl_access_qualifier)0); 610bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_src_access(second), (gl_access_qualifier)0); 611bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_dst_access(second), ACCESS_VOLATILE); 612bf215546Sopenharmony_ci} 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, memory_barrier_in_two_blocks) 615bf215546Sopenharmony_ci{ 616bf215546Sopenharmony_ci nir_variable **v = create_many_int(nir_var_mem_global, "v", 4); 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_imm_int(b, 1), 1); 619bf215546Sopenharmony_ci nir_store_var(b, v[1], nir_imm_int(b, 2), 1); 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci /* Split into many blocks. */ 622bf215546Sopenharmony_ci nir_pop_if(b, nir_push_if(b, nir_imm_int(b, 0))); 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci nir_store_var(b, v[2], nir_load_var(b, v[0]), 1); 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_ACQ_REL, 627bf215546Sopenharmony_ci nir_var_mem_global); 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_ci nir_store_var(b, v[3], nir_load_var(b, v[1]), 1); 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 632bf215546Sopenharmony_ci ASSERT_TRUE(progress); 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci /* Only the second load will remain after the optimization. */ 635bf215546Sopenharmony_ci ASSERT_EQ(1, count_intrinsics(nir_intrinsic_load_deref)); 636bf215546Sopenharmony_ci nir_intrinsic_instr *load = get_intrinsic(nir_intrinsic_load_deref, 0); 637bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), v[1]); 638bf215546Sopenharmony_ci} 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, acquire_barrier_prevents_load_removal) 641bf215546Sopenharmony_ci{ 642bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 1); 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci nir_load_var(b, x[0]); 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_ACQUIRE, 647bf215546Sopenharmony_ci nir_var_mem_global); 648bf215546Sopenharmony_ci 649bf215546Sopenharmony_ci nir_load_var(b, x[0]); 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 652bf215546Sopenharmony_ci ASSERT_FALSE(progress); 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci ASSERT_EQ(2, count_intrinsics(nir_intrinsic_load_deref)); 655bf215546Sopenharmony_ci} 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, acquire_barrier_prevents_same_mode_load_removal) 658bf215546Sopenharmony_ci{ 659bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 2); 660bf215546Sopenharmony_ci 661bf215546Sopenharmony_ci nir_load_var(b, x[0]); 662bf215546Sopenharmony_ci nir_load_var(b, x[1]); 663bf215546Sopenharmony_ci 664bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_ACQUIRE, 665bf215546Sopenharmony_ci nir_var_mem_global); 666bf215546Sopenharmony_ci 667bf215546Sopenharmony_ci nir_load_var(b, x[0]); 668bf215546Sopenharmony_ci nir_load_var(b, x[1]); 669bf215546Sopenharmony_ci 670bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 671bf215546Sopenharmony_ci ASSERT_FALSE(progress); 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_ci ASSERT_EQ(4, count_intrinsics(nir_intrinsic_load_deref)); 674bf215546Sopenharmony_ci} 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, acquire_barrier_allows_different_mode_load_removal) 677bf215546Sopenharmony_ci{ 678bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 2); 679bf215546Sopenharmony_ci nir_variable **y = create_many_int(nir_var_mem_shared, "y", 2); 680bf215546Sopenharmony_ci 681bf215546Sopenharmony_ci nir_load_var(b, x[0]); 682bf215546Sopenharmony_ci nir_load_var(b, x[1]); 683bf215546Sopenharmony_ci nir_load_var(b, y[0]); 684bf215546Sopenharmony_ci nir_load_var(b, y[1]); 685bf215546Sopenharmony_ci 686bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_ACQUIRE, 687bf215546Sopenharmony_ci nir_var_mem_global); 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci nir_load_var(b, x[0]); 690bf215546Sopenharmony_ci nir_load_var(b, x[1]); 691bf215546Sopenharmony_ci nir_load_var(b, y[0]); 692bf215546Sopenharmony_ci nir_load_var(b, y[1]); 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 695bf215546Sopenharmony_ci ASSERT_TRUE(progress); 696bf215546Sopenharmony_ci 697bf215546Sopenharmony_ci ASSERT_EQ(6, count_intrinsics(nir_intrinsic_load_deref)); 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci nir_intrinsic_instr *load; 700bf215546Sopenharmony_ci 701bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 0); 702bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), x[0]); 703bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 1); 704bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), x[1]); 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 2); 707bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), y[0]); 708bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 3); 709bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), y[1]); 710bf215546Sopenharmony_ci 711bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 4); 712bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), x[0]); 713bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 5); 714bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), x[1]); 715bf215546Sopenharmony_ci} 716bf215546Sopenharmony_ci 717bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, release_barrier_allows_load_removal) 718bf215546Sopenharmony_ci{ 719bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 1); 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci nir_load_var(b, x[0]); 722bf215546Sopenharmony_ci 723bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_RELEASE, 724bf215546Sopenharmony_ci nir_var_mem_global); 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci nir_load_var(b, x[0]); 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 729bf215546Sopenharmony_ci ASSERT_TRUE(progress); 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_ci ASSERT_EQ(1, count_intrinsics(nir_intrinsic_load_deref)); 732bf215546Sopenharmony_ci} 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, release_barrier_allows_same_mode_load_removal) 735bf215546Sopenharmony_ci{ 736bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 2); 737bf215546Sopenharmony_ci 738bf215546Sopenharmony_ci nir_load_var(b, x[0]); 739bf215546Sopenharmony_ci nir_load_var(b, x[1]); 740bf215546Sopenharmony_ci 741bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_RELEASE, 742bf215546Sopenharmony_ci nir_var_mem_global); 743bf215546Sopenharmony_ci 744bf215546Sopenharmony_ci nir_load_var(b, x[0]); 745bf215546Sopenharmony_ci nir_load_var(b, x[1]); 746bf215546Sopenharmony_ci 747bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 748bf215546Sopenharmony_ci ASSERT_TRUE(progress); 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_ci ASSERT_EQ(2, count_intrinsics(nir_intrinsic_load_deref)); 751bf215546Sopenharmony_ci} 752bf215546Sopenharmony_ci 753bf215546Sopenharmony_ciTEST_F(nir_redundant_load_vars_test, release_barrier_allows_different_mode_load_removal) 754bf215546Sopenharmony_ci{ 755bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 2); 756bf215546Sopenharmony_ci nir_variable **y = create_many_int(nir_var_mem_shared, "y", 2); 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_ci nir_load_var(b, x[0]); 759bf215546Sopenharmony_ci nir_load_var(b, x[1]); 760bf215546Sopenharmony_ci nir_load_var(b, y[0]); 761bf215546Sopenharmony_ci nir_load_var(b, y[1]); 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_RELEASE, 764bf215546Sopenharmony_ci nir_var_mem_global); 765bf215546Sopenharmony_ci 766bf215546Sopenharmony_ci nir_load_var(b, x[0]); 767bf215546Sopenharmony_ci nir_load_var(b, x[1]); 768bf215546Sopenharmony_ci nir_load_var(b, y[0]); 769bf215546Sopenharmony_ci nir_load_var(b, y[1]); 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 772bf215546Sopenharmony_ci ASSERT_TRUE(progress); 773bf215546Sopenharmony_ci 774bf215546Sopenharmony_ci ASSERT_EQ(4, count_intrinsics(nir_intrinsic_load_deref)); 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci nir_intrinsic_instr *load; 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 0); 779bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), x[0]); 780bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 1); 781bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), x[1]); 782bf215546Sopenharmony_ci 783bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 2); 784bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), y[0]); 785bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 3); 786bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), y[1]); 787bf215546Sopenharmony_ci} 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, acquire_barrier_prevents_propagation) 790bf215546Sopenharmony_ci{ 791bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 1); 792bf215546Sopenharmony_ci 793bf215546Sopenharmony_ci nir_store_var(b, x[0], nir_imm_int(b, 10), 1); 794bf215546Sopenharmony_ci 795bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_ACQUIRE, 796bf215546Sopenharmony_ci nir_var_mem_global); 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_ci nir_load_var(b, x[0]); 799bf215546Sopenharmony_ci 800bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 801bf215546Sopenharmony_ci ASSERT_FALSE(progress); 802bf215546Sopenharmony_ci 803bf215546Sopenharmony_ci ASSERT_EQ(1, count_intrinsics(nir_intrinsic_store_deref)); 804bf215546Sopenharmony_ci ASSERT_EQ(1, count_intrinsics(nir_intrinsic_load_deref)); 805bf215546Sopenharmony_ci} 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, acquire_barrier_prevents_same_mode_propagation) 808bf215546Sopenharmony_ci{ 809bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 2); 810bf215546Sopenharmony_ci 811bf215546Sopenharmony_ci nir_store_var(b, x[0], nir_imm_int(b, 10), 1); 812bf215546Sopenharmony_ci nir_store_var(b, x[1], nir_imm_int(b, 20), 1); 813bf215546Sopenharmony_ci 814bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_ACQUIRE, 815bf215546Sopenharmony_ci nir_var_mem_global); 816bf215546Sopenharmony_ci 817bf215546Sopenharmony_ci nir_load_var(b, x[0]); 818bf215546Sopenharmony_ci nir_load_var(b, x[1]); 819bf215546Sopenharmony_ci 820bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 821bf215546Sopenharmony_ci ASSERT_FALSE(progress); 822bf215546Sopenharmony_ci 823bf215546Sopenharmony_ci ASSERT_EQ(2, count_intrinsics(nir_intrinsic_store_deref)); 824bf215546Sopenharmony_ci ASSERT_EQ(2, count_intrinsics(nir_intrinsic_load_deref)); 825bf215546Sopenharmony_ci} 826bf215546Sopenharmony_ci 827bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, acquire_barrier_allows_different_mode_propagation) 828bf215546Sopenharmony_ci{ 829bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 2); 830bf215546Sopenharmony_ci nir_variable **y = create_many_int(nir_var_mem_shared, "y", 2); 831bf215546Sopenharmony_ci 832bf215546Sopenharmony_ci nir_store_var(b, x[0], nir_imm_int(b, 10), 1); 833bf215546Sopenharmony_ci nir_store_var(b, x[1], nir_imm_int(b, 20), 1); 834bf215546Sopenharmony_ci nir_store_var(b, y[0], nir_imm_int(b, 30), 1); 835bf215546Sopenharmony_ci nir_store_var(b, y[1], nir_imm_int(b, 40), 1); 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_ACQUIRE, 838bf215546Sopenharmony_ci nir_var_mem_global); 839bf215546Sopenharmony_ci 840bf215546Sopenharmony_ci nir_load_var(b, x[0]); 841bf215546Sopenharmony_ci nir_load_var(b, x[1]); 842bf215546Sopenharmony_ci nir_load_var(b, y[0]); 843bf215546Sopenharmony_ci nir_load_var(b, y[1]); 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 846bf215546Sopenharmony_ci ASSERT_TRUE(progress); 847bf215546Sopenharmony_ci 848bf215546Sopenharmony_ci ASSERT_EQ(4, count_intrinsics(nir_intrinsic_store_deref)); 849bf215546Sopenharmony_ci ASSERT_EQ(2, count_intrinsics(nir_intrinsic_load_deref)); 850bf215546Sopenharmony_ci 851bf215546Sopenharmony_ci nir_intrinsic_instr *store; 852bf215546Sopenharmony_ci 853bf215546Sopenharmony_ci store = get_intrinsic(nir_intrinsic_store_deref, 0); 854bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store, 0), x[0]); 855bf215546Sopenharmony_ci store = get_intrinsic(nir_intrinsic_store_deref, 1); 856bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store, 0), x[1]); 857bf215546Sopenharmony_ci 858bf215546Sopenharmony_ci store = get_intrinsic(nir_intrinsic_store_deref, 2); 859bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store, 0), y[0]); 860bf215546Sopenharmony_ci store = get_intrinsic(nir_intrinsic_store_deref, 3); 861bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store, 0), y[1]); 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ci nir_intrinsic_instr *load; 864bf215546Sopenharmony_ci 865bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 0); 866bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), x[0]); 867bf215546Sopenharmony_ci load = get_intrinsic(nir_intrinsic_load_deref, 1); 868bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), x[1]); 869bf215546Sopenharmony_ci} 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, release_barrier_allows_propagation) 872bf215546Sopenharmony_ci{ 873bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 1); 874bf215546Sopenharmony_ci 875bf215546Sopenharmony_ci nir_store_var(b, x[0], nir_imm_int(b, 10), 1); 876bf215546Sopenharmony_ci 877bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_RELEASE, 878bf215546Sopenharmony_ci nir_var_mem_global); 879bf215546Sopenharmony_ci 880bf215546Sopenharmony_ci nir_load_var(b, x[0]); 881bf215546Sopenharmony_ci 882bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 883bf215546Sopenharmony_ci ASSERT_TRUE(progress); 884bf215546Sopenharmony_ci 885bf215546Sopenharmony_ci ASSERT_EQ(1, count_intrinsics(nir_intrinsic_store_deref)); 886bf215546Sopenharmony_ci} 887bf215546Sopenharmony_ci 888bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, release_barrier_allows_same_mode_propagation) 889bf215546Sopenharmony_ci{ 890bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 2); 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci nir_store_var(b, x[0], nir_imm_int(b, 10), 1); 893bf215546Sopenharmony_ci nir_store_var(b, x[1], nir_imm_int(b, 20), 1); 894bf215546Sopenharmony_ci 895bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_RELEASE, 896bf215546Sopenharmony_ci nir_var_mem_global); 897bf215546Sopenharmony_ci 898bf215546Sopenharmony_ci nir_load_var(b, x[0]); 899bf215546Sopenharmony_ci nir_load_var(b, x[1]); 900bf215546Sopenharmony_ci 901bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 902bf215546Sopenharmony_ci ASSERT_TRUE(progress); 903bf215546Sopenharmony_ci 904bf215546Sopenharmony_ci ASSERT_EQ(2, count_intrinsics(nir_intrinsic_store_deref)); 905bf215546Sopenharmony_ci ASSERT_EQ(0, count_intrinsics(nir_intrinsic_load_deref)); 906bf215546Sopenharmony_ci} 907bf215546Sopenharmony_ci 908bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, release_barrier_allows_different_mode_propagation) 909bf215546Sopenharmony_ci{ 910bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 2); 911bf215546Sopenharmony_ci nir_variable **y = create_many_int(nir_var_mem_shared, "y", 2); 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci nir_store_var(b, x[0], nir_imm_int(b, 10), 1); 914bf215546Sopenharmony_ci nir_store_var(b, x[1], nir_imm_int(b, 20), 1); 915bf215546Sopenharmony_ci nir_store_var(b, y[0], nir_imm_int(b, 30), 1); 916bf215546Sopenharmony_ci nir_store_var(b, y[1], nir_imm_int(b, 40), 1); 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_RELEASE, 919bf215546Sopenharmony_ci nir_var_mem_global); 920bf215546Sopenharmony_ci 921bf215546Sopenharmony_ci nir_load_var(b, x[0]); 922bf215546Sopenharmony_ci nir_load_var(b, x[1]); 923bf215546Sopenharmony_ci nir_load_var(b, y[0]); 924bf215546Sopenharmony_ci nir_load_var(b, y[1]); 925bf215546Sopenharmony_ci 926bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 927bf215546Sopenharmony_ci ASSERT_TRUE(progress); 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci ASSERT_EQ(4, count_intrinsics(nir_intrinsic_store_deref)); 930bf215546Sopenharmony_ci ASSERT_EQ(0, count_intrinsics(nir_intrinsic_load_deref)); 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_ci nir_intrinsic_instr *store; 933bf215546Sopenharmony_ci 934bf215546Sopenharmony_ci store = get_intrinsic(nir_intrinsic_store_deref, 0); 935bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store, 0), x[0]); 936bf215546Sopenharmony_ci store = get_intrinsic(nir_intrinsic_store_deref, 1); 937bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store, 0), x[1]); 938bf215546Sopenharmony_ci 939bf215546Sopenharmony_ci store = get_intrinsic(nir_intrinsic_store_deref, 2); 940bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store, 0), y[0]); 941bf215546Sopenharmony_ci store = get_intrinsic(nir_intrinsic_store_deref, 3); 942bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(store, 0), y[1]); 943bf215546Sopenharmony_ci} 944bf215546Sopenharmony_ci 945bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, acquire_barrier_prevents_propagation_from_copy) 946bf215546Sopenharmony_ci{ 947bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 3); 948bf215546Sopenharmony_ci 949bf215546Sopenharmony_ci nir_copy_var(b, x[1], x[0]); 950bf215546Sopenharmony_ci 951bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_ACQUIRE, 952bf215546Sopenharmony_ci nir_var_mem_global); 953bf215546Sopenharmony_ci 954bf215546Sopenharmony_ci nir_copy_var(b, x[2], x[1]); 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 957bf215546Sopenharmony_ci ASSERT_FALSE(progress); 958bf215546Sopenharmony_ci 959bf215546Sopenharmony_ci ASSERT_EQ(2, count_intrinsics(nir_intrinsic_copy_deref)); 960bf215546Sopenharmony_ci 961bf215546Sopenharmony_ci nir_intrinsic_instr *copy; 962bf215546Sopenharmony_ci 963bf215546Sopenharmony_ci copy = get_intrinsic(nir_intrinsic_copy_deref, 0); 964bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(copy, 1), x[0]); 965bf215546Sopenharmony_ci 966bf215546Sopenharmony_ci copy = get_intrinsic(nir_intrinsic_copy_deref, 1); 967bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(copy, 1), x[1]); 968bf215546Sopenharmony_ci} 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, acquire_barrier_prevents_propagation_from_copy_to_different_mode) 971bf215546Sopenharmony_ci{ 972bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 2); 973bf215546Sopenharmony_ci nir_variable **y = create_many_int(nir_var_mem_shared, "y", 1); 974bf215546Sopenharmony_ci 975bf215546Sopenharmony_ci nir_copy_var(b, y[0], x[0]); 976bf215546Sopenharmony_ci 977bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_ACQUIRE, 978bf215546Sopenharmony_ci nir_var_mem_global); 979bf215546Sopenharmony_ci 980bf215546Sopenharmony_ci nir_copy_var(b, x[1], y[0]); 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 983bf215546Sopenharmony_ci ASSERT_FALSE(progress); 984bf215546Sopenharmony_ci 985bf215546Sopenharmony_ci ASSERT_EQ(2, count_intrinsics(nir_intrinsic_copy_deref)); 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci nir_intrinsic_instr *copy; 988bf215546Sopenharmony_ci 989bf215546Sopenharmony_ci copy = get_intrinsic(nir_intrinsic_copy_deref, 0); 990bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(copy, 1), x[0]); 991bf215546Sopenharmony_ci 992bf215546Sopenharmony_ci copy = get_intrinsic(nir_intrinsic_copy_deref, 1); 993bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(copy, 1), y[0]); 994bf215546Sopenharmony_ci} 995bf215546Sopenharmony_ci 996bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, release_barrier_allows_propagation_from_copy) 997bf215546Sopenharmony_ci{ 998bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 3); 999bf215546Sopenharmony_ci 1000bf215546Sopenharmony_ci nir_copy_var(b, x[1], x[0]); 1001bf215546Sopenharmony_ci 1002bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_RELEASE, 1003bf215546Sopenharmony_ci nir_var_mem_global); 1004bf215546Sopenharmony_ci 1005bf215546Sopenharmony_ci nir_copy_var(b, x[2], x[1]); 1006bf215546Sopenharmony_ci 1007bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1008bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1009bf215546Sopenharmony_ci 1010bf215546Sopenharmony_ci ASSERT_EQ(2, count_intrinsics(nir_intrinsic_copy_deref)); 1011bf215546Sopenharmony_ci 1012bf215546Sopenharmony_ci nir_intrinsic_instr *copy; 1013bf215546Sopenharmony_ci 1014bf215546Sopenharmony_ci copy = get_intrinsic(nir_intrinsic_copy_deref, 0); 1015bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(copy, 1), x[0]); 1016bf215546Sopenharmony_ci 1017bf215546Sopenharmony_ci copy = get_intrinsic(nir_intrinsic_copy_deref, 1); 1018bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(copy, 1), x[0]); 1019bf215546Sopenharmony_ci} 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, release_barrier_allows_propagation_from_copy_to_different_mode) 1022bf215546Sopenharmony_ci{ 1023bf215546Sopenharmony_ci nir_variable **x = create_many_int(nir_var_mem_global, "x", 2); 1024bf215546Sopenharmony_ci nir_variable **y = create_many_int(nir_var_mem_shared, "y", 1); 1025bf215546Sopenharmony_ci 1026bf215546Sopenharmony_ci nir_copy_var(b, y[0], x[0]); 1027bf215546Sopenharmony_ci 1028bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_RELEASE, 1029bf215546Sopenharmony_ci nir_var_mem_global); 1030bf215546Sopenharmony_ci 1031bf215546Sopenharmony_ci nir_copy_var(b, x[1], y[0]); 1032bf215546Sopenharmony_ci 1033bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1034bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1035bf215546Sopenharmony_ci 1036bf215546Sopenharmony_ci ASSERT_EQ(2, count_intrinsics(nir_intrinsic_copy_deref)); 1037bf215546Sopenharmony_ci 1038bf215546Sopenharmony_ci nir_intrinsic_instr *copy; 1039bf215546Sopenharmony_ci 1040bf215546Sopenharmony_ci copy = get_intrinsic(nir_intrinsic_copy_deref, 0); 1041bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(copy, 1), x[0]); 1042bf215546Sopenharmony_ci 1043bf215546Sopenharmony_ci copy = get_intrinsic(nir_intrinsic_copy_deref, 1); 1044bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(copy, 1), x[0]); 1045bf215546Sopenharmony_ci} 1046bf215546Sopenharmony_ci 1047bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, simple_store_load_in_two_blocks) 1048bf215546Sopenharmony_ci{ 1049bf215546Sopenharmony_ci nir_variable **v = create_many_ivec2(nir_var_function_temp, "v", 2); 1050bf215546Sopenharmony_ci unsigned mask = 1 | 2; 1051bf215546Sopenharmony_ci 1052bf215546Sopenharmony_ci nir_ssa_def *stored_value = nir_imm_ivec2(b, 10, 20); 1053bf215546Sopenharmony_ci nir_store_var(b, v[0], stored_value, mask); 1054bf215546Sopenharmony_ci 1055bf215546Sopenharmony_ci /* Adding an if statement will cause blocks to be created. */ 1056bf215546Sopenharmony_ci nir_pop_if(b, nir_push_if(b, nir_imm_int(b, 0))); 1057bf215546Sopenharmony_ci 1058bf215546Sopenharmony_ci nir_ssa_def *read_value = nir_load_var(b, v[0]); 1059bf215546Sopenharmony_ci nir_store_var(b, v[1], read_value, mask); 1060bf215546Sopenharmony_ci 1061bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1062bf215546Sopenharmony_ci 1063bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1064bf215546Sopenharmony_ci EXPECT_TRUE(progress); 1065bf215546Sopenharmony_ci 1066bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1067bf215546Sopenharmony_ci 1068bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 2); 1069bf215546Sopenharmony_ci 1070bf215546Sopenharmony_ci for (int i = 0; i < 2; i++) { 1071bf215546Sopenharmony_ci nir_intrinsic_instr *store = get_intrinsic(nir_intrinsic_store_deref, i); 1072bf215546Sopenharmony_ci ASSERT_TRUE(store->src[1].is_ssa); 1073bf215546Sopenharmony_ci EXPECT_EQ(store->src[1].ssa, stored_value); 1074bf215546Sopenharmony_ci } 1075bf215546Sopenharmony_ci} 1076bf215546Sopenharmony_ci 1077bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, load_direct_array_deref_on_vector_reuses_previous_load) 1078bf215546Sopenharmony_ci{ 1079bf215546Sopenharmony_ci nir_variable *in0 = create_ivec2(nir_var_mem_global, "in0"); 1080bf215546Sopenharmony_ci nir_variable *in1 = create_ivec2(nir_var_mem_global, "in1"); 1081bf215546Sopenharmony_ci nir_variable *vec = create_ivec2(nir_var_mem_global, "vec"); 1082bf215546Sopenharmony_ci nir_variable *out = create_int(nir_var_mem_global, "out"); 1083bf215546Sopenharmony_ci 1084bf215546Sopenharmony_ci nir_store_var(b, vec, nir_load_var(b, in0), 1 << 0); 1085bf215546Sopenharmony_ci nir_store_var(b, vec, nir_load_var(b, in1), 1 << 1); 1086bf215546Sopenharmony_ci 1087bf215546Sopenharmony_ci /* This load will be dropped, as vec.y (or vec[1]) is already known. */ 1088bf215546Sopenharmony_ci nir_deref_instr *deref = 1089bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, vec), 1); 1090bf215546Sopenharmony_ci nir_ssa_def *loaded_from_deref = nir_load_deref(b, deref); 1091bf215546Sopenharmony_ci 1092bf215546Sopenharmony_ci /* This store should use the value loaded from in1. */ 1093bf215546Sopenharmony_ci nir_store_var(b, out, loaded_from_deref, 1 << 0); 1094bf215546Sopenharmony_ci 1095bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1096bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 3); 1097bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1098bf215546Sopenharmony_ci 1099bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1100bf215546Sopenharmony_ci EXPECT_TRUE(progress); 1101bf215546Sopenharmony_ci 1102bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1103bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 2); 1104bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1105bf215546Sopenharmony_ci 1106bf215546Sopenharmony_ci nir_intrinsic_instr *store = get_intrinsic(nir_intrinsic_store_deref, 2); 1107bf215546Sopenharmony_ci ASSERT_TRUE(store->src[1].is_ssa); 1108bf215546Sopenharmony_ci 1109bf215546Sopenharmony_ci /* NOTE: The ALU instruction is how we get the vec.y. */ 1110bf215546Sopenharmony_ci ASSERT_TRUE(nir_src_as_alu_instr(store->src[1])); 1111bf215546Sopenharmony_ci} 1112bf215546Sopenharmony_ci 1113bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, load_direct_array_deref_on_vector_reuses_previous_copy) 1114bf215546Sopenharmony_ci{ 1115bf215546Sopenharmony_ci nir_variable *in0 = create_ivec2(nir_var_mem_global, "in0"); 1116bf215546Sopenharmony_ci nir_variable *vec = create_ivec2(nir_var_mem_global, "vec"); 1117bf215546Sopenharmony_ci 1118bf215546Sopenharmony_ci nir_copy_var(b, vec, in0); 1119bf215546Sopenharmony_ci 1120bf215546Sopenharmony_ci /* This load will be replaced with one from in0. */ 1121bf215546Sopenharmony_ci nir_deref_instr *deref = 1122bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, vec), 1); 1123bf215546Sopenharmony_ci nir_load_deref(b, deref); 1124bf215546Sopenharmony_ci 1125bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1126bf215546Sopenharmony_ci 1127bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1128bf215546Sopenharmony_ci EXPECT_TRUE(progress); 1129bf215546Sopenharmony_ci 1130bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1131bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1132bf215546Sopenharmony_ci 1133bf215546Sopenharmony_ci nir_intrinsic_instr *load = get_intrinsic(nir_intrinsic_load_deref, 0); 1134bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), in0); 1135bf215546Sopenharmony_ci} 1136bf215546Sopenharmony_ci 1137bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, load_direct_array_deref_on_vector_gets_reused) 1138bf215546Sopenharmony_ci{ 1139bf215546Sopenharmony_ci nir_variable *in0 = create_ivec2(nir_var_mem_global, "in0"); 1140bf215546Sopenharmony_ci nir_variable *vec = create_ivec2(nir_var_mem_global, "vec"); 1141bf215546Sopenharmony_ci nir_variable *out = create_ivec2(nir_var_mem_global, "out"); 1142bf215546Sopenharmony_ci 1143bf215546Sopenharmony_ci /* Loading "vec[1]" deref will save the information about vec.y. */ 1144bf215546Sopenharmony_ci nir_deref_instr *deref = 1145bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, vec), 1); 1146bf215546Sopenharmony_ci nir_load_deref(b, deref); 1147bf215546Sopenharmony_ci 1148bf215546Sopenharmony_ci /* Store to vec.x. */ 1149bf215546Sopenharmony_ci nir_store_var(b, vec, nir_load_var(b, in0), 1 << 0); 1150bf215546Sopenharmony_ci 1151bf215546Sopenharmony_ci /* This load will be dropped, since both vec.x and vec.y are known. */ 1152bf215546Sopenharmony_ci nir_ssa_def *loaded_from_vec = nir_load_var(b, vec); 1153bf215546Sopenharmony_ci nir_store_var(b, out, loaded_from_vec, 0x3); 1154bf215546Sopenharmony_ci 1155bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1156bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 3); 1157bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 2); 1158bf215546Sopenharmony_ci 1159bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1160bf215546Sopenharmony_ci EXPECT_TRUE(progress); 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1163bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 2); 1164bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 2); 1165bf215546Sopenharmony_ci 1166bf215546Sopenharmony_ci nir_intrinsic_instr *store = get_intrinsic(nir_intrinsic_store_deref, 1); 1167bf215546Sopenharmony_ci ASSERT_TRUE(store->src[1].is_ssa); 1168bf215546Sopenharmony_ci ASSERT_TRUE(nir_src_as_alu_instr(store->src[1])); 1169bf215546Sopenharmony_ci} 1170bf215546Sopenharmony_ci 1171bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, store_load_direct_array_deref_on_vector) 1172bf215546Sopenharmony_ci{ 1173bf215546Sopenharmony_ci nir_variable *vec = create_ivec2(nir_var_mem_global, "vec"); 1174bf215546Sopenharmony_ci nir_variable *out0 = create_int(nir_var_mem_global, "out0"); 1175bf215546Sopenharmony_ci nir_variable *out1 = create_ivec2(nir_var_mem_global, "out1"); 1176bf215546Sopenharmony_ci 1177bf215546Sopenharmony_ci /* Store to "vec[1]" and "vec[0]". */ 1178bf215546Sopenharmony_ci nir_deref_instr *store_deref_y = 1179bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, vec), 1); 1180bf215546Sopenharmony_ci nir_store_deref(b, store_deref_y, nir_imm_int(b, 20), 1); 1181bf215546Sopenharmony_ci 1182bf215546Sopenharmony_ci nir_deref_instr *store_deref_x = 1183bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, vec), 0); 1184bf215546Sopenharmony_ci nir_store_deref(b, store_deref_x, nir_imm_int(b, 10), 1); 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci /* Both loads below will be dropped, because the values are already known. */ 1187bf215546Sopenharmony_ci nir_deref_instr *load_deref_y = 1188bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, vec), 1); 1189bf215546Sopenharmony_ci nir_store_var(b, out0, nir_load_deref(b, load_deref_y), 1); 1190bf215546Sopenharmony_ci 1191bf215546Sopenharmony_ci nir_store_var(b, out1, nir_load_var(b, vec), 1); 1192bf215546Sopenharmony_ci 1193bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1194bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 2); 1195bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 4); 1196bf215546Sopenharmony_ci 1197bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1198bf215546Sopenharmony_ci EXPECT_TRUE(progress); 1199bf215546Sopenharmony_ci 1200bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1201bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 0); 1202bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 4); 1203bf215546Sopenharmony_ci 1204bf215546Sopenharmony_ci /* Third store will just use the value from first store. */ 1205bf215546Sopenharmony_ci nir_intrinsic_instr *first_store = get_intrinsic(nir_intrinsic_store_deref, 0); 1206bf215546Sopenharmony_ci nir_intrinsic_instr *third_store = get_intrinsic(nir_intrinsic_store_deref, 2); 1207bf215546Sopenharmony_ci ASSERT_TRUE(third_store->src[1].is_ssa); 1208bf215546Sopenharmony_ci EXPECT_EQ(third_store->src[1].ssa, first_store->src[1].ssa); 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_ci /* Fourth store will compose first and second store values. */ 1211bf215546Sopenharmony_ci nir_intrinsic_instr *fourth_store = get_intrinsic(nir_intrinsic_store_deref, 3); 1212bf215546Sopenharmony_ci ASSERT_TRUE(fourth_store->src[1].is_ssa); 1213bf215546Sopenharmony_ci EXPECT_TRUE(nir_src_as_alu_instr(fourth_store->src[1])); 1214bf215546Sopenharmony_ci} 1215bf215546Sopenharmony_ci 1216bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, store_load_indirect_array_deref_on_vector) 1217bf215546Sopenharmony_ci{ 1218bf215546Sopenharmony_ci nir_variable *vec = create_ivec2(nir_var_mem_global, "vec"); 1219bf215546Sopenharmony_ci nir_variable *idx = create_int(nir_var_mem_global, "idx"); 1220bf215546Sopenharmony_ci nir_variable *out = create_int(nir_var_mem_global, "out"); 1221bf215546Sopenharmony_ci 1222bf215546Sopenharmony_ci nir_ssa_def *idx_ssa = nir_load_var(b, idx); 1223bf215546Sopenharmony_ci 1224bf215546Sopenharmony_ci /* Store to vec[idx]. */ 1225bf215546Sopenharmony_ci nir_deref_instr *store_deref = 1226bf215546Sopenharmony_ci nir_build_deref_array(b, nir_build_deref_var(b, vec), idx_ssa); 1227bf215546Sopenharmony_ci nir_store_deref(b, store_deref, nir_imm_int(b, 20), 1); 1228bf215546Sopenharmony_ci 1229bf215546Sopenharmony_ci /* Load from vec[idx] to store in out. This load should be dropped. */ 1230bf215546Sopenharmony_ci nir_deref_instr *load_deref = 1231bf215546Sopenharmony_ci nir_build_deref_array(b, nir_build_deref_var(b, vec), idx_ssa); 1232bf215546Sopenharmony_ci nir_store_var(b, out, nir_load_deref(b, load_deref), 1); 1233bf215546Sopenharmony_ci 1234bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1235bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 2); 1236bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 2); 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1239bf215546Sopenharmony_ci EXPECT_TRUE(progress); 1240bf215546Sopenharmony_ci 1241bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1242bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1243bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 2); 1244bf215546Sopenharmony_ci 1245bf215546Sopenharmony_ci /* Store to vec[idx] propagated to out. */ 1246bf215546Sopenharmony_ci nir_intrinsic_instr *first = get_intrinsic(nir_intrinsic_store_deref, 0); 1247bf215546Sopenharmony_ci nir_intrinsic_instr *second = get_intrinsic(nir_intrinsic_store_deref, 1); 1248bf215546Sopenharmony_ci ASSERT_TRUE(first->src[1].is_ssa); 1249bf215546Sopenharmony_ci ASSERT_TRUE(second->src[1].is_ssa); 1250bf215546Sopenharmony_ci EXPECT_EQ(first->src[1].ssa, second->src[1].ssa); 1251bf215546Sopenharmony_ci} 1252bf215546Sopenharmony_ci 1253bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, store_load_direct_and_indirect_array_deref_on_vector) 1254bf215546Sopenharmony_ci{ 1255bf215546Sopenharmony_ci nir_variable *vec = create_ivec2(nir_var_mem_global, "vec"); 1256bf215546Sopenharmony_ci nir_variable *idx = create_int(nir_var_mem_global, "idx"); 1257bf215546Sopenharmony_ci nir_variable **out = create_many_int(nir_var_mem_global, "out", 2); 1258bf215546Sopenharmony_ci 1259bf215546Sopenharmony_ci nir_ssa_def *idx_ssa = nir_load_var(b, idx); 1260bf215546Sopenharmony_ci 1261bf215546Sopenharmony_ci /* Store to vec. */ 1262bf215546Sopenharmony_ci nir_store_var(b, vec, nir_imm_ivec2(b, 10, 10), 1 | 2); 1263bf215546Sopenharmony_ci 1264bf215546Sopenharmony_ci /* Load from vec[idx]. This load is currently not dropped. */ 1265bf215546Sopenharmony_ci nir_deref_instr *indirect = 1266bf215546Sopenharmony_ci nir_build_deref_array(b, nir_build_deref_var(b, vec), idx_ssa); 1267bf215546Sopenharmony_ci nir_store_var(b, out[0], nir_load_deref(b, indirect), 1); 1268bf215546Sopenharmony_ci 1269bf215546Sopenharmony_ci /* Load from vec[idx] again. This load should be dropped. */ 1270bf215546Sopenharmony_ci nir_store_var(b, out[1], nir_load_deref(b, indirect), 1); 1271bf215546Sopenharmony_ci 1272bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1273bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 3); 1274bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1275bf215546Sopenharmony_ci 1276bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1277bf215546Sopenharmony_ci EXPECT_TRUE(progress); 1278bf215546Sopenharmony_ci 1279bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1280bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 2); 1281bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1282bf215546Sopenharmony_ci 1283bf215546Sopenharmony_ci /* Store to vec[idx] propagated to out. */ 1284bf215546Sopenharmony_ci nir_intrinsic_instr *second = get_intrinsic(nir_intrinsic_store_deref, 1); 1285bf215546Sopenharmony_ci nir_intrinsic_instr *third = get_intrinsic(nir_intrinsic_store_deref, 2); 1286bf215546Sopenharmony_ci ASSERT_TRUE(second->src[1].is_ssa); 1287bf215546Sopenharmony_ci ASSERT_TRUE(third->src[1].is_ssa); 1288bf215546Sopenharmony_ci EXPECT_EQ(second->src[1].ssa, third->src[1].ssa); 1289bf215546Sopenharmony_ci} 1290bf215546Sopenharmony_ci 1291bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, store_load_indirect_array_deref) 1292bf215546Sopenharmony_ci{ 1293bf215546Sopenharmony_ci nir_variable *arr = create_var(nir_var_mem_global, 1294bf215546Sopenharmony_ci glsl_array_type(glsl_int_type(), 10, 0), 1295bf215546Sopenharmony_ci "arr"); 1296bf215546Sopenharmony_ci nir_variable *idx = create_int(nir_var_mem_global, "idx"); 1297bf215546Sopenharmony_ci nir_variable *out = create_int(nir_var_mem_global, "out"); 1298bf215546Sopenharmony_ci 1299bf215546Sopenharmony_ci nir_ssa_def *idx_ssa = nir_load_var(b, idx); 1300bf215546Sopenharmony_ci 1301bf215546Sopenharmony_ci /* Store to arr[idx]. */ 1302bf215546Sopenharmony_ci nir_deref_instr *store_deref = 1303bf215546Sopenharmony_ci nir_build_deref_array(b, nir_build_deref_var(b, arr), idx_ssa); 1304bf215546Sopenharmony_ci nir_store_deref(b, store_deref, nir_imm_int(b, 20), 1); 1305bf215546Sopenharmony_ci 1306bf215546Sopenharmony_ci /* Load from arr[idx] to store in out. This load should be dropped. */ 1307bf215546Sopenharmony_ci nir_deref_instr *load_deref = 1308bf215546Sopenharmony_ci nir_build_deref_array(b, nir_build_deref_var(b, arr), idx_ssa); 1309bf215546Sopenharmony_ci nir_store_var(b, out, nir_load_deref(b, load_deref), 1); 1310bf215546Sopenharmony_ci 1311bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1312bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 2); 1313bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 2); 1314bf215546Sopenharmony_ci 1315bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1316bf215546Sopenharmony_ci EXPECT_TRUE(progress); 1317bf215546Sopenharmony_ci 1318bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1319bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1320bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 2); 1321bf215546Sopenharmony_ci 1322bf215546Sopenharmony_ci /* Store to arr[idx] propagated to out. */ 1323bf215546Sopenharmony_ci nir_intrinsic_instr *first = get_intrinsic(nir_intrinsic_store_deref, 0); 1324bf215546Sopenharmony_ci nir_intrinsic_instr *second = get_intrinsic(nir_intrinsic_store_deref, 1); 1325bf215546Sopenharmony_ci ASSERT_TRUE(first->src[1].is_ssa); 1326bf215546Sopenharmony_ci ASSERT_TRUE(second->src[1].is_ssa); 1327bf215546Sopenharmony_ci EXPECT_EQ(first->src[1].ssa, second->src[1].ssa); 1328bf215546Sopenharmony_ci} 1329bf215546Sopenharmony_ci 1330bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, restrict_ssbo_bindings) 1331bf215546Sopenharmony_ci{ 1332bf215546Sopenharmony_ci glsl_struct_field field = glsl_struct_field(); 1333bf215546Sopenharmony_ci field.type = glsl_int_type(); 1334bf215546Sopenharmony_ci field.name = "x"; 1335bf215546Sopenharmony_ci const glsl_type *ifc_type = 1336bf215546Sopenharmony_ci glsl_type::get_interface_instance(&field, 1, 1337bf215546Sopenharmony_ci GLSL_INTERFACE_PACKING_STD430, 1338bf215546Sopenharmony_ci false /* row_major */, "b"); 1339bf215546Sopenharmony_ci nir_variable *ssbo0 = create_var(nir_var_mem_ssbo, ifc_type, "ssbo0"); 1340bf215546Sopenharmony_ci nir_variable *ssbo1 = create_var(nir_var_mem_ssbo, ifc_type, "ssbo1"); 1341bf215546Sopenharmony_ci ssbo0->data.access = ssbo1->data.access = ACCESS_RESTRICT; 1342bf215546Sopenharmony_ci nir_variable *out = create_var(nir_var_mem_ssbo, ifc_type, "out"); 1343bf215546Sopenharmony_ci out->data.access = ACCESS_RESTRICT; 1344bf215546Sopenharmony_ci 1345bf215546Sopenharmony_ci nir_deref_instr *ssbo0_x = 1346bf215546Sopenharmony_ci nir_build_deref_struct(b, nir_build_deref_var(b, ssbo0), 0); 1347bf215546Sopenharmony_ci nir_store_deref(b, ssbo0_x, nir_imm_int(b, 20), 1); 1348bf215546Sopenharmony_ci 1349bf215546Sopenharmony_ci nir_deref_instr *ssbo1_x = 1350bf215546Sopenharmony_ci nir_build_deref_struct(b, nir_build_deref_var(b, ssbo1), 0); 1351bf215546Sopenharmony_ci nir_store_deref(b, ssbo1_x, nir_imm_int(b, 30), 1); 1352bf215546Sopenharmony_ci 1353bf215546Sopenharmony_ci /* Load ssbo0.x and store it in out.x. This load should be dropped */ 1354bf215546Sopenharmony_ci nir_deref_instr *out_x = 1355bf215546Sopenharmony_ci nir_build_deref_struct(b, nir_build_deref_var(b, out), 0); 1356bf215546Sopenharmony_ci nir_store_deref(b, out_x, nir_load_deref(b, ssbo0_x), 1); 1357bf215546Sopenharmony_ci 1358bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1359bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1360bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1361bf215546Sopenharmony_ci 1362bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1363bf215546Sopenharmony_ci EXPECT_TRUE(progress); 1364bf215546Sopenharmony_ci 1365bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1366bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 0); 1367bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1368bf215546Sopenharmony_ci 1369bf215546Sopenharmony_ci /* Store to b0.x propagated to out. */ 1370bf215546Sopenharmony_ci nir_intrinsic_instr *first = get_intrinsic(nir_intrinsic_store_deref, 0); 1371bf215546Sopenharmony_ci nir_intrinsic_instr *third = get_intrinsic(nir_intrinsic_store_deref, 2); 1372bf215546Sopenharmony_ci ASSERT_TRUE(first->src[1].is_ssa); 1373bf215546Sopenharmony_ci ASSERT_TRUE(third->src[1].is_ssa); 1374bf215546Sopenharmony_ci EXPECT_EQ(first->src[1].ssa, third->src[1].ssa); 1375bf215546Sopenharmony_ci} 1376bf215546Sopenharmony_ci 1377bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, aliasing_ssbo_bindings) 1378bf215546Sopenharmony_ci{ 1379bf215546Sopenharmony_ci glsl_struct_field field = glsl_struct_field(); 1380bf215546Sopenharmony_ci field.type = glsl_int_type(); 1381bf215546Sopenharmony_ci field.name = "x"; 1382bf215546Sopenharmony_ci const glsl_type *ifc_type = 1383bf215546Sopenharmony_ci glsl_type::get_interface_instance(&field, 1, 1384bf215546Sopenharmony_ci GLSL_INTERFACE_PACKING_STD430, 1385bf215546Sopenharmony_ci false /* row_major */, "b"); 1386bf215546Sopenharmony_ci nir_variable *ssbo0 = create_var(nir_var_mem_ssbo, ifc_type, "ssbo0"); 1387bf215546Sopenharmony_ci nir_variable *ssbo1 = create_var(nir_var_mem_ssbo, ifc_type, "ssbo1"); 1388bf215546Sopenharmony_ci nir_variable *out = create_var(nir_var_mem_ssbo, ifc_type, "out"); 1389bf215546Sopenharmony_ci out->data.access = ACCESS_RESTRICT; 1390bf215546Sopenharmony_ci 1391bf215546Sopenharmony_ci nir_deref_instr *ssbo0_x = 1392bf215546Sopenharmony_ci nir_build_deref_struct(b, nir_build_deref_var(b, ssbo0), 0); 1393bf215546Sopenharmony_ci nir_store_deref(b, ssbo0_x, nir_imm_int(b, 20), 1); 1394bf215546Sopenharmony_ci 1395bf215546Sopenharmony_ci nir_deref_instr *ssbo1_x = 1396bf215546Sopenharmony_ci nir_build_deref_struct(b, nir_build_deref_var(b, ssbo1), 0); 1397bf215546Sopenharmony_ci nir_store_deref(b, ssbo1_x, nir_imm_int(b, 30), 1); 1398bf215546Sopenharmony_ci 1399bf215546Sopenharmony_ci /* Load ssbo0.x and store it in out.x. This load should not be dropped */ 1400bf215546Sopenharmony_ci nir_deref_instr *out_x = 1401bf215546Sopenharmony_ci nir_build_deref_struct(b, nir_build_deref_var(b, out), 0); 1402bf215546Sopenharmony_ci nir_store_deref(b, out_x, nir_load_deref(b, ssbo0_x), 1); 1403bf215546Sopenharmony_ci 1404bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1405bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1406bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1407bf215546Sopenharmony_ci 1408bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1409bf215546Sopenharmony_ci EXPECT_FALSE(progress); 1410bf215546Sopenharmony_ci 1411bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1412bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1413bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1414bf215546Sopenharmony_ci} 1415bf215546Sopenharmony_ci 1416bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, ssbo_array_binding_indirect) 1417bf215546Sopenharmony_ci{ 1418bf215546Sopenharmony_ci glsl_struct_field field = glsl_struct_field(); 1419bf215546Sopenharmony_ci field.type = glsl_int_type(); 1420bf215546Sopenharmony_ci field.name = "x"; 1421bf215546Sopenharmony_ci const glsl_type *ifc_type = 1422bf215546Sopenharmony_ci glsl_type::get_interface_instance(&field, 1, 1423bf215546Sopenharmony_ci GLSL_INTERFACE_PACKING_STD430, 1424bf215546Sopenharmony_ci false /* row_major */, "b"); 1425bf215546Sopenharmony_ci const glsl_type *arr_ifc_type = glsl_type::get_array_instance(ifc_type, 2); 1426bf215546Sopenharmony_ci nir_variable *ssbo_arr = create_var(nir_var_mem_ssbo, arr_ifc_type, 1427bf215546Sopenharmony_ci "ssbo_arr"); 1428bf215546Sopenharmony_ci ssbo_arr->data.access = ACCESS_RESTRICT; 1429bf215546Sopenharmony_ci nir_variable *out = create_var(nir_var_mem_ssbo, ifc_type, "out"); 1430bf215546Sopenharmony_ci out->data.access = ACCESS_RESTRICT; 1431bf215546Sopenharmony_ci 1432bf215546Sopenharmony_ci nir_deref_instr *ssbo_0 = 1433bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, ssbo_arr), 0); 1434bf215546Sopenharmony_ci nir_deref_instr *ssbo_0_x = nir_build_deref_struct(b, ssbo_0, 0); 1435bf215546Sopenharmony_ci nir_store_deref(b, ssbo_0_x, nir_imm_int(b, 20), 1); 1436bf215546Sopenharmony_ci 1437bf215546Sopenharmony_ci nir_deref_instr *ssbo_i = 1438bf215546Sopenharmony_ci nir_build_deref_array(b, nir_build_deref_var(b, ssbo_arr), 1439bf215546Sopenharmony_ci nir_load_local_invocation_index(b)); 1440bf215546Sopenharmony_ci nir_deref_instr *ssbo_i_x = nir_build_deref_struct(b, ssbo_i, 0); 1441bf215546Sopenharmony_ci nir_store_deref(b, ssbo_i_x, nir_imm_int(b, 30), 1); 1442bf215546Sopenharmony_ci 1443bf215546Sopenharmony_ci /* Load ssbo_arr[0].x and store it in out.x. This load should not be dropped */ 1444bf215546Sopenharmony_ci nir_deref_instr *out_x = 1445bf215546Sopenharmony_ci nir_build_deref_struct(b, nir_build_deref_var(b, out), 0); 1446bf215546Sopenharmony_ci nir_store_deref(b, out_x, nir_load_deref(b, ssbo_0_x), 1); 1447bf215546Sopenharmony_ci 1448bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1449bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1450bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1451bf215546Sopenharmony_ci 1452bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1453bf215546Sopenharmony_ci EXPECT_FALSE(progress); 1454bf215546Sopenharmony_ci 1455bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1456bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1457bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1458bf215546Sopenharmony_ci} 1459bf215546Sopenharmony_ci 1460bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, restrict_ssbo_array_binding) 1461bf215546Sopenharmony_ci{ 1462bf215546Sopenharmony_ci glsl_struct_field field = glsl_struct_field(); 1463bf215546Sopenharmony_ci field.type = glsl_int_type(); 1464bf215546Sopenharmony_ci field.name = "x"; 1465bf215546Sopenharmony_ci const glsl_type *ifc_type = 1466bf215546Sopenharmony_ci glsl_type::get_interface_instance(&field, 1, 1467bf215546Sopenharmony_ci GLSL_INTERFACE_PACKING_STD430, 1468bf215546Sopenharmony_ci false /* row_major */, "b"); 1469bf215546Sopenharmony_ci const glsl_type *arr_ifc_type = glsl_type::get_array_instance(ifc_type, 2); 1470bf215546Sopenharmony_ci nir_variable *ssbo_arr = create_var(nir_var_mem_ssbo, arr_ifc_type, 1471bf215546Sopenharmony_ci "ssbo_arr"); 1472bf215546Sopenharmony_ci ssbo_arr->data.access = ACCESS_RESTRICT; 1473bf215546Sopenharmony_ci nir_variable *out = create_var(nir_var_mem_ssbo, ifc_type, "out"); 1474bf215546Sopenharmony_ci out->data.access = ACCESS_RESTRICT; 1475bf215546Sopenharmony_ci 1476bf215546Sopenharmony_ci nir_deref_instr *ssbo_0 = 1477bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, ssbo_arr), 0); 1478bf215546Sopenharmony_ci nir_deref_instr *ssbo_0_x = nir_build_deref_struct(b, ssbo_0, 0); 1479bf215546Sopenharmony_ci nir_store_deref(b, ssbo_0_x, nir_imm_int(b, 20), 1); 1480bf215546Sopenharmony_ci 1481bf215546Sopenharmony_ci nir_deref_instr *ssbo_1 = 1482bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, ssbo_arr), 1); 1483bf215546Sopenharmony_ci nir_deref_instr *ssbo_1_x = nir_build_deref_struct(b, ssbo_1, 0); 1484bf215546Sopenharmony_ci nir_store_deref(b, ssbo_1_x, nir_imm_int(b, 30), 1); 1485bf215546Sopenharmony_ci 1486bf215546Sopenharmony_ci /* Load ssbo_arr[0].x and store it in out.x. This load should be dropped */ 1487bf215546Sopenharmony_ci nir_deref_instr *out_x = 1488bf215546Sopenharmony_ci nir_build_deref_struct(b, nir_build_deref_var(b, out), 0); 1489bf215546Sopenharmony_ci nir_store_deref(b, out_x, nir_load_deref(b, ssbo_0_x), 1); 1490bf215546Sopenharmony_ci 1491bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1492bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1493bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1494bf215546Sopenharmony_ci 1495bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1496bf215546Sopenharmony_ci EXPECT_TRUE(progress); 1497bf215546Sopenharmony_ci 1498bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1499bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 0); 1500bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1501bf215546Sopenharmony_ci 1502bf215546Sopenharmony_ci /* Store to b0.x propagated to out. */ 1503bf215546Sopenharmony_ci nir_intrinsic_instr *first = get_intrinsic(nir_intrinsic_store_deref, 0); 1504bf215546Sopenharmony_ci nir_intrinsic_instr *third = get_intrinsic(nir_intrinsic_store_deref, 2); 1505bf215546Sopenharmony_ci ASSERT_TRUE(first->src[1].is_ssa); 1506bf215546Sopenharmony_ci ASSERT_TRUE(third->src[1].is_ssa); 1507bf215546Sopenharmony_ci EXPECT_EQ(first->src[1].ssa, third->src[1].ssa); 1508bf215546Sopenharmony_ci} 1509bf215546Sopenharmony_ci 1510bf215546Sopenharmony_ciTEST_F(nir_copy_prop_vars_test, aliasing_ssbo_array_binding) 1511bf215546Sopenharmony_ci{ 1512bf215546Sopenharmony_ci glsl_struct_field field = glsl_struct_field(); 1513bf215546Sopenharmony_ci field.type = glsl_int_type(); 1514bf215546Sopenharmony_ci field.name = "x"; 1515bf215546Sopenharmony_ci const glsl_type *ifc_type = 1516bf215546Sopenharmony_ci glsl_type::get_interface_instance(&field, 1, 1517bf215546Sopenharmony_ci GLSL_INTERFACE_PACKING_STD430, 1518bf215546Sopenharmony_ci false /* row_major */, "b"); 1519bf215546Sopenharmony_ci const glsl_type *arr_ifc_type = glsl_type::get_array_instance(ifc_type, 2); 1520bf215546Sopenharmony_ci nir_variable *ssbo_arr = create_var(nir_var_mem_ssbo, arr_ifc_type, 1521bf215546Sopenharmony_ci "ssbo_arr"); 1522bf215546Sopenharmony_ci nir_variable *out = create_var(nir_var_mem_ssbo, ifc_type, "out"); 1523bf215546Sopenharmony_ci out->data.access = ACCESS_RESTRICT; 1524bf215546Sopenharmony_ci 1525bf215546Sopenharmony_ci nir_deref_instr *ssbo_0 = 1526bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, ssbo_arr), 0); 1527bf215546Sopenharmony_ci nir_deref_instr *ssbo_0_x = nir_build_deref_struct(b, ssbo_0, 0); 1528bf215546Sopenharmony_ci nir_store_deref(b, ssbo_0_x, nir_imm_int(b, 20), 1); 1529bf215546Sopenharmony_ci 1530bf215546Sopenharmony_ci nir_deref_instr *ssbo_1 = 1531bf215546Sopenharmony_ci nir_build_deref_array_imm(b, nir_build_deref_var(b, ssbo_arr), 1); 1532bf215546Sopenharmony_ci nir_deref_instr *ssbo_1_x = nir_build_deref_struct(b, ssbo_1, 0); 1533bf215546Sopenharmony_ci nir_store_deref(b, ssbo_1_x, nir_imm_int(b, 30), 1); 1534bf215546Sopenharmony_ci 1535bf215546Sopenharmony_ci /* Load ssbo_arr[0].x and store it in out.x. This load should not be dropped */ 1536bf215546Sopenharmony_ci nir_deref_instr *out_x = 1537bf215546Sopenharmony_ci nir_build_deref_struct(b, nir_build_deref_var(b, out), 0); 1538bf215546Sopenharmony_ci nir_store_deref(b, out_x, nir_load_deref(b, ssbo_0_x), 1); 1539bf215546Sopenharmony_ci 1540bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1541bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1542bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1543bf215546Sopenharmony_ci 1544bf215546Sopenharmony_ci bool progress = nir_opt_copy_prop_vars(b->shader); 1545bf215546Sopenharmony_ci EXPECT_FALSE(progress); 1546bf215546Sopenharmony_ci 1547bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1548bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_load_deref), 1); 1549bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 1550bf215546Sopenharmony_ci} 1551bf215546Sopenharmony_ci 1552bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, no_dead_writes_in_block) 1553bf215546Sopenharmony_ci{ 1554bf215546Sopenharmony_ci nir_variable **v = create_many_int(nir_var_mem_global, "v", 2); 1555bf215546Sopenharmony_ci 1556bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[1]), 1); 1557bf215546Sopenharmony_ci 1558bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1559bf215546Sopenharmony_ci ASSERT_FALSE(progress); 1560bf215546Sopenharmony_ci} 1561bf215546Sopenharmony_ci 1562bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, no_dead_writes_different_components_in_block) 1563bf215546Sopenharmony_ci{ 1564bf215546Sopenharmony_ci nir_variable **v = create_many_ivec2(nir_var_mem_global, "v", 3); 1565bf215546Sopenharmony_ci 1566bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[1]), 1 << 0); 1567bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[2]), 1 << 1); 1568bf215546Sopenharmony_ci 1569bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1570bf215546Sopenharmony_ci ASSERT_FALSE(progress); 1571bf215546Sopenharmony_ci} 1572bf215546Sopenharmony_ci 1573bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, volatile_write) 1574bf215546Sopenharmony_ci{ 1575bf215546Sopenharmony_ci nir_variable *v = create_int(nir_var_mem_global, "v"); 1576bf215546Sopenharmony_ci 1577bf215546Sopenharmony_ci nir_store_var(b, v, nir_imm_int(b, 0), 0x1); 1578bf215546Sopenharmony_ci nir_store_var_volatile(b, v, nir_imm_int(b, 1), 0x1); 1579bf215546Sopenharmony_ci nir_store_var(b, v, nir_imm_int(b, 2), 0x1); 1580bf215546Sopenharmony_ci 1581bf215546Sopenharmony_ci /* Our approach here is a bit scorched-earth. We expect the volatile store 1582bf215546Sopenharmony_ci * in the middle to cause both that store and the one before it to be kept. 1583bf215546Sopenharmony_ci * Technically, volatile only prevents combining the volatile store with 1584bf215546Sopenharmony_ci * another store and one could argue that the store before the volatile and 1585bf215546Sopenharmony_ci * the one after it could be combined. However, it seems safer to just 1586bf215546Sopenharmony_ci * treat a volatile store like an atomic and prevent any combining across 1587bf215546Sopenharmony_ci * it. 1588bf215546Sopenharmony_ci */ 1589bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1590bf215546Sopenharmony_ci ASSERT_FALSE(progress); 1591bf215546Sopenharmony_ci} 1592bf215546Sopenharmony_ci 1593bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, volatile_copies) 1594bf215546Sopenharmony_ci{ 1595bf215546Sopenharmony_ci nir_variable **v = create_many_int(nir_var_mem_global, "v", 2); 1596bf215546Sopenharmony_ci 1597bf215546Sopenharmony_ci nir_copy_var(b, v[0], v[1]); 1598bf215546Sopenharmony_ci nir_copy_deref_with_access(b, nir_build_deref_var(b, v[0]), 1599bf215546Sopenharmony_ci nir_build_deref_var(b, v[1]), 1600bf215546Sopenharmony_ci ACCESS_VOLATILE, (gl_access_qualifier)0); 1601bf215546Sopenharmony_ci nir_copy_var(b, v[0], v[1]); 1602bf215546Sopenharmony_ci 1603bf215546Sopenharmony_ci /* Our approach here is a bit scorched-earth. We expect the volatile store 1604bf215546Sopenharmony_ci * in the middle to cause both that store and the one before it to be kept. 1605bf215546Sopenharmony_ci * Technically, volatile only prevents combining the volatile store with 1606bf215546Sopenharmony_ci * another store and one could argue that the store before the volatile and 1607bf215546Sopenharmony_ci * the one after it could be combined. However, it seems safer to just 1608bf215546Sopenharmony_ci * treat a volatile store like an atomic and prevent any combining across 1609bf215546Sopenharmony_ci * it. 1610bf215546Sopenharmony_ci */ 1611bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1612bf215546Sopenharmony_ci ASSERT_FALSE(progress); 1613bf215546Sopenharmony_ci} 1614bf215546Sopenharmony_ci 1615bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, no_dead_writes_in_if_statement) 1616bf215546Sopenharmony_ci{ 1617bf215546Sopenharmony_ci nir_variable **v = create_many_int(nir_var_mem_global, "v", 6); 1618bf215546Sopenharmony_ci 1619bf215546Sopenharmony_ci nir_store_var(b, v[2], nir_load_var(b, v[0]), 1); 1620bf215546Sopenharmony_ci nir_store_var(b, v[3], nir_load_var(b, v[1]), 1); 1621bf215546Sopenharmony_ci 1622bf215546Sopenharmony_ci /* Each arm of the if statement will overwrite one store. */ 1623bf215546Sopenharmony_ci nir_if *if_stmt = nir_push_if(b, nir_imm_int(b, 0)); 1624bf215546Sopenharmony_ci nir_store_var(b, v[2], nir_load_var(b, v[4]), 1); 1625bf215546Sopenharmony_ci 1626bf215546Sopenharmony_ci nir_push_else(b, if_stmt); 1627bf215546Sopenharmony_ci nir_store_var(b, v[3], nir_load_var(b, v[5]), 1); 1628bf215546Sopenharmony_ci 1629bf215546Sopenharmony_ci nir_pop_if(b, if_stmt); 1630bf215546Sopenharmony_ci 1631bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1632bf215546Sopenharmony_ci ASSERT_FALSE(progress); 1633bf215546Sopenharmony_ci} 1634bf215546Sopenharmony_ci 1635bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, no_dead_writes_in_loop_statement) 1636bf215546Sopenharmony_ci{ 1637bf215546Sopenharmony_ci nir_variable **v = create_many_int(nir_var_mem_global, "v", 3); 1638bf215546Sopenharmony_ci 1639bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[1]), 1); 1640bf215546Sopenharmony_ci 1641bf215546Sopenharmony_ci /* Loop will write other value. Since it might not be executed, it doesn't 1642bf215546Sopenharmony_ci * kill the first write. 1643bf215546Sopenharmony_ci */ 1644bf215546Sopenharmony_ci nir_loop *loop = nir_push_loop(b); 1645bf215546Sopenharmony_ci 1646bf215546Sopenharmony_ci nir_if *if_stmt = nir_push_if(b, nir_imm_int(b, 0)); 1647bf215546Sopenharmony_ci nir_jump(b, nir_jump_break); 1648bf215546Sopenharmony_ci nir_pop_if(b, if_stmt); 1649bf215546Sopenharmony_ci 1650bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[2]), 1); 1651bf215546Sopenharmony_ci nir_pop_loop(b, loop); 1652bf215546Sopenharmony_ci 1653bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1654bf215546Sopenharmony_ci ASSERT_FALSE(progress); 1655bf215546Sopenharmony_ci} 1656bf215546Sopenharmony_ci 1657bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, dead_write_in_block) 1658bf215546Sopenharmony_ci{ 1659bf215546Sopenharmony_ci nir_variable **v = create_many_int(nir_var_mem_global, "v", 3); 1660bf215546Sopenharmony_ci 1661bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[1]), 1); 1662bf215546Sopenharmony_ci nir_ssa_def *load_v2 = nir_load_var(b, v[2]); 1663bf215546Sopenharmony_ci nir_store_var(b, v[0], load_v2, 1); 1664bf215546Sopenharmony_ci 1665bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1666bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1667bf215546Sopenharmony_ci 1668bf215546Sopenharmony_ci EXPECT_EQ(1, count_intrinsics(nir_intrinsic_store_deref)); 1669bf215546Sopenharmony_ci 1670bf215546Sopenharmony_ci nir_intrinsic_instr *store = get_intrinsic(nir_intrinsic_store_deref, 0); 1671bf215546Sopenharmony_ci ASSERT_TRUE(store->src[1].is_ssa); 1672bf215546Sopenharmony_ci EXPECT_EQ(store->src[1].ssa, load_v2); 1673bf215546Sopenharmony_ci} 1674bf215546Sopenharmony_ci 1675bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, dead_write_components_in_block) 1676bf215546Sopenharmony_ci{ 1677bf215546Sopenharmony_ci nir_variable **v = create_many_ivec2(nir_var_mem_global, "v", 3); 1678bf215546Sopenharmony_ci 1679bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[1]), 1 << 0); 1680bf215546Sopenharmony_ci nir_ssa_def *load_v2 = nir_load_var(b, v[2]); 1681bf215546Sopenharmony_ci nir_store_var(b, v[0], load_v2, 1 << 0); 1682bf215546Sopenharmony_ci 1683bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1684bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1685bf215546Sopenharmony_ci 1686bf215546Sopenharmony_ci EXPECT_EQ(1, count_intrinsics(nir_intrinsic_store_deref)); 1687bf215546Sopenharmony_ci 1688bf215546Sopenharmony_ci nir_intrinsic_instr *store = get_intrinsic(nir_intrinsic_store_deref, 0); 1689bf215546Sopenharmony_ci ASSERT_TRUE(store->src[1].is_ssa); 1690bf215546Sopenharmony_ci EXPECT_EQ(store->src[1].ssa, load_v2); 1691bf215546Sopenharmony_ci} 1692bf215546Sopenharmony_ci 1693bf215546Sopenharmony_ci 1694bf215546Sopenharmony_ci/* TODO: The DISABLED tests below depend on the dead write removal be able to 1695bf215546Sopenharmony_ci * identify dead writes between multiple blocks. This is still not 1696bf215546Sopenharmony_ci * implemented. 1697bf215546Sopenharmony_ci */ 1698bf215546Sopenharmony_ci 1699bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, DISABLED_dead_write_in_two_blocks) 1700bf215546Sopenharmony_ci{ 1701bf215546Sopenharmony_ci nir_variable **v = create_many_int(nir_var_mem_global, "v", 3); 1702bf215546Sopenharmony_ci 1703bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[1]), 1); 1704bf215546Sopenharmony_ci nir_ssa_def *load_v2 = nir_load_var(b, v[2]); 1705bf215546Sopenharmony_ci 1706bf215546Sopenharmony_ci /* Causes the stores to be in different blocks. */ 1707bf215546Sopenharmony_ci nir_pop_if(b, nir_push_if(b, nir_imm_int(b, 0))); 1708bf215546Sopenharmony_ci 1709bf215546Sopenharmony_ci nir_store_var(b, v[0], load_v2, 1); 1710bf215546Sopenharmony_ci 1711bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1712bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1713bf215546Sopenharmony_ci 1714bf215546Sopenharmony_ci EXPECT_EQ(1, count_intrinsics(nir_intrinsic_store_deref)); 1715bf215546Sopenharmony_ci 1716bf215546Sopenharmony_ci nir_intrinsic_instr *store = get_intrinsic(nir_intrinsic_store_deref, 0); 1717bf215546Sopenharmony_ci ASSERT_TRUE(store->src[1].is_ssa); 1718bf215546Sopenharmony_ci EXPECT_EQ(store->src[1].ssa, load_v2); 1719bf215546Sopenharmony_ci} 1720bf215546Sopenharmony_ci 1721bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, DISABLED_dead_write_components_in_two_blocks) 1722bf215546Sopenharmony_ci{ 1723bf215546Sopenharmony_ci nir_variable **v = create_many_ivec2(nir_var_mem_global, "v", 3); 1724bf215546Sopenharmony_ci 1725bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[1]), 1 << 0); 1726bf215546Sopenharmony_ci 1727bf215546Sopenharmony_ci /* Causes the stores to be in different blocks. */ 1728bf215546Sopenharmony_ci nir_pop_if(b, nir_push_if(b, nir_imm_int(b, 0))); 1729bf215546Sopenharmony_ci 1730bf215546Sopenharmony_ci nir_ssa_def *load_v2 = nir_load_var(b, v[2]); 1731bf215546Sopenharmony_ci nir_store_var(b, v[0], load_v2, 1 << 0); 1732bf215546Sopenharmony_ci 1733bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1734bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1735bf215546Sopenharmony_ci 1736bf215546Sopenharmony_ci EXPECT_EQ(1, count_intrinsics(nir_intrinsic_store_deref)); 1737bf215546Sopenharmony_ci 1738bf215546Sopenharmony_ci nir_intrinsic_instr *store = get_intrinsic(nir_intrinsic_store_deref, 0); 1739bf215546Sopenharmony_ci ASSERT_TRUE(store->src[1].is_ssa); 1740bf215546Sopenharmony_ci EXPECT_EQ(store->src[1].ssa, load_v2); 1741bf215546Sopenharmony_ci} 1742bf215546Sopenharmony_ci 1743bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, DISABLED_dead_writes_in_if_statement) 1744bf215546Sopenharmony_ci{ 1745bf215546Sopenharmony_ci nir_variable **v = create_many_int(nir_var_mem_global, "v", 4); 1746bf215546Sopenharmony_ci 1747bf215546Sopenharmony_ci /* Both branches will overwrite, making the previous store dead. */ 1748bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[1]), 1); 1749bf215546Sopenharmony_ci 1750bf215546Sopenharmony_ci nir_if *if_stmt = nir_push_if(b, nir_imm_int(b, 0)); 1751bf215546Sopenharmony_ci nir_ssa_def *load_v2 = nir_load_var(b, v[2]); 1752bf215546Sopenharmony_ci nir_store_var(b, v[0], load_v2, 1); 1753bf215546Sopenharmony_ci 1754bf215546Sopenharmony_ci nir_push_else(b, if_stmt); 1755bf215546Sopenharmony_ci nir_ssa_def *load_v3 = nir_load_var(b, v[3]); 1756bf215546Sopenharmony_ci nir_store_var(b, v[0], load_v3, 1); 1757bf215546Sopenharmony_ci 1758bf215546Sopenharmony_ci nir_pop_if(b, if_stmt); 1759bf215546Sopenharmony_ci 1760bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1761bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1762bf215546Sopenharmony_ci EXPECT_EQ(2, count_intrinsics(nir_intrinsic_store_deref)); 1763bf215546Sopenharmony_ci 1764bf215546Sopenharmony_ci nir_intrinsic_instr *first_store = get_intrinsic(nir_intrinsic_store_deref, 0); 1765bf215546Sopenharmony_ci ASSERT_TRUE(first_store->src[1].is_ssa); 1766bf215546Sopenharmony_ci EXPECT_EQ(first_store->src[1].ssa, load_v2); 1767bf215546Sopenharmony_ci 1768bf215546Sopenharmony_ci nir_intrinsic_instr *second_store = get_intrinsic(nir_intrinsic_store_deref, 1); 1769bf215546Sopenharmony_ci ASSERT_TRUE(second_store->src[1].is_ssa); 1770bf215546Sopenharmony_ci EXPECT_EQ(second_store->src[1].ssa, load_v3); 1771bf215546Sopenharmony_ci} 1772bf215546Sopenharmony_ci 1773bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, DISABLED_memory_barrier_in_two_blocks) 1774bf215546Sopenharmony_ci{ 1775bf215546Sopenharmony_ci nir_variable **v = create_many_int(nir_var_mem_global, "v", 2); 1776bf215546Sopenharmony_ci 1777bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_imm_int(b, 1), 1); 1778bf215546Sopenharmony_ci nir_store_var(b, v[1], nir_imm_int(b, 2), 1); 1779bf215546Sopenharmony_ci 1780bf215546Sopenharmony_ci /* Split into many blocks. */ 1781bf215546Sopenharmony_ci nir_pop_if(b, nir_push_if(b, nir_imm_int(b, 0))); 1782bf215546Sopenharmony_ci 1783bf215546Sopenharmony_ci /* Because it is before the barrier, this will kill the previous store to that target. */ 1784bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_imm_int(b, 3), 1); 1785bf215546Sopenharmony_ci 1786bf215546Sopenharmony_ci nir_scoped_memory_barrier(b, NIR_SCOPE_DEVICE, NIR_MEMORY_ACQ_REL, 1787bf215546Sopenharmony_ci nir_var_mem_global); 1788bf215546Sopenharmony_ci 1789bf215546Sopenharmony_ci nir_store_var(b, v[1], nir_imm_int(b, 4), 1); 1790bf215546Sopenharmony_ci 1791bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1792bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1793bf215546Sopenharmony_ci 1794bf215546Sopenharmony_ci EXPECT_EQ(3, count_intrinsics(nir_intrinsic_store_deref)); 1795bf215546Sopenharmony_ci} 1796bf215546Sopenharmony_ci 1797bf215546Sopenharmony_ciTEST_F(nir_dead_write_vars_test, DISABLED_unrelated_barrier_in_two_blocks) 1798bf215546Sopenharmony_ci{ 1799bf215546Sopenharmony_ci nir_variable **v = create_many_int(nir_var_mem_global, "v", 3); 1800bf215546Sopenharmony_ci nir_variable *out = create_int(nir_var_shader_out, "out"); 1801bf215546Sopenharmony_ci 1802bf215546Sopenharmony_ci nir_store_var(b, out, nir_load_var(b, v[1]), 1); 1803bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[1]), 1); 1804bf215546Sopenharmony_ci 1805bf215546Sopenharmony_ci /* Split into many blocks. */ 1806bf215546Sopenharmony_ci nir_pop_if(b, nir_push_if(b, nir_imm_int(b, 0))); 1807bf215546Sopenharmony_ci 1808bf215546Sopenharmony_ci /* Emit vertex will ensure writes to output variables are considered used, 1809bf215546Sopenharmony_ci * but should not affect other types of variables. */ 1810bf215546Sopenharmony_ci 1811bf215546Sopenharmony_ci nir_emit_vertex(b); 1812bf215546Sopenharmony_ci 1813bf215546Sopenharmony_ci nir_store_var(b, out, nir_load_var(b, v[2]), 1); 1814bf215546Sopenharmony_ci nir_store_var(b, v[0], nir_load_var(b, v[2]), 1); 1815bf215546Sopenharmony_ci 1816bf215546Sopenharmony_ci bool progress = nir_opt_dead_write_vars(b->shader); 1817bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1818bf215546Sopenharmony_ci 1819bf215546Sopenharmony_ci /* Verify the first write to v[0] was removed. */ 1820bf215546Sopenharmony_ci EXPECT_EQ(3, count_intrinsics(nir_intrinsic_store_deref)); 1821bf215546Sopenharmony_ci 1822bf215546Sopenharmony_ci nir_intrinsic_instr *first_store = get_intrinsic(nir_intrinsic_store_deref, 0); 1823bf215546Sopenharmony_ci EXPECT_EQ(nir_intrinsic_get_var(first_store, 0), out); 1824bf215546Sopenharmony_ci 1825bf215546Sopenharmony_ci nir_intrinsic_instr *second_store = get_intrinsic(nir_intrinsic_store_deref, 1); 1826bf215546Sopenharmony_ci EXPECT_EQ(nir_intrinsic_get_var(second_store, 0), out); 1827bf215546Sopenharmony_ci 1828bf215546Sopenharmony_ci nir_intrinsic_instr *third_store = get_intrinsic(nir_intrinsic_store_deref, 2); 1829bf215546Sopenharmony_ci EXPECT_EQ(nir_intrinsic_get_var(third_store, 0), v[0]); 1830bf215546Sopenharmony_ci} 1831bf215546Sopenharmony_ci 1832bf215546Sopenharmony_ciTEST_F(nir_combine_stores_test, non_overlapping_stores) 1833bf215546Sopenharmony_ci{ 1834bf215546Sopenharmony_ci nir_variable **v = create_many_ivec4(nir_var_mem_global, "v", 4); 1835bf215546Sopenharmony_ci nir_variable *out = create_ivec4(nir_var_shader_out, "out"); 1836bf215546Sopenharmony_ci 1837bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 1838bf215546Sopenharmony_ci nir_store_var(b, out, nir_load_var(b, v[i]), 1 << i); 1839bf215546Sopenharmony_ci 1840bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1841bf215546Sopenharmony_ci 1842bf215546Sopenharmony_ci bool progress = nir_opt_combine_stores(b->shader, nir_var_shader_out); 1843bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1844bf215546Sopenharmony_ci 1845bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1846bf215546Sopenharmony_ci 1847bf215546Sopenharmony_ci /* Clean up to verify from where the values in combined store are coming. */ 1848bf215546Sopenharmony_ci nir_copy_prop(b->shader); 1849bf215546Sopenharmony_ci nir_opt_dce(b->shader); 1850bf215546Sopenharmony_ci 1851bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 1); 1852bf215546Sopenharmony_ci nir_intrinsic_instr *combined = get_intrinsic(nir_intrinsic_store_deref, 0); 1853bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_write_mask(combined), 0xf); 1854bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(combined, 0), out); 1855bf215546Sopenharmony_ci 1856bf215546Sopenharmony_ci nir_alu_instr *vec = nir_src_as_alu_instr(combined->src[1]); 1857bf215546Sopenharmony_ci ASSERT_TRUE(vec); 1858bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) { 1859bf215546Sopenharmony_ci nir_intrinsic_instr *load = nir_src_as_intrinsic(vec->src[i].src); 1860bf215546Sopenharmony_ci ASSERT_EQ(load->intrinsic, nir_intrinsic_load_deref); 1861bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load, 0), v[i]) 1862bf215546Sopenharmony_ci << "Source value for component " << i << " of store is wrong"; 1863bf215546Sopenharmony_ci ASSERT_EQ(vec->src[i].swizzle[0], i) 1864bf215546Sopenharmony_ci << "Source component for component " << i << " of store is wrong"; 1865bf215546Sopenharmony_ci } 1866bf215546Sopenharmony_ci} 1867bf215546Sopenharmony_ci 1868bf215546Sopenharmony_ciTEST_F(nir_combine_stores_test, overlapping_stores) 1869bf215546Sopenharmony_ci{ 1870bf215546Sopenharmony_ci nir_variable **v = create_many_ivec4(nir_var_mem_global, "v", 3); 1871bf215546Sopenharmony_ci nir_variable *out = create_ivec4(nir_var_shader_out, "out"); 1872bf215546Sopenharmony_ci 1873bf215546Sopenharmony_ci /* Make stores with xy, yz and zw masks. */ 1874bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) { 1875bf215546Sopenharmony_ci nir_component_mask_t mask = (1 << i) | (1 << (i + 1)); 1876bf215546Sopenharmony_ci nir_store_var(b, out, nir_load_var(b, v[i]), mask); 1877bf215546Sopenharmony_ci } 1878bf215546Sopenharmony_ci 1879bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1880bf215546Sopenharmony_ci 1881bf215546Sopenharmony_ci bool progress = nir_opt_combine_stores(b->shader, nir_var_shader_out); 1882bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1883bf215546Sopenharmony_ci 1884bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1885bf215546Sopenharmony_ci 1886bf215546Sopenharmony_ci /* Clean up to verify from where the values in combined store are coming. */ 1887bf215546Sopenharmony_ci nir_copy_prop(b->shader); 1888bf215546Sopenharmony_ci nir_opt_dce(b->shader); 1889bf215546Sopenharmony_ci 1890bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 1); 1891bf215546Sopenharmony_ci nir_intrinsic_instr *combined = get_intrinsic(nir_intrinsic_store_deref, 0); 1892bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_write_mask(combined), 0xf); 1893bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(combined, 0), out); 1894bf215546Sopenharmony_ci 1895bf215546Sopenharmony_ci nir_alu_instr *vec = nir_src_as_alu_instr(combined->src[1]); 1896bf215546Sopenharmony_ci ASSERT_TRUE(vec); 1897bf215546Sopenharmony_ci 1898bf215546Sopenharmony_ci /* Component x comes from v[0]. */ 1899bf215546Sopenharmony_ci nir_intrinsic_instr *load_for_x = nir_src_as_intrinsic(vec->src[0].src); 1900bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load_for_x, 0), v[0]); 1901bf215546Sopenharmony_ci ASSERT_EQ(vec->src[0].swizzle[0], 0); 1902bf215546Sopenharmony_ci 1903bf215546Sopenharmony_ci /* Component y comes from v[1]. */ 1904bf215546Sopenharmony_ci nir_intrinsic_instr *load_for_y = nir_src_as_intrinsic(vec->src[1].src); 1905bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load_for_y, 0), v[1]); 1906bf215546Sopenharmony_ci ASSERT_EQ(vec->src[1].swizzle[0], 1); 1907bf215546Sopenharmony_ci 1908bf215546Sopenharmony_ci /* Components z and w come from v[2]. */ 1909bf215546Sopenharmony_ci nir_intrinsic_instr *load_for_z = nir_src_as_intrinsic(vec->src[2].src); 1910bf215546Sopenharmony_ci nir_intrinsic_instr *load_for_w = nir_src_as_intrinsic(vec->src[3].src); 1911bf215546Sopenharmony_ci ASSERT_EQ(load_for_z, load_for_w); 1912bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load_for_z, 0), v[2]); 1913bf215546Sopenharmony_ci ASSERT_EQ(vec->src[2].swizzle[0], 2); 1914bf215546Sopenharmony_ci ASSERT_EQ(vec->src[3].swizzle[0], 3); 1915bf215546Sopenharmony_ci} 1916bf215546Sopenharmony_ci 1917bf215546Sopenharmony_ciTEST_F(nir_combine_stores_test, direct_array_derefs) 1918bf215546Sopenharmony_ci{ 1919bf215546Sopenharmony_ci nir_variable **v = create_many_ivec4(nir_var_mem_global, "vec", 2); 1920bf215546Sopenharmony_ci nir_variable **s = create_many_int(nir_var_mem_global, "scalar", 2); 1921bf215546Sopenharmony_ci nir_variable *out = create_ivec4(nir_var_mem_global, "out"); 1922bf215546Sopenharmony_ci 1923bf215546Sopenharmony_ci nir_deref_instr *out_deref = nir_build_deref_var(b, out); 1924bf215546Sopenharmony_ci 1925bf215546Sopenharmony_ci /* Store to vector with mask x. */ 1926bf215546Sopenharmony_ci nir_store_deref(b, out_deref, nir_load_var(b, v[0]), 1927bf215546Sopenharmony_ci 1 << 0); 1928bf215546Sopenharmony_ci 1929bf215546Sopenharmony_ci /* Store to vector with mask yz. */ 1930bf215546Sopenharmony_ci nir_store_deref(b, out_deref, nir_load_var(b, v[1]), 1931bf215546Sopenharmony_ci (1 << 2) | (1 << 1)); 1932bf215546Sopenharmony_ci 1933bf215546Sopenharmony_ci /* Store to vector[2], overlapping with previous store. */ 1934bf215546Sopenharmony_ci nir_store_deref(b, 1935bf215546Sopenharmony_ci nir_build_deref_array_imm(b, out_deref, 2), 1936bf215546Sopenharmony_ci nir_load_var(b, s[0]), 1937bf215546Sopenharmony_ci 1 << 0); 1938bf215546Sopenharmony_ci 1939bf215546Sopenharmony_ci /* Store to vector[3], no overlap. */ 1940bf215546Sopenharmony_ci nir_store_deref(b, 1941bf215546Sopenharmony_ci nir_build_deref_array_imm(b, out_deref, 3), 1942bf215546Sopenharmony_ci nir_load_var(b, s[1]), 1943bf215546Sopenharmony_ci 1 << 0); 1944bf215546Sopenharmony_ci 1945bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1946bf215546Sopenharmony_ci 1947bf215546Sopenharmony_ci bool progress = nir_opt_combine_stores(b->shader, nir_var_mem_global); 1948bf215546Sopenharmony_ci ASSERT_TRUE(progress); 1949bf215546Sopenharmony_ci 1950bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 1951bf215546Sopenharmony_ci 1952bf215546Sopenharmony_ci /* Clean up to verify from where the values in combined store are coming. */ 1953bf215546Sopenharmony_ci nir_copy_prop(b->shader); 1954bf215546Sopenharmony_ci nir_opt_dce(b->shader); 1955bf215546Sopenharmony_ci 1956bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 1); 1957bf215546Sopenharmony_ci nir_intrinsic_instr *combined = get_intrinsic(nir_intrinsic_store_deref, 0); 1958bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_write_mask(combined), 0xf); 1959bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(combined, 0), out); 1960bf215546Sopenharmony_ci 1961bf215546Sopenharmony_ci nir_alu_instr *vec = nir_src_as_alu_instr(combined->src[1]); 1962bf215546Sopenharmony_ci ASSERT_TRUE(vec); 1963bf215546Sopenharmony_ci 1964bf215546Sopenharmony_ci /* Component x comes from v[0]. */ 1965bf215546Sopenharmony_ci nir_intrinsic_instr *load_for_x = nir_src_as_intrinsic(vec->src[0].src); 1966bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load_for_x, 0), v[0]); 1967bf215546Sopenharmony_ci ASSERT_EQ(vec->src[0].swizzle[0], 0); 1968bf215546Sopenharmony_ci 1969bf215546Sopenharmony_ci /* Component y comes from v[1]. */ 1970bf215546Sopenharmony_ci nir_intrinsic_instr *load_for_y = nir_src_as_intrinsic(vec->src[1].src); 1971bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load_for_y, 0), v[1]); 1972bf215546Sopenharmony_ci ASSERT_EQ(vec->src[1].swizzle[0], 1); 1973bf215546Sopenharmony_ci 1974bf215546Sopenharmony_ci /* Components z comes from s[0]. */ 1975bf215546Sopenharmony_ci nir_intrinsic_instr *load_for_z = nir_src_as_intrinsic(vec->src[2].src); 1976bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load_for_z, 0), s[0]); 1977bf215546Sopenharmony_ci ASSERT_EQ(vec->src[2].swizzle[0], 0); 1978bf215546Sopenharmony_ci 1979bf215546Sopenharmony_ci /* Component w comes from s[1]. */ 1980bf215546Sopenharmony_ci nir_intrinsic_instr *load_for_w = nir_src_as_intrinsic(vec->src[3].src); 1981bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_get_var(load_for_w, 0), s[1]); 1982bf215546Sopenharmony_ci ASSERT_EQ(vec->src[3].swizzle[0], 0); 1983bf215546Sopenharmony_ci} 1984bf215546Sopenharmony_ci 1985bf215546Sopenharmony_cistatic int64_t 1986bf215546Sopenharmony_civec_src_comp_as_int(nir_src src, unsigned comp) 1987bf215546Sopenharmony_ci{ 1988bf215546Sopenharmony_ci if (nir_src_is_const(src)) 1989bf215546Sopenharmony_ci return nir_src_comp_as_int(src, comp); 1990bf215546Sopenharmony_ci 1991bf215546Sopenharmony_ci assert(src.is_ssa); 1992bf215546Sopenharmony_ci nir_ssa_scalar s = { src.ssa, comp }; 1993bf215546Sopenharmony_ci assert(nir_op_is_vec(nir_ssa_scalar_alu_op(s))); 1994bf215546Sopenharmony_ci return nir_ssa_scalar_as_int(nir_ssa_scalar_chase_alu_src(s, comp)); 1995bf215546Sopenharmony_ci} 1996bf215546Sopenharmony_ci 1997bf215546Sopenharmony_ciTEST_F(nir_combine_stores_test, store_volatile) 1998bf215546Sopenharmony_ci{ 1999bf215546Sopenharmony_ci nir_variable *out = create_ivec4(nir_var_shader_out, "out"); 2000bf215546Sopenharmony_ci 2001bf215546Sopenharmony_ci nir_store_var(b, out, nir_imm_ivec4(b, 0, 0, 0, 0), 1 << 0); 2002bf215546Sopenharmony_ci nir_store_var(b, out, nir_imm_ivec4(b, 1, 1, 1, 1), 1 << 1); 2003bf215546Sopenharmony_ci nir_store_var_volatile(b, out, nir_imm_ivec4(b, -1, -2, -3, -4), 0xf); 2004bf215546Sopenharmony_ci nir_store_var(b, out, nir_imm_ivec4(b, 2, 2, 2, 2), 1 << 2); 2005bf215546Sopenharmony_ci nir_store_var(b, out, nir_imm_ivec4(b, 3, 3, 3, 3), 1 << 3); 2006bf215546Sopenharmony_ci 2007bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2008bf215546Sopenharmony_ci 2009bf215546Sopenharmony_ci bool progress = nir_opt_combine_stores(b->shader, nir_var_shader_out); 2010bf215546Sopenharmony_ci ASSERT_TRUE(progress); 2011bf215546Sopenharmony_ci 2012bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2013bf215546Sopenharmony_ci 2014bf215546Sopenharmony_ci /* Clean up the stored values */ 2015bf215546Sopenharmony_ci nir_opt_constant_folding(b->shader); 2016bf215546Sopenharmony_ci nir_opt_dce(b->shader); 2017bf215546Sopenharmony_ci 2018bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 3); 2019bf215546Sopenharmony_ci 2020bf215546Sopenharmony_ci nir_intrinsic_instr *first = get_intrinsic(nir_intrinsic_store_deref, 0); 2021bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_write_mask(first), 0x3); 2022bf215546Sopenharmony_ci ASSERT_EQ(vec_src_comp_as_int(first->src[1], 0), 0); 2023bf215546Sopenharmony_ci ASSERT_EQ(vec_src_comp_as_int(first->src[1], 1), 1); 2024bf215546Sopenharmony_ci 2025bf215546Sopenharmony_ci nir_intrinsic_instr *second = get_intrinsic(nir_intrinsic_store_deref, 1); 2026bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_write_mask(second), 0xf); 2027bf215546Sopenharmony_ci ASSERT_EQ(vec_src_comp_as_int(second->src[1], 0), -1); 2028bf215546Sopenharmony_ci ASSERT_EQ(vec_src_comp_as_int(second->src[1], 1), -2); 2029bf215546Sopenharmony_ci ASSERT_EQ(vec_src_comp_as_int(second->src[1], 2), -3); 2030bf215546Sopenharmony_ci ASSERT_EQ(vec_src_comp_as_int(second->src[1], 3), -4); 2031bf215546Sopenharmony_ci 2032bf215546Sopenharmony_ci nir_intrinsic_instr *third = get_intrinsic(nir_intrinsic_store_deref, 2); 2033bf215546Sopenharmony_ci ASSERT_EQ(nir_intrinsic_write_mask(third), 0xc); 2034bf215546Sopenharmony_ci ASSERT_EQ(vec_src_comp_as_int(third->src[1], 2), 2); 2035bf215546Sopenharmony_ci ASSERT_EQ(vec_src_comp_as_int(third->src[1], 3), 3); 2036bf215546Sopenharmony_ci} 2037bf215546Sopenharmony_ci 2038bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, simple_split) 2039bf215546Sopenharmony_ci{ 2040bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 4); 2041bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2042bf215546Sopenharmony_ci "temp"); 2043bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2044bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 2045bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array_imm(b, temp_deref, i), nir_load_var(b, in[i]), 1); 2046bf215546Sopenharmony_ci 2047bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2048bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 4); 2049bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 1); 2050bf215546Sopenharmony_ci 2051bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2052bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2053bf215546Sopenharmony_ci 2054bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2055bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 0); 2056bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 4); 2057bf215546Sopenharmony_ci} 2058bf215546Sopenharmony_ci 2059bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, simple_no_split_array_struct) 2060bf215546Sopenharmony_ci{ 2061bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 4); 2062bf215546Sopenharmony_ci struct glsl_struct_field field; 2063bf215546Sopenharmony_ci 2064bf215546Sopenharmony_ci field.type = glsl_float_type(); 2065bf215546Sopenharmony_ci field.name = ralloc_asprintf(b->shader, "field1"); 2066bf215546Sopenharmony_ci field.location = -1; 2067bf215546Sopenharmony_ci field.offset = 0; 2068bf215546Sopenharmony_ci 2069bf215546Sopenharmony_ci const struct glsl_type *st_type = glsl_struct_type(&field, 1, "struct", false); 2070bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(st_type, 4, 0), 2071bf215546Sopenharmony_ci "temp"); 2072bf215546Sopenharmony_ci 2073bf215546Sopenharmony_ci nir_variable *temp2 = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), "temp2"); 2074bf215546Sopenharmony_ci 2075bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2076bf215546Sopenharmony_ci nir_deref_instr *temp2_deref = nir_build_deref_var(b, temp2); 2077bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 2078bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array_imm(b, temp2_deref, i), nir_load_var(b, in[i]), 1); 2079bf215546Sopenharmony_ci 2080bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 2081bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_struct(b, nir_build_deref_array_imm(b, temp_deref, i), 0), nir_load_var(b, in[i]), 1); 2082bf215546Sopenharmony_ci 2083bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2084bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 8); 2085bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_struct), 4); 2086bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 2); 2087bf215546Sopenharmony_ci 2088bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2089bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2090bf215546Sopenharmony_ci 2091bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2092bf215546Sopenharmony_ci 2093bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 4); 2094bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_struct), 4); 2095bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) { 2096bf215546Sopenharmony_ci nir_deref_instr *deref = get_deref(nir_deref_type_array, i); 2097bf215546Sopenharmony_ci ASSERT_TRUE(deref); 2098bf215546Sopenharmony_ci ASSERT_TRUE(glsl_type_is_struct(deref->type)); 2099bf215546Sopenharmony_ci } 2100bf215546Sopenharmony_ci 2101bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 5); 2102bf215546Sopenharmony_ci} 2103bf215546Sopenharmony_ci 2104bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, simple_split_shader_temp) 2105bf215546Sopenharmony_ci{ 2106bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 4); 2107bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_shader_temp, glsl_array_type(glsl_int_type(), 4, 0), 2108bf215546Sopenharmony_ci "temp"); 2109bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2110bf215546Sopenharmony_ci 2111bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 2112bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array_imm(b, temp_deref, i), nir_load_var(b, in[i]), 1); 2113bf215546Sopenharmony_ci 2114bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2115bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 4); 2116bf215546Sopenharmony_ci ASSERT_EQ(count_shader_temp_vars(), 1); 2117bf215546Sopenharmony_ci 2118bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_shader_temp); 2119bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2120bf215546Sopenharmony_ci 2121bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2122bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 0); 2123bf215546Sopenharmony_ci ASSERT_EQ(count_shader_temp_vars(), 4); 2124bf215546Sopenharmony_ci} 2125bf215546Sopenharmony_ci 2126bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, simple_oob) 2127bf215546Sopenharmony_ci{ 2128bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 6); 2129bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2130bf215546Sopenharmony_ci "temp"); 2131bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2132bf215546Sopenharmony_ci 2133bf215546Sopenharmony_ci for (int i = 0; i < 6; i++) 2134bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array_imm(b, temp_deref, i), nir_load_var(b, in[i]), 1); 2135bf215546Sopenharmony_ci 2136bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2137bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 6); 2138bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 1); 2139bf215546Sopenharmony_ci 2140bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2141bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2142bf215546Sopenharmony_ci 2143bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2144bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 0); 2145bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 4); 2146bf215546Sopenharmony_ci} 2147bf215546Sopenharmony_ci 2148bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, simple_unused) 2149bf215546Sopenharmony_ci{ 2150bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 2); 2151bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2152bf215546Sopenharmony_ci "temp"); 2153bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2154bf215546Sopenharmony_ci 2155bf215546Sopenharmony_ci for (int i = 0; i < 2; i++) 2156bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array_imm(b, temp_deref, i), nir_load_var(b, in[i]), 1); 2157bf215546Sopenharmony_ci 2158bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2159bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 2); 2160bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 1); 2161bf215546Sopenharmony_ci 2162bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2163bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2164bf215546Sopenharmony_ci 2165bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2166bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 0); 2167bf215546Sopenharmony_ci /* this pass doesn't remove the unused ones */ 2168bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 4); 2169bf215546Sopenharmony_ci} 2170bf215546Sopenharmony_ci 2171bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, two_level_split) 2172bf215546Sopenharmony_ci{ 2173bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 4); 2174bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_array_type(glsl_int_type(), 4, 0), 4, 0), 2175bf215546Sopenharmony_ci "temp"); 2176bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2177bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) { 2178bf215546Sopenharmony_ci nir_deref_instr *level0 = nir_build_deref_array_imm(b, temp_deref, i); 2179bf215546Sopenharmony_ci for (int j = 0; j < 4; j++) { 2180bf215546Sopenharmony_ci nir_deref_instr *level1 = nir_build_deref_array_imm(b, level0, j); 2181bf215546Sopenharmony_ci nir_store_deref(b, level1, nir_load_var(b, in[i]), 1); 2182bf215546Sopenharmony_ci } 2183bf215546Sopenharmony_ci } 2184bf215546Sopenharmony_ci 2185bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2186bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 20); 2187bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 1); 2188bf215546Sopenharmony_ci 2189bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2190bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2191bf215546Sopenharmony_ci 2192bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2193bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 0); 2194bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 16); 2195bf215546Sopenharmony_ci} 2196bf215546Sopenharmony_ci 2197bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, simple_dont_split) 2198bf215546Sopenharmony_ci{ 2199bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 4); 2200bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2201bf215546Sopenharmony_ci "temp"); 2202bf215546Sopenharmony_ci nir_variable *ind = create_int(nir_var_shader_in, "ind"); 2203bf215546Sopenharmony_ci 2204bf215546Sopenharmony_ci nir_deref_instr *ind_deref = nir_build_deref_var(b, ind); 2205bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2206bf215546Sopenharmony_ci 2207bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 2208bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array(b, temp_deref, &ind_deref->dest.ssa), nir_load_var(b, in[i]), 1); 2209bf215546Sopenharmony_ci 2210bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2211bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 4); 2212bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 1); 2213bf215546Sopenharmony_ci 2214bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2215bf215546Sopenharmony_ci EXPECT_FALSE(progress); 2216bf215546Sopenharmony_ci 2217bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2218bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 4); 2219bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 1); 2220bf215546Sopenharmony_ci} 2221bf215546Sopenharmony_ci 2222bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, twolevel_dont_split_lvl_0) 2223bf215546Sopenharmony_ci{ 2224bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 4); 2225bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_array_type(glsl_int_type(), 6, 0), 4, 0), 2226bf215546Sopenharmony_ci "temp"); 2227bf215546Sopenharmony_ci nir_variable *ind = create_int(nir_var_shader_in, "ind"); 2228bf215546Sopenharmony_ci 2229bf215546Sopenharmony_ci nir_deref_instr *ind_deref = nir_build_deref_var(b, ind); 2230bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2231bf215546Sopenharmony_ci 2232bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) { 2233bf215546Sopenharmony_ci nir_deref_instr *level0 = nir_build_deref_array(b, temp_deref, &ind_deref->dest.ssa); 2234bf215546Sopenharmony_ci for (int j = 0; j < 6; j++) { 2235bf215546Sopenharmony_ci nir_deref_instr *level1 = nir_build_deref_array_imm(b, level0, j); 2236bf215546Sopenharmony_ci nir_store_deref(b, level1, nir_load_var(b, in[i]), 1); 2237bf215546Sopenharmony_ci } 2238bf215546Sopenharmony_ci } 2239bf215546Sopenharmony_ci 2240bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2241bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 28); 2242bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 1); 2243bf215546Sopenharmony_ci 2244bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2245bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2246bf215546Sopenharmony_ci 2247bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2248bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 24); 2249bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 6); 2250bf215546Sopenharmony_ci} 2251bf215546Sopenharmony_ci 2252bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, twolevel_dont_split_lvl_1) 2253bf215546Sopenharmony_ci{ 2254bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 6); 2255bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_array_type(glsl_int_type(), 6, 0), 4, 0), 2256bf215546Sopenharmony_ci "temp"); 2257bf215546Sopenharmony_ci nir_variable *ind = create_int(nir_var_shader_in, "ind"); 2258bf215546Sopenharmony_ci 2259bf215546Sopenharmony_ci nir_deref_instr *ind_deref = nir_build_deref_var(b, ind); 2260bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2261bf215546Sopenharmony_ci 2262bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) { 2263bf215546Sopenharmony_ci nir_deref_instr *level0 = nir_build_deref_array_imm(b, temp_deref, i); 2264bf215546Sopenharmony_ci for (int j = 0; j < 6; j++) { 2265bf215546Sopenharmony_ci /* just add the inner index to get some different derefs */ 2266bf215546Sopenharmony_ci nir_deref_instr *level1 = nir_build_deref_array(b, level0, nir_iadd(b, &ind_deref->dest.ssa, nir_imm_int(b, j))); 2267bf215546Sopenharmony_ci nir_store_deref(b, level1, nir_load_var(b, in[i]), 1); 2268bf215546Sopenharmony_ci } 2269bf215546Sopenharmony_ci } 2270bf215546Sopenharmony_ci 2271bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2272bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 28); 2273bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 1); 2274bf215546Sopenharmony_ci 2275bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2276bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2277bf215546Sopenharmony_ci 2278bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2279bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 24); 2280bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 4); 2281bf215546Sopenharmony_ci} 2282bf215546Sopenharmony_ci 2283bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, split_multiple_store) 2284bf215546Sopenharmony_ci{ 2285bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 4); 2286bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2287bf215546Sopenharmony_ci "temp"); 2288bf215546Sopenharmony_ci nir_variable *temp2 = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2289bf215546Sopenharmony_ci "temp2"); 2290bf215546Sopenharmony_ci 2291bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2292bf215546Sopenharmony_ci nir_deref_instr *temp2_deref = nir_build_deref_var(b, temp2); 2293bf215546Sopenharmony_ci 2294bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 2295bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array_imm(b, temp_deref, i), nir_load_var(b, in[i]), 1); 2296bf215546Sopenharmony_ci 2297bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 2298bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array_imm(b, temp2_deref, i), nir_load_var(b, in[i]), 1); 2299bf215546Sopenharmony_ci 2300bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2301bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 8); 2302bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 2); 2303bf215546Sopenharmony_ci 2304bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2305bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2306bf215546Sopenharmony_ci 2307bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2308bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 0); 2309bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 8); 2310bf215546Sopenharmony_ci} 2311bf215546Sopenharmony_ci 2312bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, split_load_store) 2313bf215546Sopenharmony_ci{ 2314bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 4); 2315bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2316bf215546Sopenharmony_ci "temp"); 2317bf215546Sopenharmony_ci nir_variable *temp2 = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2318bf215546Sopenharmony_ci "temp2"); 2319bf215546Sopenharmony_ci 2320bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2321bf215546Sopenharmony_ci nir_deref_instr *temp2_deref = nir_build_deref_var(b, temp2); 2322bf215546Sopenharmony_ci 2323bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 2324bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array_imm(b, temp_deref, i), nir_load_var(b, in[i]), 1); 2325bf215546Sopenharmony_ci 2326bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) { 2327bf215546Sopenharmony_ci nir_deref_instr *store_deref = nir_build_deref_array_imm(b, temp2_deref, i); 2328bf215546Sopenharmony_ci nir_deref_instr *load_deref = nir_build_deref_array_imm(b, temp_deref, i); 2329bf215546Sopenharmony_ci nir_store_deref(b, store_deref, nir_load_deref(b, load_deref), 1); 2330bf215546Sopenharmony_ci } 2331bf215546Sopenharmony_ci 2332bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2333bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 12); 2334bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 2); 2335bf215546Sopenharmony_ci 2336bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2337bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2338bf215546Sopenharmony_ci 2339bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2340bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 0); 2341bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 8); 2342bf215546Sopenharmony_ci} 2343bf215546Sopenharmony_ci 2344bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, split_copy) 2345bf215546Sopenharmony_ci{ 2346bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 4); 2347bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2348bf215546Sopenharmony_ci "temp"); 2349bf215546Sopenharmony_ci nir_variable *temp2 = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2350bf215546Sopenharmony_ci "temp2"); 2351bf215546Sopenharmony_ci 2352bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2353bf215546Sopenharmony_ci nir_deref_instr *temp2_deref = nir_build_deref_var(b, temp2); 2354bf215546Sopenharmony_ci 2355bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 2356bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array_imm(b, temp_deref, i), nir_load_var(b, in[i]), 1); 2357bf215546Sopenharmony_ci 2358bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) { 2359bf215546Sopenharmony_ci nir_deref_instr *store_deref = nir_build_deref_array_imm(b, temp2_deref, i); 2360bf215546Sopenharmony_ci nir_deref_instr *load_deref = nir_build_deref_array_imm(b, temp_deref, i); 2361bf215546Sopenharmony_ci nir_copy_deref(b, store_deref, load_deref); 2362bf215546Sopenharmony_ci } 2363bf215546Sopenharmony_ci 2364bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2365bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 12); 2366bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 2); 2367bf215546Sopenharmony_ci 2368bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2369bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2370bf215546Sopenharmony_ci 2371bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2372bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 0); 2373bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 8); 2374bf215546Sopenharmony_ci} 2375bf215546Sopenharmony_ci 2376bf215546Sopenharmony_ciTEST_F(nir_split_vars_test, split_wildcard_copy) 2377bf215546Sopenharmony_ci{ 2378bf215546Sopenharmony_ci nir_variable **in = create_many_int(nir_var_shader_in, "in", 4); 2379bf215546Sopenharmony_ci nir_variable *temp = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2380bf215546Sopenharmony_ci "temp"); 2381bf215546Sopenharmony_ci nir_variable *temp2 = create_var(nir_var_function_temp, glsl_array_type(glsl_int_type(), 4, 0), 2382bf215546Sopenharmony_ci "temp2"); 2383bf215546Sopenharmony_ci 2384bf215546Sopenharmony_ci nir_deref_instr *temp_deref = nir_build_deref_var(b, temp); 2385bf215546Sopenharmony_ci nir_deref_instr *temp2_deref = nir_build_deref_var(b, temp2); 2386bf215546Sopenharmony_ci 2387bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 2388bf215546Sopenharmony_ci nir_store_deref(b, nir_build_deref_array_imm(b, temp_deref, i), nir_load_var(b, in[i]), 1); 2389bf215546Sopenharmony_ci 2390bf215546Sopenharmony_ci nir_deref_instr *src_wildcard = nir_build_deref_array_wildcard(b, temp_deref); 2391bf215546Sopenharmony_ci nir_deref_instr *dst_wildcard = nir_build_deref_array_wildcard(b, temp2_deref); 2392bf215546Sopenharmony_ci 2393bf215546Sopenharmony_ci nir_copy_deref(b, dst_wildcard, src_wildcard); 2394bf215546Sopenharmony_ci 2395bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2396bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 4); 2397bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array_wildcard), 2); 2398bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 2); 2399bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_copy_deref), 1); 2400bf215546Sopenharmony_ci 2401bf215546Sopenharmony_ci bool progress = nir_split_array_vars(b->shader, nir_var_function_temp); 2402bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2403bf215546Sopenharmony_ci 2404bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2405bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array), 0); 2406bf215546Sopenharmony_ci ASSERT_EQ(count_derefs(nir_deref_type_array_wildcard), 0); 2407bf215546Sopenharmony_ci ASSERT_EQ(count_function_temp_vars(), 8); 2408bf215546Sopenharmony_ci ASSERT_EQ(count_intrinsics(nir_intrinsic_copy_deref), 4); 2409bf215546Sopenharmony_ci} 2410bf215546Sopenharmony_ci 2411bf215546Sopenharmony_ciTEST_F(nir_remove_dead_variables_test, pointer_initializer_used) 2412bf215546Sopenharmony_ci{ 2413bf215546Sopenharmony_ci nir_variable *x = create_int(nir_var_shader_temp, "x"); 2414bf215546Sopenharmony_ci nir_variable *y = create_int(nir_var_shader_temp, "y"); 2415bf215546Sopenharmony_ci y->pointer_initializer = x; 2416bf215546Sopenharmony_ci nir_variable *out = create_int(nir_var_shader_out, "out"); 2417bf215546Sopenharmony_ci 2418bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2419bf215546Sopenharmony_ci 2420bf215546Sopenharmony_ci nir_copy_var(b, out, y); 2421bf215546Sopenharmony_ci 2422bf215546Sopenharmony_ci bool progress = nir_remove_dead_variables(b->shader, nir_var_all, NULL); 2423bf215546Sopenharmony_ci EXPECT_FALSE(progress); 2424bf215546Sopenharmony_ci 2425bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2426bf215546Sopenharmony_ci 2427bf215546Sopenharmony_ci unsigned count = 0; 2428bf215546Sopenharmony_ci nir_foreach_variable_in_shader(var, b->shader) 2429bf215546Sopenharmony_ci count++; 2430bf215546Sopenharmony_ci 2431bf215546Sopenharmony_ci ASSERT_EQ(count, 3); 2432bf215546Sopenharmony_ci} 2433bf215546Sopenharmony_ci 2434bf215546Sopenharmony_ciTEST_F(nir_remove_dead_variables_test, pointer_initializer_dead) 2435bf215546Sopenharmony_ci{ 2436bf215546Sopenharmony_ci nir_variable *x = create_int(nir_var_shader_temp, "x"); 2437bf215546Sopenharmony_ci nir_variable *y = create_int(nir_var_shader_temp, "y"); 2438bf215546Sopenharmony_ci nir_variable *z = create_int(nir_var_shader_temp, "z"); 2439bf215546Sopenharmony_ci y->pointer_initializer = x; 2440bf215546Sopenharmony_ci z->pointer_initializer = y; 2441bf215546Sopenharmony_ci 2442bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2443bf215546Sopenharmony_ci 2444bf215546Sopenharmony_ci bool progress = nir_remove_dead_variables(b->shader, nir_var_all, NULL); 2445bf215546Sopenharmony_ci EXPECT_TRUE(progress); 2446bf215546Sopenharmony_ci 2447bf215546Sopenharmony_ci nir_validate_shader(b->shader, NULL); 2448bf215546Sopenharmony_ci 2449bf215546Sopenharmony_ci unsigned count = 0; 2450bf215546Sopenharmony_ci nir_foreach_variable_in_shader(var, b->shader) 2451bf215546Sopenharmony_ci count++; 2452bf215546Sopenharmony_ci 2453bf215546Sopenharmony_ci ASSERT_EQ(count, 0); 2454bf215546Sopenharmony_ci} 2455bf215546Sopenharmony_ci 2456bf215546Sopenharmony_ci 2457