.MASK_LOAD_LANES has an aggregate (array of vectors) return value
which is not compatible with the else value used when trying to
fold this with all lanes inactive.  Instead use an empty CTOR if
the else value is zero and otherwise do not simplify.

Bootstrap and regtest in progress on x86_64-unknown-linux-gnu.

        PR middle-end/123697
        * gimple-fold.cc (gimple_fold_partial_load_store): Use an
        empty CTOR for a zero else value in .MASK_LOAD_LANES.

        * gcc.dg/vect/vect-pr123697.c: New testcase.
---
 gcc/gimple-fold.cc                        |  6 ++++++
 gcc/testsuite/gcc.dg/vect/vect-pr123697.c | 13 +++++++++++++
 2 files changed, 19 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-pr123697.c

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index b92bf450aba..4766187e0b9 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -5899,6 +5899,12 @@ gimple_fold_partial_load_store (gimple_stmt_iterator 
*gsi, gcall *call)
          /* Replace load with else value.  */
          int else_index = internal_fn_else_index (ifn);
          tree else_value = gimple_call_arg (call, else_index);
+         if (!is_gimple_reg (lhs))
+           {
+             if (!zerop (else_value))
+               return false;
+             else_value = build_constructor (TREE_TYPE (lhs), NULL);
+           }
          gassign *new_stmt = gimple_build_assign (lhs, else_value);
          gimple_set_location (new_stmt, gimple_location (call));
          gsi_replace (gsi, new_stmt, false);
diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr123697.c 
b/gcc/testsuite/gcc.dg/vect/vect-pr123697.c
new file mode 100644
index 00000000000..e1717012e0a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-pr123697.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+
+struct a {
+  int c[2];
+};
+struct a d[3];
+double f;
+void g()
+{
+  for (int e = 0; e < 3; ++e)
+    f += d[e].c[1];
+}
-- 
2.51.0

Reply via email to