]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
omp-expand: Initialize fd->loop.n2 if needed for the zero iter case [PR121453]
authorJakub Jelinek <jakub@redhat.com>
Mon, 25 Aug 2025 22:28:10 +0000 (00:28 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 14 Oct 2025 19:08:13 +0000 (21:08 +0200)
When expand_omp_for_init_counts is called from expand_omp_for_generic,
zero_iter1_bb is NULL and the code always creates a new bb in which it
clears fd->loop.n2 var (if it is a var), because it can dominate code
with lastprivate guards that use the var.
When called from other places, zero_iter1_bb is non-NULL and so we don't
insert the clearing (and can't, because the same bb is used also for the
non-zero iterations exit and in that case we need to preserve the iteration
count).  Clearing is also not necessary when e.g. outermost collapsed
loop has constant non-zero number of iterations, in that case we initialize the
var to something already earlier.  The following patch makes sure to clear
it if it hasn't been initialized yet before the first check for zero iterations.

2025-08-26  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/121453
* omp-expand.cc (expand_omp_for_init_counts): Clear fd->loop.n2
before first zero count check if zero_iter1_bb is non-NULL upon
entry and fd->loop.n2 has not been written yet.

* gcc.dg/gomp/pr121453.c: New test.

(cherry picked from commit 948f20cc520e50968f8759b173096358dcbba3de)

gcc/omp-expand.cc
gcc/testsuite/gcc.dg/gomp/pr121453.c [new file with mode: 0644]

index 24287826444533308d948f251219d99460862f80..2bfef956fee4271dbf6e9f9d77c251cabcb81d6f 100644 (file)
@@ -1861,6 +1861,7 @@ expand_omp_for_init_counts (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
        }
     }
   bool rect_count_seen = false;
+  bool init_n2 = SSA_VAR_P (fd->loop.n2) && zero_iter1_bb;
   for (i = 0; i < (fd->ordered ? fd->ordered : fd->collapse); i++)
     {
       tree itype = TREE_TYPE (fd->loops[i].v);
@@ -1885,6 +1886,21 @@ expand_omp_for_init_counts (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
        {
          gcond *cond_stmt;
          tree n1, n2;
+         if (init_n2 && i < fd->collapse && !rect_count_seen)
+           {
+             /* When called with non-NULL zero_iter1_bb, we won't clear
+                fd->loop.n2 in the if (zero_iter_bb == NULL) code below
+                and if it is prior to storing fd->loop.n2 where
+                rect_count_seen is set, it could be used uninitialized.
+                As zero_iter1_bb in that case can be reached also if there
+                are non-zero iterations, the clearing can't be emitted
+                to the zero_iter1_bb, but needs to be done before the
+                condition.  */
+             gassign *assign_stmt
+               = gimple_build_assign (fd->loop.n2, build_zero_cst (type));
+             gsi_insert_before (gsi, assign_stmt, GSI_SAME_STMT);
+             init_n2 = false;
+           }
          n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
          n1 = force_gimple_operand_gsi (gsi, n1, true, NULL_TREE,
                                         true, GSI_SAME_STMT);
diff --git a/gcc/testsuite/gcc.dg/gomp/pr121453.c b/gcc/testsuite/gcc.dg/gomp/pr121453.c
new file mode 100644 (file)
index 0000000..74014e6
--- /dev/null
@@ -0,0 +1,18 @@
+/* PR middle-end/121453 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -O2 -Wuninitialized" } */
+
+void bar (int, int, int);
+int v[40][40][40];
+
+void
+foo (int x, int y, int z)
+{
+  int i, j, k;
+#pragma omp parallel for simd collapse(3)
+  for (k = 1; k <= z; ++k)
+    for (j = 2; j <= y - 1; ++j)
+      for (i = 1; i <= x; ++i)
+       v[i][j][k] = 0;
+  bar (i, j, k);
+}