tree-optimization/98064 - fix BB SLP live lane extract wrt LC SSA
authorRichard Biener <rguenther@suse.de>
Mon, 30 Nov 2020 12:39:59 +0000 (13:39 +0100)
committerRichard Biener <rguenther@suse.de>
Mon, 30 Nov 2020 13:29:57 +0000 (14:29 +0100)
This avoids breaking LC SSA when SLP codegen pulled an out-of-loop
def into a loop when merging with in-loop defs for an external def.

2020-11-30  Richard Biener  <rguenther@suse.de>

PR tree-optimization/98064
* tree-vect-loop.c (vectorizable_live_operation): Avoid
breaking LC SSA for BB vectorization.

* g++.dg/vect/pr98064.cc: New testcase.

gcc/testsuite/g++.dg/vect/pr98064.cc [new file with mode: 0644]
gcc/tree-vect-loop.c

diff --git a/gcc/testsuite/g++.dg/vect/pr98064.cc b/gcc/testsuite/g++.dg/vect/pr98064.cc
new file mode 100644 (file)
index 0000000..74043ce
--- /dev/null
@@ -0,0 +1,25 @@
+// { dg-do compile }
+// { dg-additional-options "-O3" }
+
+const long long &min(const long long &__a, long long &__b) {
+  if (__b < __a)
+    return __b;
+  return __a;
+}
+extern long var_2;
+extern int var_3, var_8;
+extern long long var_5;
+extern unsigned short arr_353[];
+extern short arr_362[];
+extern int arr_518[];
+void test() {
+    for (char d = 0; d < 013; d += 4) {
+        for (char e = 0; e < 11; e++)
+            arr_353[e] = var_2 | min((long long)7, var_5);
+        for (int f = var_5; f; f += 4)
+            for (short g = var_8; g; g++)
+                arr_362[g] = 0;
+    }
+    for (short h = 5; (short)var_2; h += 5)
+        arr_518[h] = 0;
+}
index 48dfb4df00e338c036c4f440658c5be9638566f6..c8b4dc3a0c30ac20e6e0926b791c47f49b2f0445 100644 (file)
@@ -8743,6 +8743,24 @@ vectorizable_live_operation (vec_info *vinfo,
                                   "def\n");
                continue;
              }
+           /* ???  It can also happen that we end up pulling a def into
+              a loop where replacing out-of-loop uses would require
+              a new LC SSA PHI node.  Retain the original scalar in
+              those cases as well.  PR98064.  */
+           if (TREE_CODE (new_tree) == SSA_NAME
+               && !SSA_NAME_IS_DEFAULT_DEF (new_tree)
+               && (gimple_bb (use_stmt)->loop_father
+                   != gimple_bb (vec_stmt)->loop_father)
+               && !flow_loop_nested_p (gimple_bb (vec_stmt)->loop_father,
+                                       gimple_bb (use_stmt)->loop_father))
+             {
+               if (dump_enabled_p ())
+                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                                  "Using original scalar computation for "
+                                  "live lane because there is an out-of-loop "
+                                  "definition for it\n");
+               continue;
+             }
            FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
              SET_USE (use_p, new_tree);
            update_stmt (use_stmt);