https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71106
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Target| |mips CC| |ebotcazou at gcc dot gnu.org --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- I think that is "expected" behavior for strict-aling targets that do not provide a movmisalign handler. But newer GCC (like GCC 6 you used) should behave correctly here. The issue seems to be that the misalign handling is restricted to indirect references in expand_assignment. Thus Index: gcc/expr.c =================================================================== --- gcc/expr.c (revision 236309) +++ gcc/expr.c (working copy) @@ -4654,9 +4654,7 @@ expand_assignment (tree to, tree from, b /* Handle misaligned stores. */ mode = TYPE_MODE (TREE_TYPE (to)); - if ((TREE_CODE (to) == MEM_REF - || TREE_CODE (to) == TARGET_MEM_REF) - && mode != BLKmode + if (mode != BLKmode && !mem_ref_refers_to_non_mem_p (to) && ((align = get_object_alignment (to)) < GET_MODE_ALIGNMENT (mode)) would fix that. Without pruning some of the "pessimistic" handling in get_object_alignment this will likely result in some code-gen regressions though. Index: gcc/builtins.c =================================================================== --- gcc/builtins.c (revision 236309) +++ gcc/builtins.c (working copy) @@ -339,7 +339,7 @@ get_object_alignment_2 (tree exp, unsign Do so only if get_pointer_alignment_1 did not reveal absolute alignment knowledge and if using that alignment would improve the situation. */ - if (!addr_p && !known_alignment + if (!addr_p && TYPE_ALIGN (TREE_TYPE (exp)) > align) align = TYPE_ALIGN (TREE_TYPE (exp)); else