diff --git a/src/compiler/nir/nir_inline_functions.c b/src/compiler/nir/nir_inline_functions.c index b1399897be5..eba53d06029 100644 --- a/src/compiler/nir/nir_inline_functions.c +++ b/src/compiler/nir/nir_inline_functions.c @@ -26,6 +26,12 @@ #include "nir_control_flow.h" #include "nir_vla.h" +static bool function_ends_in_jump(nir_function_impl *impl) +{ + nir_block *last_block = nir_impl_last_block(impl); + return nir_block_ends_in_jump(last_block); +} + void nir_inline_function_impl(struct nir_builder *b, const nir_function_impl *impl, nir_ssa_def **params, @@ -33,11 +39,6 @@ void nir_inline_function_impl(struct nir_builder *b, { nir_function_impl *copy = nir_function_impl_clone(b->shader, impl); - /* Insert a nop at the cursor so we can keep track of where things are as - * we add/remove stuff from the CFG. - */ - nir_intrinsic_instr *nop = nir_nop(b); - exec_list_append(&b->impl->locals, ©->locals); exec_list_append(&b->impl->registers, ©->registers); @@ -104,12 +105,24 @@ void nir_inline_function_impl(struct nir_builder *b, } } + bool nest_if = function_ends_in_jump(copy); + /* Pluck the body out of the function and place it here */ nir_cf_list body; nir_cf_list_extract(&body, ©->body); - nir_cf_reinsert(&body, nir_before_instr(&nop->instr)); - b->cursor = nir_instr_remove(&nop->instr); + if (nest_if) { + nir_if *cf = nir_push_if(b, nir_imm_bool(b, true)); + nir_cf_reinsert(&body, nir_after_cf_list(&cf->then_list)); + nir_pop_if(b, cf); + } else { + /* Insert a nop at the cursor so we can keep track of where things are as + * we add/remove stuff from the CFG. + */ + nir_intrinsic_instr *nop = nir_nop(b); + nir_cf_reinsert(&body, nir_before_instr(&nop->instr)); + b->cursor = nir_instr_remove(&nop->instr); + } } static bool inline_function_impl(nir_function_impl *impl, struct set *inlined);