https://gcc.gnu.org/g:89874dfab4d15e292ecf222796a6d3747749aa7b
commit 89874dfab4d15e292ecf222796a6d3747749aa7b Author: Mikael Morin <mik...@gcc.gnu.org> Date: Sun Aug 31 20:17:06 2025 +0200 gimple-simulate: Correction prise en charge offset coupé en deux MEM_REF/ARRAY_REF Diff: --- gcc/gimple-simulate.cc | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc index 30b512260b2b..721d34bea9aa 100644 --- a/gcc/gimple-simulate.cc +++ b/gcc/gimple-simulate.cc @@ -1022,14 +1022,14 @@ rewrite_ref (tree * data_ref, unsigned * offset, simul_scope & context) tree comp = TREE_OPERAND (ref, 1); tree rewritten_base = base; - unsigned off = 0; + unsigned off = *offset; if (!rewrite_ref (&rewritten_base, &off, context)) return false; tree t = build3 (COMPONENT_REF, TREE_TYPE (ref), rewritten_base, comp, NULL_TREE); *data_ref = t; - *offset += off; + *offset = off; return true; } @@ -1039,16 +1039,28 @@ rewrite_ref (tree * data_ref, unsigned * offset, simul_scope & context) tree index = TREE_OPERAND (ref, 1); tree rewritten_base = base; - unsigned rewritten_off = 0; + unsigned rewritten_off = *offset; if (!rewrite_ref (&rewritten_base, &rewritten_off, context) && TREE_CODE (index) == INTEGER_CST) return false; data_value idx_val = context.evaluate (index); + wide_int wi_idx = idx_val.get_known (); + unsigned elt_size; + elt_size = get_constant_type_size (TREE_TYPE (TREE_TYPE (base))); + wide_int total_off = wi_idx * elt_size + rewritten_off; + wide_int wi_elt_size = wi::uhwi (elt_size, total_off.get_precision ()); + wide_int global_idx = wi::udiv_trunc (total_off, wi_elt_size); + gcc_assert (wi::ges_p (global_idx, 0) + && wi::fits_uhwi_p (global_idx)); *data_ref = build4 (ARRAY_REF, TREE_TYPE (ref), rewritten_base, - idx_val.to_tree (TREE_TYPE (index)), + build_int_cst (TREE_TYPE (index), + global_idx.to_uhwi ()), NULL_TREE, NULL_TREE); - *offset += rewritten_off; + wide_int remaining_offset = total_off - global_idx * elt_size; + gcc_assert (wi::ges_p (remaining_offset, 0) + && wi::fits_uhwi_p (remaining_offset)); + *offset = remaining_offset.to_uhwi (); return true; }