1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2020 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#include <gtest/gtest.h> 24bf215546Sopenharmony_ci#include "nir.h" 25bf215546Sopenharmony_ci#include "nir_builder.h" 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ciclass nir_opt_dce_test : public ::testing::Test { 28bf215546Sopenharmony_ciprotected: 29bf215546Sopenharmony_ci nir_opt_dce_test(); 30bf215546Sopenharmony_ci ~nir_opt_dce_test(); 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci nir_builder bld; 33bf215546Sopenharmony_ci}; 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_cinir_opt_dce_test::nir_opt_dce_test() 36bf215546Sopenharmony_ci{ 37bf215546Sopenharmony_ci glsl_type_singleton_init_or_ref(); 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci static const nir_shader_compiler_options options = { }; 40bf215546Sopenharmony_ci bld = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, &options, "dce test"); 41bf215546Sopenharmony_ci} 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_cinir_opt_dce_test::~nir_opt_dce_test() 44bf215546Sopenharmony_ci{ 45bf215546Sopenharmony_ci ralloc_free(bld.shader); 46bf215546Sopenharmony_ci glsl_type_singleton_decref(); 47bf215546Sopenharmony_ci} 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_cinir_phi_instr *create_one_source_phi(nir_shader *shader, nir_block *pred, 50bf215546Sopenharmony_ci nir_ssa_def *def) 51bf215546Sopenharmony_ci{ 52bf215546Sopenharmony_ci nir_phi_instr *phi = nir_phi_instr_create(shader); 53bf215546Sopenharmony_ci nir_phi_instr_add_src(phi, pred, nir_src_for_ssa(def)); 54bf215546Sopenharmony_ci nir_ssa_dest_init(&phi->instr, &phi->dest, 55bf215546Sopenharmony_ci def->num_components, def->bit_size, NULL); 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci return phi; 58bf215546Sopenharmony_ci} 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ciTEST_F(nir_opt_dce_test, return_before_loop) 61bf215546Sopenharmony_ci{ 62bf215546Sopenharmony_ci /* Test that nir_opt_dce() works correctly with loops immediately following a jump. 63bf215546Sopenharmony_ci * nir_opt_dce() has a fast path for loops without continues, and this test ensures that it 64bf215546Sopenharmony_ci * looks at the actual predecessors of the header instead of just counting. 65bf215546Sopenharmony_ci * 66bf215546Sopenharmony_ci * block block_0: 67bf215546Sopenharmony_ci * // preds: 68bf215546Sopenharmony_ci * return 69bf215546Sopenharmony_ci * // succs: block_3 70bf215546Sopenharmony_ci * loop { 71bf215546Sopenharmony_ci * block block_1: 72bf215546Sopenharmony_ci * // preds: block_1 73bf215546Sopenharmony_ci * vec1 32 ssa_1 = phi block_1: ssa_0 74bf215546Sopenharmony_ci * vec1 32 ssa_0 = load_const (0x00000001) 75bf215546Sopenharmony_ci * vec1 32 ssa_2 = deref_var &out (shader_out int) 76bf215546Sopenharmony_ci * intrinsic store_deref (ssa_2, ssa_1) (1, 0) 77bf215546Sopenharmony_ci * // succs: block_1 78bf215546Sopenharmony_ci * } 79bf215546Sopenharmony_ci * block block_2: 80bf215546Sopenharmony_ci * // preds: 81bf215546Sopenharmony_ci * // succs: block_3 82bf215546Sopenharmony_ci * block block_3: 83bf215546Sopenharmony_ci * 84bf215546Sopenharmony_ci * If the fast path is taken here, ssa_0 will be incorrectly DCE'd. 85bf215546Sopenharmony_ci */ 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci nir_variable *var = nir_variable_create(bld.shader, nir_var_shader_out, glsl_int_type(), "out"); 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci nir_jump(&bld, nir_jump_return); 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci nir_loop *loop = nir_push_loop(&bld); 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci nir_ssa_def *one = nir_imm_int(&bld, 1); 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci nir_phi_instr *phi = create_one_source_phi(bld.shader, one->parent_instr->block, one); 96bf215546Sopenharmony_ci nir_instr_insert_before_block(one->parent_instr->block, &phi->instr); 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci nir_store_var(&bld, var, &phi->dest.ssa, 0x1); 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci nir_pop_loop(&bld, loop); 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci ASSERT_FALSE(nir_opt_dce(bld.shader)); 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci nir_validate_shader(bld.shader, NULL); 105bf215546Sopenharmony_ci} 106