https://gcc.gnu.org/g:2fc25a21820001c67258d30f0960ac9cd0f268cf

commit r15-4951-g2fc25a21820001c67258d30f0960ac9cd0f268cf
Author: Richard Biener <rguent...@suse.de>
Date:   Mon Nov 4 11:39:05 2024 +0100

    middle-end/117433 - ICE with gimple BLKmode reg copy
    
    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.

Diff:
---
 gcc/cfgexpand.cc                |  7 ++++++-
 gcc/testsuite/gcc.dg/pr117433.c | 21 +++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
index e35664cc93d8..f3a33ff9a07d 100644
--- a/gcc/cfgexpand.cc
+++ b/gcc/cfgexpand.cc
@@ -4068,8 +4068,13 @@ expand_gimple_stmt_1 (gimple *stmt)
            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);
              }
          }
       }
diff --git a/gcc/testsuite/gcc.dg/pr117433.c b/gcc/testsuite/gcc.dg/pr117433.c
new file mode 100644
index 000000000000..1014c1ef3186
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr117433.c
@@ -0,0 +1,21 @@
+/* { 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;
+}

Reply via email to