https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94226
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- The issue is most likely get_origin_and_offset which looks at the pointer argument pointed-to-type: tree xtype = TREE_TYPE (TREE_TYPE (x)); /* The byte offset of the most basic struct member the byte offset *OFF corresponds to, or for a (multidimensional) array member, the byte offset of the array element. */ HOST_WIDE_INT index = 0; if ((RECORD_OR_UNION_TYPE_P (xtype) && field_at_offset (xtype, *off, &index)) || (TREE_CODE (xtype) == ARRAY_TYPE && TREE_CODE (TREE_TYPE (xtype)) == ARRAY_TYPE && array_elt_at_offset (xtype, *off, &index))) { *fldoff += index; *off -= index; } here we now see a single-dimensional array because the MEM[&MEM] propagation simply preserves the original pointer type. Since the pointer type doesn't have any semantics heuristics should better look at the type of the underlying object (if there is any). The following fixes this testcase (not that I agree with the way all this is written): diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 13640e0fd36..1879686ce0a 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -2331,7 +2331,9 @@ get_origin_and_offset (tree x, HOST_WIDE_INT *fldoff, HOST_WIDE_INT *off) if (off) { - tree xtype = TREE_TYPE (TREE_TYPE (x)); + tree xtype + = (TREE_CODE (x) == ADDR_EXPR + ? TREE_TYPE (TREE_OPERAND (x, 0)) : TREE_TYPE (TREE_TYPE (x))); /* The byte offset of the most basic struct member the byte offset *OFF corresponds to, or for a (multidimensional)