diff mbox series

[committed] openmp: Fix up handling of addressable temporaries in simd lb, b and incr expressions [PR98383]

Message ID 20201221080320.GC3788@tucnak
State New
Headers show
Series [committed] openmp: Fix up handling of addressable temporaries in simd lb, b and incr expressions [PR98383] | expand

Commit Message

Jakub Jelinek Dec. 21, 2020, 8:03 a.m. UTC
Hi!

For simd, we have code to artificially add locally defined variables into
private clauses if they are addressable, so that omplower turns them into
"omp simd array" variables.  As the testcase shows, this is undesirable if
those temporaries only show in the lb, b or incr expressions and nowhere else,
if it is just used there, we really want normal scalar temporaries.

This patch implements that by making sure we don't set for those GOVD_LOCAL-ish
temporaries turned into GOVD_PRIVATE the GOVD_SEEN flag during gimplification
of the lb, b and incr expressions, which means that the private clause isn't
added for those.

Bootstrapped/regtested on x86_64-linux and i686-linux so far.

2020-12-21  Jakub Jelinek  <jakub@redhat.com>

	PR c++/98383
	* gimplify.c (struct gimplify_omp_ctx): Add in_for_exprs flag.
	(gimple_add_tmp_var): For addressable temporaries appearing in
	simd lb, b or incr expressions, don't add a private clause unless
	it is seen also outside of those expressions in the simd body.
	(omp_notice_variable): Likewise.
	(gimplify_omp_for): Set and reset in_for_exprs around gimplification
	of lb, b or incr expressions.

	* g++.dg/gomp/pr98383.C: New test.



	Jakub
diff mbox series

Patch

--- gcc/gimplify.c.jj	2020-12-18 21:43:02.308626945 +0100
+++ gcc/gimplify.c	2020-12-20 19:26:11.620475648 +0100
@@ -232,6 +232,7 @@  struct gimplify_omp_ctx
   bool add_safelen1;
   bool order_concurrent;
   bool has_depend;
+  bool in_for_exprs;
   int defaultmap[4];
 };
 
@@ -781,7 +782,7 @@  gimple_add_tmp_var (tree tmp)
       if (gimplify_omp_ctxp)
 	{
 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
-	  int flag = GOVD_LOCAL;
+	  int flag = GOVD_LOCAL | GOVD_SEEN;
 	  while (ctx
 		 && (ctx->region_type == ORT_WORKSHARE
 		     || ctx->region_type == ORT_TASKGROUP
@@ -794,14 +795,16 @@  gimple_add_tmp_var (tree tmp)
 		{
 		  if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
 		    ctx->add_safelen1 = true;
-		  else
+		  else if (ctx->in_for_exprs)
 		    flag = GOVD_PRIVATE;
+		  else
+		    flag = GOVD_PRIVATE | GOVD_SEEN;
 		  break;
 		}
 	      ctx = ctx->outer_context;
 	    }
 	  if (ctx)
-	    omp_add_variable (ctx, tmp, flag | GOVD_SEEN);
+	    omp_add_variable (ctx, tmp, flag);
 	}
     }
   else if (cfun)
@@ -7617,6 +7620,14 @@  omp_notice_variable (struct gimplify_omp
       goto do_outer;
     }
 
+  /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
+     lb, b or incr expressions, those shouldn't be turned into simd arrays.  */
+  if (ctx->region_type == ORT_SIMD
+      && ctx->in_for_exprs
+      && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
+	  == GOVD_PRIVATE))
+    flags &= ~GOVD_SEEN;
+
   if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
       && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
       && DECL_SIZE (decl))
@@ -12080,6 +12091,7 @@  gimplify_omp_for (tree *expr_p, gimple_s
       else
 	var = decl;
 
+      gimplify_omp_ctxp->in_for_exprs = true;
       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
 	{
 	  tree lb = TREE_OPERAND (t, 1);
@@ -12092,6 +12104,7 @@  gimplify_omp_for (tree *expr_p, gimple_s
       else
 	tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
 			      is_gimple_val, fb_rvalue, false);
+      gimplify_omp_ctxp->in_for_exprs = false;
       ret = MIN (ret, tret);
       if (ret == GS_ERROR)
 	return ret;
@@ -12101,6 +12114,7 @@  gimplify_omp_for (tree *expr_p, gimple_s
       gcc_assert (COMPARISON_CLASS_P (t));
       gcc_assert (TREE_OPERAND (t, 0) == decl);
 
+      gimplify_omp_ctxp->in_for_exprs = true;
       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
 	{
 	  tree ub = TREE_OPERAND (t, 1);
@@ -12113,6 +12127,7 @@  gimplify_omp_for (tree *expr_p, gimple_s
       else
 	tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
 			      is_gimple_val, fb_rvalue, false);
+      gimplify_omp_ctxp->in_for_exprs = false;
       ret = MIN (ret, tret);
 
       /* Handle OMP_FOR_INCR.  */
@@ -12178,6 +12193,7 @@  gimplify_omp_for (tree *expr_p, gimple_s
 	      gcc_unreachable ();
 	    }
 
+	  gimplify_omp_ctxp->in_for_exprs = true;
 	  tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
 				is_gimple_val, fb_rvalue, false);
 	  ret = MIN (ret, tret);
@@ -12199,6 +12215,7 @@  gimplify_omp_for (tree *expr_p, gimple_s
 		  ret = MIN (ret, tret);
 		}
 	    }
+	  gimplify_omp_ctxp->in_for_exprs = false;
 	  break;
 
 	default:
--- gcc/testsuite/g++.dg/gomp/pr98383.C.jj	2020-12-20 19:27:57.540277373 +0100
+++ gcc/testsuite/g++.dg/gomp/pr98383.C	2020-12-20 19:27:49.388369600 +0100
@@ -0,0 +1,18 @@ 
+// PR c++/98383
+// { dg-options "-fopenmp -O1" }
+
+int bar (const int &);
+
+void
+foo (int *a)
+{
+#pragma omp simd
+  for (int i = 0; i < bar (8); ++i)
+    a[i]++;
+#pragma omp simd
+  for (int i = bar (9); i < 16; ++i)
+    a[i]++;
+#pragma omp simd
+  for (int i = 0; i < 32; i += bar (10))
+    a[i]++;
+}