When we end up expanding a SSA name copy with BLKmode regs which can
happen for vectors, possibly wrapped in a NOP-conversion or
a PAREN_EXPR and we are not optimizing we can end up with two
BLKmode MEMs that expand_gimple_stmt_1 doesn't properly handle
when expanding, trying to emit_move_insn them. Looking at store_expr
which what expand_gimple_stmt_1 is really doing reveals a lot of
magic that's missing. It eventually falls back to emit_block_move
(store_expr isn't exported), so this is what I ended up using here
given I think we'll only have BLKmode "registers" for vectors.
PR middle-end/117433
* cfgexpand.cc (expand_gimple_stmt_1): Use emit_block_move
when moving temp to BLKmode target.
* gcc.dg/pr117433.c: New testcase.
else
{
temp = force_operand (temp, target);
- if (temp != target)
+ if (temp == target)
+ ;
+ else if (GET_MODE (target) != BLKmode)
emit_move_insn (target, temp);
+ else
+ emit_block_move (target, temp, expr_size (lhs),
+ BLOCK_OP_NORMAL);
}
}
}
--- /dev/null
+/* { dg-do run } */
+
+__attribute__((__vector_size__ (sizeof (long unsigned) * 8))) long unsigned b;
+
+void __attribute__((noipa))
+foo ()
+{
+ b += __builtin_assoc_barrier (b);
+}
+
+int main()
+{
+ int i;
+ for (i = 0; i < 8; ++i)
+ b[i] = i;
+ foo ();
+ for (i = 0; i < 8; ++i)
+ if (b[i] != 2*i)
+ __builtin_abort ();
+ return 0;
+}