[PATCH][CilkPlus] Fix PR69363

Ilya Verbin iverbin@gmail.com
Wed Feb 17 14:33:00 GMT 2016


Hi!

This patch fixes <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69363>
Bootstrap and make check passed.  OK for... stage 1?


gcc/c-family/
	PR c++/69363
	* c-cilkplus.c (c_finish_cilk_clauses): Remove function.
	* c-common.h (c_finish_cilk_clauses): Remove declaration.
gcc/c/
	PR c++/69363
	* c-parser.c (c_parser_cilk_all_clauses): Use c_finish_omp_clauses
	instead of c_finish_cilk_clauses.
	* c-tree.h (c_finish_omp_clauses): Add new default argument.
	* c-typeck.c (c_finish_omp_clauses): Add new argument.  Allow
	floating-point variables in the linear clause for Cilk Plus.
gcc/cp/
	PR c++/69363
	* cp-tree.h (finish_omp_clauses): Add new default argument.
	* parser.c (cp_parser_cilk_simd_all_clauses): Use finish_omp_clauses
	instead of c_finish_cilk_clauses.
	* semantics.c (finish_omp_clauses): Add new argument.  Allow
	floating-point variables in the linear clause for Cilk Plus.
gcc/testsuite/
	PR c++/69363
	* c-c++-common/cilk-plus/PS/clauses3.c: Adjust dg-error string.
	* c-c++-common/cilk-plus/PS/clauses4.c: New test.
	* c-c++-common/cilk-plus/PS/pr69363.c: New test.


diff --git a/gcc/c-family/c-cilkplus.c b/gcc/c-family/c-cilkplus.c
index 3e7902fd..9f1f364 100644
--- a/gcc/c-family/c-cilkplus.c
+++ b/gcc/c-family/c-cilkplus.c
@@ -41,56 +41,6 @@ c_check_cilk_loop (location_t loc, tree decl)
   return true;
 }
 
-/* Validate and emit code for <#pragma simd> clauses.  */
-
-tree
-c_finish_cilk_clauses (tree clauses)
-{
-  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
-    {
-      tree prev = clauses;
-
-      /* If a variable appears in a linear clause it cannot appear in
-	 any other OMP clause.  */
-      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
-	for (tree c2 = clauses; c2; c2 = OMP_CLAUSE_CHAIN (c2))
-	  {
-	    if (c == c2)
-	      continue;
-	    enum omp_clause_code code = OMP_CLAUSE_CODE (c2);
-
-	    switch (code)
-	      {
-	      case OMP_CLAUSE_LINEAR:
-	      case OMP_CLAUSE_PRIVATE:
-	      case OMP_CLAUSE_FIRSTPRIVATE:
-	      case OMP_CLAUSE_LASTPRIVATE:
-	      case OMP_CLAUSE_REDUCTION:
-		break;
-
-	      case OMP_CLAUSE_SAFELEN:
-		goto next;
-
-	      default:
-		gcc_unreachable ();
-	      }
-
-	    if (OMP_CLAUSE_DECL (c) == OMP_CLAUSE_DECL (c2))
-	      {
-		error_at (OMP_CLAUSE_LOCATION (c2),
-			  "variable appears in more than one clause");
-		inform (OMP_CLAUSE_LOCATION (c),
-			"other clause defined here");
-		// Remove problematic clauses.
-		OMP_CLAUSE_CHAIN (prev) = OMP_CLAUSE_CHAIN (c2);
-	      }
-	  next:
-	    prev = c2;
-	  }
-    }
-  return clauses;
-}
-
 /* Calculate number of iterations of CILK_FOR.  */
 
 tree
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index fa3746c..663e457 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1369,7 +1369,6 @@ extern enum stv_conv scalar_to_vector (location_t loc, enum tree_code code,
 				       tree op0, tree op1, bool);
 
 /* In c-cilkplus.c  */
-extern tree c_finish_cilk_clauses (tree);
 extern tree c_validate_cilk_plus_loop (tree *, int *, void *);
 extern bool c_check_cilk_loop (location_t, tree);
 
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 7a27244..4770f45d 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -17427,7 +17427,7 @@ c_parser_cilk_all_clauses (c_parser *parser)
 
  saw_error:
   c_parser_skip_to_pragma_eol (parser);
