https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94482
--- Comment #17 from Richard Biener <rguenth at gcc dot gnu.org> --- This: if (write) { gassign *stmt; if (access->grp_partial_lhs) ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE, false, GSI_NEW_STMT); stmt = gimple_build_assign (repl, ref); gimple_set_location (stmt, loc); gsi_insert_after (gsi, stmt, GSI_NEW_STMT); is definitely wrong. And in the else case grp_partial_lhs is never true. The whole bfr path looks fisy, too. The following fixes the testcase: diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index b2056b58750..e16b641c9bb 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -3737,36 +3737,8 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write) type conversion (see PR42196) and when scalarized unions are involved in assembler statements (see PR42398). */ if (!useless_type_conversion_p (type, access->type)) - { - tree ref; - - ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false); - - if (write) - { - gassign *stmt; - - if (access->grp_partial_lhs) - ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE, - false, GSI_NEW_STMT); - stmt = gimple_build_assign (repl, ref); - gimple_set_location (stmt, loc); - gsi_insert_after (gsi, stmt, GSI_NEW_STMT); - } - else - { - gassign *stmt; - - if (access->grp_partial_lhs) - repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE, - true, GSI_SAME_STMT); - stmt = gimple_build_assign (ref, repl); - gimple_set_location (stmt, loc); - gsi_insert_before (gsi, stmt, GSI_SAME_STMT); - } - } - else - *expr = repl; + repl = build1 (VIEW_CONVERT_EXPR, type, repl); + *expr = repl; sra_stats.exprs++; } else if (write && access->grp_to_be_debug_replaced)