Module: Mesa Branch: staging/23.0 Commit: 785cf852962aba988215aa15031ab5269a58a6cb URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=785cf852962aba988215aa15031ab5269a58a6cb
Author: Faith Ekstrand <[email protected]> Date: Fri Feb 10 16:21:19 2023 -0600 nir/deref: Preserve alignments in opt_remove_cast_cast() This also removes the loop so opt_remove_cast_cast() will only optimize cast(cast(x)) and not cast(cast(cast(x))). However, since nir_opt_deref walks instructions top-down, there will almost never be a tripple cast because the parent cast will have opt_remove_cast_cast() run on it. Reviewed-by: Jesse Natalie <[email protected]> (cherry picked from commit af9212dd82b8885e0d94921e8500b90561faa5e0) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21467> --- src/compiler/nir/nir_deref.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c index e03be3ac662..3de401d9853 100644 --- a/src/compiler/nir/nir_deref.c +++ b/src/compiler/nir/nir_deref.c @@ -1024,19 +1024,28 @@ opt_remove_restricting_cast_alignments(nir_deref_instr *cast) static bool opt_remove_cast_cast(nir_deref_instr *cast) { - nir_deref_instr *first_cast = cast; + nir_deref_instr *parent = nir_deref_instr_parent(cast); + if (parent == NULL || parent->deref_type != nir_deref_type_cast) + return false; - while (true) { - nir_deref_instr *parent = nir_deref_instr_parent(first_cast); - if (parent == NULL || parent->deref_type != nir_deref_type_cast) - break; - first_cast = parent; + /* Copy align info from the parent cast if needed + * + * In the case that align_mul = 0, the alignment for this cast is inhereted + * from the parent deref (if any). If we aren't careful, removing our + * parent cast from the chain may lose alignment information so we need to + * copy the parent's alignment information (if any). + * + * opt_remove_restricting_cast_alignments() above is run before this pass + * and will will have cleared our alignment (set align_mul = 0) in the case + * where the parent's alignment information is somehow superior. + */ + if (cast->cast.align_mul == 0) { + cast->cast.align_mul = parent->cast.align_mul; + cast->cast.align_offset = parent->cast.align_offset; } - if (cast == first_cast) - return false; nir_instr_rewrite_src(&cast->instr, &cast->parent, - nir_src_for_ssa(first_cast->parent.ssa)); + nir_src_for_ssa(parent->parent.ssa)); return true; }
