and need be, put it there. */
else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem))
{
+ machine_mode tem_mode = TYPE_MODE (TREE_TYPE (tem));
poly_int64 size;
if (!poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (tem)), &size))
size = max_int_size_in_bytes (TREE_TYPE (tem));
- memloc = assign_stack_local (TYPE_MODE (TREE_TYPE (tem)), size,
- TREE_CODE (tem) == SSA_NAME
- ? TYPE_ALIGN (TREE_TYPE (tem))
- : get_object_alignment (tem));
+ unsigned int align = TREE_CODE (tem) == SSA_NAME
+ ? TYPE_ALIGN (TREE_TYPE (tem))
+ : get_object_alignment (tem);
+ if (STRICT_ALIGNMENT)
+ {
+ /* For STRICT_ALIGNMENT targets, when we force the operand to
+ memory, we may need to increase the alignment to meet the
+ expectation in later RTL lowering passes. The increased
+ alignment is capped by MAX_SUPPORTED_STACK_ALIGNMENT. */
+ if (tem_mode != BLKmode)
+ align = MAX (align, GET_MODE_ALIGNMENT (tem_mode));
+ else
+ align = MAX (align, TYPE_ALIGN (TREE_TYPE (tem)));
+ align = MIN (align, (unsigned) MAX_SUPPORTED_STACK_ALIGNMENT);
+ }
+ memloc = assign_stack_local (tem_mode, size, align);
emit_move_insn (memloc, op0);
op0 = memloc;
clear_mem_expr = true;
--- /dev/null
+/* PR middle-end/123447 */
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-O2 -mstrict-align" } */
+
+typedef __attribute__((__vector_size__(32))) _Decimal64 D;
+typedef __attribute__((__vector_size__(64))) int V;
+typedef __attribute__((__vector_size__(64))) _Decimal64 D64;
+
+D d;
+
+void foo1 () {
+ D _4;
+ D64 _5;
+ V _1;
+ _1 = (V) { 9, -64497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ _5 = (D64) _1;
+ _4 = __builtin_shufflevector (_5, _5, 0, 1, 2, 3);
+ d = _4;
+}