/* * Copyright (c) 2024 Intel Corporation * SPDX-License-Identifier: MIT */ #include #include "brw_fs.h" #include "brw_builder.h" #include "brw_cfg.h" using namespace brw; struct FSCombineConstantsTest : public ::testing::Test { FSCombineConstantsTest() { mem_ctx = ralloc_context(NULL); devinfo = {}; devinfo.ver = 9; devinfo.verx10 = 90; compiler = {}; compiler.devinfo = &devinfo; brw_init_isa_info(&compiler.isa, &devinfo); params = {}; params.mem_ctx = mem_ctx; prog_data = {}; nir_shader *nir = nir_shader_create(mem_ctx, MESA_SHADER_COMPUTE, NULL, NULL); shader = new fs_visitor(&compiler, ¶ms, NULL, &prog_data.base, nir, 8, false, false); } ~FSCombineConstantsTest() override { delete shader; ralloc_free(mem_ctx); mem_ctx = NULL; } void *mem_ctx; brw_compiler compiler; brw_compile_params params; intel_device_info devinfo; struct brw_wm_prog_data prog_data; struct gl_shader_program *shader_prog; fs_visitor *shader; bool opt_combine_constants(fs_visitor *s) { const bool print = getenv("TEST_DEBUG"); if (print) { fprintf(stderr, "= Before =\n"); s->cfg->dump(); } bool ret = brw_opt_combine_constants(*s); if (print) { fprintf(stderr, "\n= After =\n"); s->cfg->dump(); } return ret; } }; static brw_builder make_builder(fs_visitor *s) { return brw_builder(s, s->dispatch_width).at_end(); } TEST_F(FSCombineConstantsTest, Simple) { brw_builder bld = make_builder(shader); brw_reg r = brw_vec8_grf(1, 0); brw_reg imm_a = brw_imm_ud(1); brw_reg imm_b = brw_imm_ud(2); bld.SEL(r, imm_a, imm_b); brw_calculate_cfg(*shader); bool progress = opt_combine_constants(shader); ASSERT_TRUE(progress); ASSERT_EQ(shader->cfg->num_blocks, 1); bblock_t *block = cfg_first_block(shader->cfg); ASSERT_NE(block, nullptr); /* We can do better but for now sanity check that * there's a MOV and a SEL. */ ASSERT_EQ(bblock_start(block)->opcode, BRW_OPCODE_MOV); ASSERT_EQ(bblock_end(block)->opcode, BRW_OPCODE_SEL); } TEST_F(FSCombineConstantsTest, DoContainingDo) { brw_builder bld = make_builder(shader); brw_reg r1 = brw_vec8_grf(1, 0); brw_reg r2 = brw_vec8_grf(2, 0); brw_reg imm_a = brw_imm_ud(1); brw_reg imm_b = brw_imm_ud(2); bld.DO(); bld.DO(); bld.SEL(r1, imm_a, imm_b); bld.WHILE(); bld.WHILE(); bld.SEL(r2, imm_a, imm_b); brw_calculate_cfg(*shader); unsigned original_num_blocks = shader->cfg->num_blocks; bool progress = opt_combine_constants(shader); ASSERT_TRUE(progress); /* We can do better but for now sanity check there's * enough blocks, since the original issue motivating this * test is that the shader would be empty. */ ASSERT_GE(shader->cfg->num_blocks, original_num_blocks); brw_validate(*shader); }