-  return c_finish_cilk_clauses (clauses);
+  return c_finish_omp_clauses (clauses, false, false, true);
 }
 
 /* This function helps parse the grainsize pragma for a _Cilk_for statement.
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 96ab049..8bfd256 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -661,7 +661,7 @@ extern tree c_begin_omp_task (void);
 extern tree c_finish_omp_task (location_t, tree, tree);
 extern void c_finish_omp_cancel (location_t, tree);
 extern void c_finish_omp_cancellation_point (location_t, tree);
-extern tree c_finish_omp_clauses (tree, bool, bool = false);
+extern tree c_finish_omp_clauses (tree, bool, bool = false, bool = false);
 extern tree c_build_va_arg (location_t, tree, location_t, tree);
 extern tree c_finish_transaction (location_t, tree, int);
 extern bool c_tree_equal (tree, tree);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 1122a88..d91bd72 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -12527,7 +12527,8 @@ c_find_omp_placeholder_r (tree *tp, int *, void *data)
    Remove any elements from the list that are invalid.  */
 
 tree
-c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd)
+c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
+		      bool is_cilk)
 {
   bitmap_head generic_head, firstprivate_head, lastprivate_head;
   bitmap_head aligned_head, map_head, map_field_head;
@@ -12809,14 +12810,31 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd)
 			"clause on %<simd%> or %<for%> constructs");
 	      OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
 	    }
-	  if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
-	      && TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
+	  if (is_cilk)
 	    {
-	      error_at (OMP_CLAUSE_LOCATION (c),
-			"linear clause applied to non-integral non-pointer "
-			"variable with type %qT", TREE_TYPE (t));
-	      remove = true;
-	      break;
+	      if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
+		  && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (t))
+		  && TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
+		{
+		  error_at (OMP_CLAUSE_LOCATION (c),
+			    "linear clause applied to non-integral, "
+			    "non-floating, non-pointer variable with type %qT",
+			    TREE_TYPE (t));
+		  remove = true;
+		  break;
+		}
+	    }
+	  else
+	    {
+	      if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
+		  && TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
+		{
+		  error_at (OMP_CLAUSE_LOCATION (c),
+			    "linear clause applied to non-integral non-pointer "
+			    "variable with type %qT", TREE_TYPE (t));
+		  remove = true;
+		  break;
+		}
 	    }
 	  if (declare_simd)
 	    {
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3b91089..e44fb7f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6417,7 +6417,7 @@ extern tree omp_reduction_id			(enum tree_code, tree, tree);
 extern tree cp_remove_omp_priv_cleanup_stmt	(tree *, int *, void *);
 extern void cp_check_omp_declare_reduction	(tree);
 extern void finish_omp_declare_simd_methods	(tree);
-extern tree finish_omp_clauses			(tree, bool, bool = false);
+extern tree finish_omp_clauses			(tree, bool, bool = false, bool = false);
 extern tree push_omp_privatization_clauses	(bool);
 extern void pop_omp_privatization_clauses	(tree);
 extern void save_omp_privatization_clauses	(vec<tree> &);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 07d1821..21b45b9 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -37633,7 +37633,7 @@ cp_parser_cilk_simd_all_clauses (cp_parser *parser, cp_token *pragma_token)
   if (clauses == error_mark_node)
     return error_mark_node;
   else
-    return c_finish_cilk_clauses (clauses);
+    return finish_omp_clauses (clauses, false, false, true);
 }
 
 /* Main entry-point for parsing Cilk Plus <#pragma simd> for loops.  */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0cf5f93..c97b738 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5736,7 +5736,8 @@ cp_finish_omp_clause_depend_sink (tree sink_clause)
    Remove any elements from the list that are invalid.  */
 
 tree
-finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
+finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
+		    bool is_cilk)
 {
   bitmap_head generic_head, firstprivate_head, lastprivate_head;
   bitmap_head aligned_head, map_head, map_field_head;
@@ -5832,13 +5833,29 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
 		}
 	      if (TREE_CODE (type) == REFERENCE_TYPE)
 		type = TREE_TYPE (type);
