X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fcompiler%2Fnir%2Fnir_validate.c;h=9d2dfbc820675d7f7385f69824e536674e294e84;hp=410f5906c0b1aab0d47fa23377259025ea7e80b0;hb=e4f07f8bdc602bae665fd57bb69e293a69d89bef;hpb=5dc85abc4fe0a27beb00ef31bb21b79dbdcfec8d diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 410f5906c0b..9d2dfbc8206 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -509,11 +509,27 @@ validate_deref_instr(nir_deref_instr *instr, validate_state *state) validate_assert(state, instr->mode == nir_var_mem_ubo || instr->mode == nir_var_mem_ssbo || instr->mode == nir_var_mem_shared || - instr->mode == nir_var_mem_global); + instr->mode == nir_var_mem_global || + instr->mode == nir_var_mem_constant); } } } +static bool +vectorized_intrinsic(nir_intrinsic_instr *intr) +{ + const nir_intrinsic_info *info = &nir_intrinsic_infos[intr->intrinsic]; + + if (info->dest_components == 0) + return true; + + for (unsigned i = 0; i < info->num_srcs; i++) + if (info->src_components[i] == 0) + return true; + + return false; +} + static void validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state) { @@ -570,11 +586,20 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state) break; } + case nir_intrinsic_load_ubo_vec4: { + int bit_size = nir_dest_bit_size(instr->dest); + validate_assert(state, bit_size >= 8); + validate_assert(state, (nir_intrinsic_component(instr) + + instr->num_components) * (bit_size / 8) <= 16); + break; + } + case nir_intrinsic_load_ubo: case nir_intrinsic_load_ssbo: case nir_intrinsic_load_shared: case nir_intrinsic_load_global: case nir_intrinsic_load_scratch: + case nir_intrinsic_load_constant: /* These memory load operations must have alignments */ validate_assert(state, util_is_power_of_two_nonzero(nir_intrinsic_align_mul(instr))); @@ -589,7 +614,6 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state) case nir_intrinsic_load_output: case nir_intrinsic_load_per_vertex_output: case nir_intrinsic_load_push_constant: - case nir_intrinsic_load_constant: /* All memory load operations must load at least a byte */ validate_assert(state, nir_dest_bit_size(instr->dest) >= 8); break; @@ -640,6 +664,9 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state) validate_dest(&instr->dest, state, dest_bit_size, components_written); } + + if (!vectorized_intrinsic(instr)) + validate_assert(state, instr->num_components == 0); } static void @@ -749,6 +776,67 @@ validate_phi_instr(nir_phi_instr *instr, validate_state *state) state->block->predecessors->entries); } +static void +validate_jump_instr(nir_jump_instr *instr, validate_state *state) +{ + nir_block *block = state->block; + validate_assert(state, &instr->instr == nir_block_last_instr(block)); + + switch (instr->type) { + case nir_jump_return: + validate_assert(state, block->successors[0] == state->impl->end_block); + validate_assert(state, block->successors[1] == NULL); + validate_assert(state, instr->target == NULL); + validate_assert(state, instr->else_target == NULL); + break; + + case nir_jump_break: + validate_assert(state, state->impl->structured); + validate_assert(state, state->loop != NULL); + if (state->loop) { + nir_block *after = + nir_cf_node_as_block(nir_cf_node_next(&state->loop->cf_node)); + validate_assert(state, block->successors[0] == after); + } + validate_assert(state, block->successors[1] == NULL); + validate_assert(state, instr->target == NULL); + validate_assert(state, instr->else_target == NULL); + break; + + case nir_jump_continue: + validate_assert(state, state->impl->structured); + validate_assert(state, state->loop != NULL); + if (state->loop) { + nir_block *first = nir_loop_first_block(state->loop); + validate_assert(state, block->successors[0] == first); + } + validate_assert(state, block->successors[1] == NULL); + validate_assert(state, instr->target == NULL); + validate_assert(state, instr->else_target == NULL); + break; + + case nir_jump_goto: + validate_assert(state, !state->impl->structured); + validate_assert(state, instr->target == block->successors[0]); + validate_assert(state, instr->target != NULL); + validate_assert(state, instr->else_target == NULL); + break; + + case nir_jump_goto_if: + validate_assert(state, !state->impl->structured); + validate_assert(state, instr->target == block->successors[1]); + validate_assert(state, instr->else_target == block->successors[0]); + validate_src(&instr->condition, state, 0, 1); + validate_assert(state, instr->target != NULL); + validate_assert(state, instr->else_target != NULL); + break; + + default: + validate_assert(state, !"Invalid jump instruction type"); + break; + } +} + static void validate_instr(nir_instr *instr, validate_state *state) { @@ -790,6 +878,7 @@ validate_instr(nir_instr *instr, validate_state *state) break; case nir_instr_type_jump: + validate_jump_instr(nir_instr_as_jump(instr), state); break; default: @@ -817,8 +906,8 @@ validate_phi_src(nir_phi_instr *instr, nir_block *pred, validate_state *state) return; } } - - abort(); + validate_assert(state, !"Phi does not have a source corresponding to one " + "of its predecessor blocks"); } static void @@ -848,10 +937,6 @@ validate_block(nir_block *block, validate_state *state) nir_instr_prev(instr)->type == nir_instr_type_phi); } - if (instr->type == nir_instr_type_jump) { - validate_assert(state, instr == nir_block_last_instr(block)); - } - validate_instr(instr, state); } @@ -874,32 +959,9 @@ validate_block(nir_block *block, validate_state *state) pred->successors[1] == block); } - if (!exec_list_is_empty(&block->instr_list) && - nir_block_last_instr(block)->type == nir_instr_type_jump) { - validate_assert(state, block->successors[1] == NULL); - nir_jump_instr *jump = nir_instr_as_jump(nir_block_last_instr(block)); - switch (jump->type) { - case nir_jump_break: { - nir_block *after = - nir_cf_node_as_block(nir_cf_node_next(&state->loop->cf_node)); - validate_assert(state, block->successors[0] == after); - break; - } - - case nir_jump_continue: { - nir_block *first = nir_loop_first_block(state->loop); - validate_assert(state, block->successors[0] == first); - break; - } - - case nir_jump_return: - validate_assert(state, block->successors[0] == state->impl->end_block); - break; - - default: - unreachable("bad jump type"); - } - } else { + if (!state->impl->structured) { + validate_assert(state, nir_block_ends_in_jump(block)); + } else if (!nir_block_ends_in_jump(block)) { nir_cf_node *next = nir_cf_node_next(&block->cf_node); if (next == NULL) { switch (state->parent_node->type) { @@ -935,12 +997,14 @@ validate_block(nir_block *block, validate_state *state) nir_if_first_then_block(if_stmt)); validate_assert(state, block->successors[1] == nir_if_first_else_block(if_stmt)); - } else { - validate_assert(state, next->type == nir_cf_node_loop); + } else if (next->type == nir_cf_node_loop) { nir_loop *loop = nir_cf_node_as_loop(next); validate_assert(state, block->successors[0] == nir_loop_first_block(loop)); validate_assert(state, block->successors[1] == NULL); + } else { + validate_assert(state, + !"Structured NIR cannot have consecutive blocks"); } } } @@ -949,6 +1013,8 @@ validate_block(nir_block *block, validate_state *state) static void validate_if(nir_if *if_stmt, validate_state *state) { + validate_assert(state, state->impl->structured); + state->if_stmt = if_stmt; validate_assert(state, !exec_node_is_head_sentinel(if_stmt->cf_node.node.prev)); @@ -984,6 +1050,8 @@ validate_if(nir_if *if_stmt, validate_state *state) static void validate_loop(nir_loop *loop, validate_state *state) { + validate_assert(state, state->impl->structured); + validate_assert(state, !exec_node_is_head_sentinel(loop->cf_node.node.prev)); nir_cf_node *prev_node = nir_cf_node_prev(&loop->cf_node); validate_assert(state, prev_node->type == nir_cf_node_block); @@ -1066,42 +1134,21 @@ postvalidate_reg_decl(nir_register *reg, validate_state *state) validate_assert(state, entry); _mesa_set_remove(reg_state->uses, entry); } - - if (reg_state->uses->entries != 0) { - printf("extra entries in register uses:\n"); - set_foreach(reg_state->uses, entry) - printf("%p\n", entry->key); - - abort(); - } + validate_assert(state, reg_state->uses->entries == 0); nir_foreach_if_use(src, reg) { struct set_entry *entry = _mesa_set_search(reg_state->if_uses, src); validate_assert(state, entry); _mesa_set_remove(reg_state->if_uses, entry); } - - if (reg_state->if_uses->entries != 0) { - printf("extra entries in register if_uses:\n"); - set_foreach(reg_state->if_uses, entry) - printf("%p\n", entry->key); - - abort(); - } + validate_assert(state, reg_state->if_uses->entries == 0); nir_foreach_def(src, reg) { struct set_entry *entry = _mesa_set_search(reg_state->defs, src); validate_assert(state, entry); _mesa_set_remove(reg_state->defs, entry); } - - if (reg_state->defs->entries != 0) { - printf("extra entries in register defs:\n"); - set_foreach(reg_state->defs, entry) - printf("%p\n", entry->key); - - abort(); - } + validate_assert(state, reg_state->defs->entries == 0); } static void @@ -1172,7 +1219,7 @@ validate_function_impl(nir_function_impl *impl, validate_state *state) state->parent_node = &impl->cf_node; exec_list_validate(&impl->locals); - nir_foreach_variable(var, &impl->locals) { + nir_foreach_function_temp_variable(var, impl) { validate_var_decl(var, nir_var_function_temp, state); } @@ -1198,13 +1245,8 @@ validate_function_impl(nir_function_impl *impl, validate_state *state) postvalidate_reg_decl(reg, state); } - if (state->ssa_srcs->entries != 0) { - printf("extra dangling SSA sources:\n"); - set_foreach(state->ssa_srcs, entry) - printf("%p\n", entry->key); - - abort(); - } + validate_assert(state, state->ssa_srcs->entries == 0); + _mesa_set_clear(state->ssa_srcs, NULL); } static void @@ -1287,38 +1329,20 @@ nir_validate_shader(nir_shader *shader, const char *when) state.shader = shader; - exec_list_validate(&shader->uniforms); - nir_foreach_variable(var, &shader->uniforms) { - validate_var_decl(var, nir_var_uniform | - nir_var_mem_ubo | - nir_var_mem_ssbo, - &state); - } - - exec_list_validate(&shader->inputs); - nir_foreach_variable(var, &shader->inputs) { - validate_var_decl(var, nir_var_shader_in, &state); - } - - exec_list_validate(&shader->outputs); - nir_foreach_variable(var, &shader->outputs) { - validate_var_decl(var, nir_var_shader_out, &state); - } - - exec_list_validate(&shader->shared); - nir_foreach_variable(var, &shader->shared) { - validate_var_decl(var, nir_var_mem_shared, &state); - } - - exec_list_validate(&shader->globals); - nir_foreach_variable(var, &shader->globals) { - validate_var_decl(var, nir_var_shader_temp, &state); - } - - exec_list_validate(&shader->system_values); - nir_foreach_variable(var, &shader->system_values) { - validate_var_decl(var, nir_var_system_value, &state); - } + nir_variable_mode valid_modes = + nir_var_shader_in | + nir_var_shader_out | + nir_var_shader_temp | + nir_var_uniform | + nir_var_mem_ubo | + nir_var_system_value | + nir_var_mem_ssbo | + nir_var_mem_shared | + nir_var_mem_constant; + + exec_list_validate(&shader->variables); + nir_foreach_variable_in_shader(var, shader) + validate_var_decl(var, valid_modes, &state); exec_list_validate(&shader->functions); foreach_list_typed(nir_function, func, node, &shader->functions) {