https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94600
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
So for example
diff --git a/gcc/expr.c b/gcc/expr.c
index b97c217e86d..a980811c1e9 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8263,7 +8263,8 @@ expand_constructor (tree exp, rtx target, enum
expand_modifier modifier,
/* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
if (target == 0 || ! safe_from_p (target, exp, 1)
- || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM)
+ || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM
+ || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target)))
{
if (avoid_temp_mem)
return NULL_RTX;
avoids the constant folding and produces
foo:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
mov r3, #655360
ldr r2, .L4
push {r4, lr}
ldm r2, {r4, lr}
ldr ip, [r2, #8]
add r0, r2, #12
str r4, [r3, #44]
ldm r0, {r0, r1, r2}
str lr, [r3, #48]
str ip, [r3, #52]
str r0, [r3, #56]
str r1, [r3, #60]
str r2, [r3, #64]
pop {r4, pc}
on arm.