-	      if (!INTEGRAL_TYPE_P (type)
-		  && TREE_CODE (type) != POINTER_TYPE)
+	      if (is_cilk)
 		{
-		  error ("linear clause applied to non-integral non-pointer "
-			 "variable with %qT type", TREE_TYPE (t));
-		  remove = true;
-		  break;
+		  if (!INTEGRAL_TYPE_P (type)
+		      && !SCALAR_FLOAT_TYPE_P (type)
+		      && TREE_CODE (type) != POINTER_TYPE)
+		    {
+		      error ("linear clause applied to non-integral, "
+			     "non-floating, non-pointer variable with %qT type",
+			     TREE_TYPE (t));
+		      remove = true;
+		      break;
+		    }
+		}
+	      else
+		{
+		  if (!INTEGRAL_TYPE_P (type)
+		      && TREE_CODE (type) != POINTER_TYPE)
+		    {
+		      error ("linear clause applied to non-integral non-pointer "
+			     "variable with %qT type", TREE_TYPE (t));
+		      remove = true;
+		      break;
+		    }
 		}
 	    }
 	  t = OMP_CLAUSE_LINEAR_STEP (c);
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses3.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses3.c
index 579b718..0b5ace6 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses3.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses3.c
@@ -6,31 +6,31 @@
 int A[N], B[N], C[N];
 int main (void)
 {
-#pragma simd private (B) linear(B:1) /* { dg-error "more than one clause" } */
+#pragma simd private (B) linear(B:1) /* { dg-error "applied to non-integral" } */
   for (int ii = 0; ii < N; ii++)
     {
       A[ii] = B[ii] + C[ii];
     }
 
-#pragma simd private (B, C) linear(B:1) /* { dg-error "more than one clause" } */
+#pragma simd private (B, C) linear(B:1) /* { dg-error "applied to non-integral" } */
   for (int ii = 0; ii < N; ii++)
     {
       A[ii] = B[ii] + C[ii];
     }
 
-#pragma simd private (B) linear(C:2, B:1) /* { dg-error "more than one clause" } */
+#pragma simd private (B) linear(C:2, B:1) /* { dg-error "applied to non-integral" } */
   for (int ii = 0; ii < N; ii++)
     {
       A[ii] = B[ii] + C[ii];
     }
 
-#pragma simd reduction (+:B) linear(B:1) /* { dg-error "more than one clause" } */
+#pragma simd reduction (+:B) linear(B:1) /* { dg-error "applied to non-integral" } */
   for (int ii = 0; ii < N; ii++)
     {
       A[ii] = B[ii] + C[ii];
     }
 
-#pragma simd reduction (+:B) linear(B) /* { dg-error "more than one clause" } */
+#pragma simd reduction (+:B) linear(B) /* { dg-error "applied to non-integral" } */
   for (int ii = 0; ii < N; ii++)
     {
       A[ii] = B[ii] + C[ii];
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses4.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses4.c
new file mode 100644
index 0000000..87f0c5d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses4.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+#define N 1000
+
+int A, B, C;
+double D;
+
+int main (void)
+{
+  #pragma simd linear (D:10)
+  for (int ii = 0; ii < N; ii++)
+    ;
+
+  #pragma simd private (B) linear(B:1) /* { dg-error "more than once" } */
+  for (int ii = 0; ii < N; ii++)
+    ;
+
+  #pragma simd private (B, C) linear(B:1) /* { dg-error "more than once" } */
+  for (int ii = 0; ii < N; ii++)
+    ;
+
+  #pragma simd private (B) linear(C:2, B:1) /* { dg-error "more than once" } */
+  for (int ii = 0; ii < N; ii++)
+    ;
+
+  #pragma simd reduction (+:B) linear(B:1) /* { dg-error "more than once" } */
+  for (int ii = 0; ii < N; ii++)
+    ;
+
+  #pragma simd reduction (+:B) linear(B) /* { dg-error "more than once" } */
+  for (int ii = 0; ii < N; ii++)
+    ;
+
+  return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/pr69363.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/pr69363.c
new file mode 100644
index 0000000..1d1bb04
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/pr69363.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+double t1 (double *x, int N)
+{
+  double result = 0.0;
+
+  #pragma simd reduction (max: result)
+  for (int i = 0; i < N; ++i)
+    result = x[i] > result ? x[i] : result;
+
+  return result;
+}


  -- Ilya



More information about the Gcc-patches mailing list