This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp4] Some further little steps towards #pragma omp simd support
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>, Aldy Hernandez <aldyh at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 23 Apr 2013 16:48:40 +0200
- Subject: [gomp4] Some further little steps towards #pragma omp simd support
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
This patch fixes handling of #pragma omp simd with pointer vars, or
noreturn bodies, expands some aligned clauses into __builtin_assume_aligned
(though, had to limit that to a few hopefully common cases so far,
namely pointer automatic vars that aren't shared in outer context
(because otherwise it can lead into ptr = ptr assignments) and array
type global vars, not sure what to do about other aligned clauses, right now
they are dropped on the floor). The patch also fixes a few ICEs and missed
checks.
Tested on x86_64-linux, committed to gomp-4_0-branch.
2013-04-23 Jakub Jelinek <jakub@redhat.com>
* Makefile.in (omp-low.o): Depend on $(TARGET_H).
* gimplify.c (gimplify_adjust_omp_clauses): For linear clauses
if outer_context is non-NULL, but not ORT_COMBINED_PARALLEL,
call omp_notice_variable. Remove aligned clauses that can't
be handled yet.
* omp-low.c: Include target.h.
(scan_sharing_clauses): For aligned clauses with global arrays
register local replacement.
(omp_clause_aligned_alignment): New function.
(lower_rec_input_clauses): For aligned clauses for global
arrays or automatic pointers emit __builtin_assume_aligned
before the loop if possible.
(expand_omp_regimplify_p, expand_omp_build_assign): New functions.
(expand_omp_simd): Use them. Handle pointer iterators and broken
loops.
(lower_omp_for): Call lower_omp on gimple_omp_body_ptr after
calling lower_rec_input_clauses, not before it.
cp/
* semantics.c (finish_omp_clauses): On OMP_CLAUSE_LINEAR clauses
verify OMP_CLAUSE_DECL has integral or pointer type, and handle
linear steps for pointer type decls. FIx up handling of
OMP_CLAUSE_UNIFORM.
testsuite/
* c-c++-common/gomp/simd3.c: New test.
* c-c++-common/gomp/simd4.c: New test.
* c-c++-common/gomp/simd5.c: New test.
--- gcc/Makefile.in.jj 2013-03-20 10:08:27.000000000 +0100
+++ gcc/Makefile.in 2013-04-22 16:22:37.131008342 +0200
@@ -2535,7 +2535,7 @@ omp-low.o : omp-low.c $(CONFIG_H) $(SYST
$(RTL_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_CORE_H) \
$(TREE_FLOW_H) $(FLAGS_H) $(EXPR_H) $(DIAGNOSTIC_CORE_H) \
$(TREE_PASS_H) $(GGC_H) $(EXCEPT_H) $(SPLAY_TREE_H) $(OPTABS_H) \
- $(CFGLOOP_H) tree-iterator.h gt-omp-low.h
+ $(CFGLOOP_H) tree-iterator.h $(TARGET_H) gt-omp-low.h
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TREE_H) $(TREE_PRETTY_PRINT_H)
omega.o : omega.c $(OMEGA_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
--- gcc/gimplify.c.jj 2013-04-19 14:51:38.000000000 +0200
+++ gcc/gimplify.c 2013-04-22 18:14:43.519471249 +0200
@@ -6473,24 +6473,28 @@ gimplify_adjust_omp_clauses (tree *list_
}
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
&& ctx->outer_context
- && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
&& !(OMP_CLAUSE_LINEAR_NO_COPYIN (c)
&& OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
&& !is_global_var (decl))
{
- n = splay_tree_lookup (ctx->outer_context->variables,
- (splay_tree_key) decl);
- if (n == NULL
- || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
+ if (ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
{
- int flags = OMP_CLAUSE_LINEAR_NO_COPYIN (c)
- ? GOVD_LASTPRIVATE : GOVD_SHARED;
- if (n == NULL)
- omp_add_variable (ctx->outer_context, decl,
- flags | GOVD_SEEN);
- else
- n->value |= flags | GOVD_SEEN;
+ n = splay_tree_lookup (ctx->outer_context->variables,
+ (splay_tree_key) decl);
+ if (n == NULL
+ || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
+ {
+ int flags = OMP_CLAUSE_LINEAR_NO_COPYIN (c)
+ ? GOVD_LASTPRIVATE : GOVD_SHARED;
+ if (n == NULL)
+ omp_add_variable (ctx->outer_context, decl,
+ flags | GOVD_SEEN);
+ else
+ n->value |= flags | GOVD_SEEN;
+ }
}
+ else
+ omp_notice_variable (ctx->outer_context, decl, true);
}
}
break;
@@ -6510,6 +6514,39 @@ gimplify_adjust_omp_clauses (tree *list_
{
n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
remove = n == NULL || !(n->value & GOVD_SEEN);
+ if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
+ {
+ struct gimplify_omp_ctx *octx;
+ if (n != NULL
+ && (n->value & (GOVD_DATA_SHARE_CLASS
+ & ~GOVD_FIRSTPRIVATE)))
+ remove = true;
+ else
+ for (octx = ctx->outer_context; octx;
+ octx = octx->outer_context)
+ {
+ n = splay_tree_lookup (octx->variables,
+ (splay_tree_key) decl);
+ if (n == NULL)
+ continue;
+ if (n->value & GOVD_LOCAL)
+ break;
+ /* We have to avoid assigning a shared variable
+ to itself when trying to add
+ __builtin_assume_aligned. */
+ if (n->value & GOVD_SHARED)
+ {
+ remove = true;
+ break;
+ }
+ }
+ }
+ }
+ else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+ {
+ n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
+ if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
+ remove = true;
}
break;
--- gcc/omp-low.c.jj 2013-04-19 14:51:38.000000000 +0200
+++ gcc/omp-low.c 2013-04-23 15:05:29.763583104 +0200
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.
#include "splay-tree.h"
#include "optabs.h"
#include "cfgloop.h"
+#include "target.h"
/* Lowering of OpenMP parallel and workshare constructs proceeds in two
@@ -1490,7 +1491,13 @@ scan_sharing_clauses (tree clauses, omp_
case OMP_CLAUSE_MERGEABLE:
case OMP_CLAUSE_PROC_BIND:
case OMP_CLAUSE_SAFELEN:
+ break;
+
case OMP_CLAUSE_ALIGNED:
+ decl = OMP_CLAUSE_DECL (c);
+ if (is_global_var (decl)
+ && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+ install_var_local (decl, ctx);
break;
default:
@@ -2275,6 +2282,49 @@ omp_reduction_init (tree clause, tree ty
}
}
+/* Return alignment to be assumed for var in CLAUSE, which should be
+ OMP_CLAUSE_ALIGNED. */
+
+static tree
+omp_clause_aligned_alignment (tree clause)
+{
+ if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
+ return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause);
+
+ /* Otherwise return implementation defined alignment. */
+ unsigned int al = 1;
+ enum machine_mode mode, vmode;
+ int vs = targetm.vectorize.autovectorize_vector_sizes ();
+ if (vs)
+ vs = 1 << floor_log2 (vs);
+ static enum mode_class classes[]
+ = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
+ for (int i = 0; i < 4; i += 2)
+ for (mode = GET_CLASS_NARROWEST_MODE (classes[i]);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ {
+ vmode = targetm.vectorize.preferred_simd_mode (mode);
+ if (GET_MODE_CLASS (vmode) != classes[i + 1])
+ continue;
+ while (vs
+ && GET_MODE_SIZE (vmode) < vs
+ && GET_MODE_2XWIDER_MODE (vmode) != VOIDmode)
+ vmode = GET_MODE_2XWIDER_MODE (vmode);
+
+ tree type = lang_hooks.types.type_for_mode (mode, 1);
+ if (type == NULL_TREE || TYPE_MODE (type) != mode)
+ continue;
+ type = build_vector_type (type, GET_MODE_SIZE (vmode)
+ / GET_MODE_SIZE (mode));
+ if (TYPE_MODE (type) != vmode)
+ continue;
+ if (TYPE_ALIGN_UNIT (type) > al)
+ al = TYPE_ALIGN_UNIT (type);
+ }
+ return build_int_cst (integer_type_node, al);
+}
+
/* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
from the receiver (aka child) side and initializers for REFERENCE_TYPE
private variables. Initialization statements go in ILIST, while calls
@@ -2329,6 +2379,42 @@ lower_rec_input_clauses (tree clauses, g
continue;
}
break;
+ case OMP_CLAUSE_ALIGNED:
+ if (pass == 0)
+ continue;
+ var = OMP_CLAUSE_DECL (c);
+ if (TREE_CODE (TREE_TYPE (var)) == POINTER_TYPE
+ && !is_global_var (var))
+ {
+ new_var = maybe_lookup_decl (var, ctx);
+ if (new_var == NULL_TREE)
+ new_var = maybe_lookup_decl_in_outer_ctx (var, ctx);
+ x = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
+ x = build_call_expr_loc (clause_loc, x, 2, new_var,
+ omp_clause_aligned_alignment (c));
+ x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
+ x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
+ gimplify_and_add (x, ilist);
+ }
+ else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
+ && is_global_var (var))
+ {
+ tree ptype = build_pointer_type (TREE_TYPE (var)), t, t2;
+ new_var = lookup_decl (var, ctx);
+ t = maybe_lookup_decl_in_outer_ctx (var, ctx);
+ t = build_fold_addr_expr_loc (clause_loc, t);
+ t2 = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
+ t = build_call_expr_loc (clause_loc, t2, 2, t,
+ omp_clause_aligned_alignment (c));
+ t = fold_convert_loc (clause_loc, ptype, t);
+ x = create_tmp_var (ptype, NULL);
+ t = build2 (MODIFY_EXPR, ptype, x, t);
+ gimplify_and_add (t, ilist);
+ t = build_simple_mem_ref_loc (clause_loc, x);
+ SET_DECL_VALUE_EXPR (new_var, t);
+ DECL_HAS_VALUE_EXPR_P (new_var) = 1;
+ }
+ continue;
default:
continue;
}
@@ -3422,6 +3508,43 @@ optimize_omp_library_calls (gimple entry
}
}
+/* Callback for expand_omp_build_assign. Return non-NULL if *tp needs to be
+ regimplified. */
+
+static tree
+expand_omp_regimplify_p (tree *tp, int *walk_subtrees, void *)
+{
+ tree t = *tp;
+
+ /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
+ if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
+ return t;
+
+ if (TREE_CODE (t) == ADDR_EXPR)
+ recompute_tree_invariant_for_addr_expr (t);
+
+ *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
+ return NULL_TREE;
+}
+
+/* Prepend TO = FROM assignment before *GSI_P. */
+
+static void
+expand_omp_build_assign (gimple_stmt_iterator *gsi_p, tree to, tree from)
+{
+ bool simple_p = DECL_P (to) && TREE_ADDRESSABLE (to);
+ from = force_gimple_operand_gsi (gsi_p, from, simple_p, NULL_TREE,
+ true, GSI_SAME_STMT);
+ gimple stmt = gimple_build_assign (to, from);
+ gsi_insert_before (gsi_p, stmt, GSI_SAME_STMT);
+ if (walk_tree (&from, expand_omp_regimplify_p, NULL, NULL)
+ || walk_tree (&to, expand_omp_regimplify_p, NULL, NULL))
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, &gsi);
+ }
+}
+
/* Expand the OpenMP parallel or task directive starting at REGION. */
static void
@@ -4802,38 +4925,27 @@ expand_omp_simd (struct omp_region *regi
else
{
counts[i] = create_tmp_reg (type, ".count");
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- stmt = gimple_build_assign (counts[i], t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ expand_omp_build_assign (&gsi, counts[i], t);
}
if (SSA_VAR_P (fd->loop.n2))
{
if (i == 0)
t = counts[0];
else
- {
- t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- }
- stmt = gimple_build_assign (fd->loop.n2, t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
+ expand_omp_build_assign (&gsi, fd->loop.n2, t);
}
}
}
- t = fold_convert (type, fd->loop.n1);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- gsi_insert_before (&gsi, gimple_build_assign (fd->loop.v, t), GSI_SAME_STMT);
+ expand_omp_build_assign (&gsi, fd->loop.v, fold_convert (type, fd->loop.n1));
if (fd->collapse > 1)
for (i = 0; i < fd->collapse; i++)
{
+ tree itype = TREE_TYPE (fd->loops[i].v);
+ if (POINTER_TYPE_P (itype))
+ itype = signed_type_for (itype);
t = fold_convert (TREE_TYPE (fd->loops[i].v), fd->loops[i].n1);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- gsi_insert_before (&gsi, gimple_build_assign (fd->loops[i].v, t),
- GSI_SAME_STMT);
+ expand_omp_build_assign (&gsi, fd->loops[i].v, t);
}
/* Remove the GIMPLE_OMP_FOR statement. */
@@ -4850,37 +4962,42 @@ expand_omp_simd (struct omp_region *regi
t = fold_build_pointer_plus (fd->loop.v, fd->loop.step);
else
t = fold_build2 (PLUS_EXPR, type, fd->loop.v, fd->loop.step);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- stmt = gimple_build_assign (fd->loop.v, t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ expand_omp_build_assign (&gsi, fd->loop.v, t);
if (fd->collapse > 1)
{
i = fd->collapse - 1;
- t = fold_convert (TREE_TYPE (fd->loops[i].v), fd->loops[i].step);
- t = build2 (PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
- fd->loops[i].v, t);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- stmt = gimple_build_assign (fd->loops[i].v, t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
+ {
+ t = fold_convert (sizetype, fd->loop.step);
+ t = fold_build_pointer_plus (fd->loops[i].v, t);
+ }
+ else
+ {
+ t = fold_convert (TREE_TYPE (fd->loops[i].v),
+ fd->loops[i].step);
+ t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
+ fd->loops[i].v, t);
+ }
+ expand_omp_build_assign (&gsi, fd->loops[i].v, t);
for (i = fd->collapse - 1; i > 0; i--)
{
tree itype = TREE_TYPE (fd->loops[i].v);
tree itype2 = TREE_TYPE (fd->loops[i - 1].v);
+ if (POINTER_TYPE_P (itype2))
+ itype2 = signed_type_for (itype2);
t = build3 (COND_EXPR, itype2,
build2 (fd->loops[i].cond_code, boolean_type_node,
fd->loops[i].v,
fold_convert (itype, fd->loops[i].n2)),
build_int_cst (itype2, 0),
fold_convert (itype2, fd->loops[i - 1].step));
- t = build2 (PLUS_EXPR, itype2, fd->loops[i - 1].v, t);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- stmt = gimple_build_assign (fd->loops[i - 1].v, t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i - 1].v)))
+ t = fold_build_pointer_plus (fd->loops[i - 1].v, t);
+ else
+ t = fold_build2 (PLUS_EXPR, itype2, fd->loops[i - 1].v, t);
+ expand_omp_build_assign (&gsi, fd->loops[i - 1].v, t);
t = build3 (COND_EXPR, itype,
build2 (fd->loops[i].cond_code, boolean_type_node,
@@ -4888,10 +5005,7 @@ expand_omp_simd (struct omp_region *regi
fold_convert (itype, fd->loops[i].n2)),
fd->loops[i].v,
fold_convert (itype, fd->loops[i].n1));
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- stmt = gimple_build_assign (fd->loops[i].v, t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ expand_omp_build_assign (&gsi, fd->loops[i].v, t);
}
}
@@ -4906,7 +5020,16 @@ expand_omp_simd (struct omp_region *regi
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
t = build2 (fd->loop.cond_code, boolean_type_node, fd->loop.v, t);
- gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
+ stmt = gimple_build_cond_empty (t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+ if (walk_tree (gimple_cond_lhs_ptr (stmt), expand_omp_regimplify_p,
+ NULL, NULL)
+ || walk_tree (gimple_cond_rhs_ptr (stmt), expand_omp_regimplify_p,
+ NULL, NULL))
+ {
+ gsi = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, &gsi);
+ }
/* Remove GIMPLE_OMP_RETURN. */
gsi = gsi_last_bb (exit_bb);
@@ -4923,18 +5046,22 @@ expand_omp_simd (struct omp_region *regi
e = BRANCH_EDGE (l1_bb);
ne = FALLTHRU_EDGE (l1_bb);
e->flags = EDGE_TRUE_VALUE;
- ne->flags = EDGE_FALSE_VALUE;
- e->probability = REG_BR_PROB_BASE * 7 / 8;
- ne->probability = REG_BR_PROB_BASE / 8;
-
- set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
- set_immediate_dominator (CDI_DOMINATORS, l2_bb, l1_bb);
- set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
}
else
{
single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
+
+ ne = single_succ_edge (l1_bb);
+ e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
+
}
+ ne->flags = EDGE_FALSE_VALUE;
+ e->probability = REG_BR_PROB_BASE * 7 / 8;
+ ne->probability = REG_BR_PROB_BASE / 8;
+
+ set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
+ set_immediate_dominator (CDI_DOMINATORS, l2_bb, l1_bb);
+ set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
}
@@ -6583,7 +6710,6 @@ lower_omp_for (gimple_stmt_iterator *gsi
push_gimplify_context (&gctx);
lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
- lower_omp (gimple_omp_body_ptr (stmt), ctx);
block = make_node (BLOCK);
new_stmt = gimple_build_bind (NULL, NULL, block);
@@ -6608,6 +6734,8 @@ lower_omp_for (gimple_stmt_iterator *gsi
lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
+
/* Lower the header expressions. At this point, we can assume that
the header is of the form:
--- gcc/cp/semantics.c.jj 2013-04-19 14:51:38.000000000 +0200
+++ gcc/cp/semantics.c 2013-04-23 15:19:27.529086777 +0200
@@ -4058,6 +4058,15 @@ finish_omp_clauses (tree clauses)
goto check_dup_generic;
case OMP_CLAUSE_LINEAR:
name = "linear";
+ t = OMP_CLAUSE_DECL (c);
+ if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t))
+ && TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
+ {
+ error ("linear clause applied to non-integral non-pointer");
+ remove = true;
+ break;
+ }
t = OMP_CLAUSE_LINEAR_STEP (c);
if (t == NULL_TREE)
t = integer_one_node;
@@ -4073,7 +4082,20 @@ finish_omp_clauses (tree clauses)
{
t = mark_rvalue_use (t);
if (!processing_template_decl)
- t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ {
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
+ == POINTER_TYPE)
+ {
+ t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
+ OMP_CLAUSE_DECL (c), t);
+ t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
+ MINUS_EXPR, sizetype, t,
+ OMP_CLAUSE_DECL (c));
+ if (t == error_mark_node)
+ remove = true;
+ }
+ }
OMP_CLAUSE_LINEAR_STEP (c) = t;
}
goto check_dup_generic;
@@ -4385,6 +4407,7 @@ finish_omp_clauses (tree clauses)
break;
case OMP_CLAUSE_UNIFORM:
+ t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) != PARM_DECL)
{
if (processing_template_decl)
--- gcc/testsuite/c-c++-common/gomp/simd3.c.jj 2013-04-23 14:36:42.839827496 +0200
+++ gcc/testsuite/c-c++-common/gomp/simd3.c 2013-04-22 19:41:58.000000000 +0200
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { ! c } } } */
+/* { dg-options "-fopenmp" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+
+extern int a[13*13*13*13*2], b[1024], *k, l, m;
+
+void
+foo (int *q, float *p)
+{
+ int *i, *j, *n, *o;
+#pragma omp simd collapse (4) linear(k : m + 1) aligned(p, q)
+ for (i = &a[0]; i < &a[13*13*13*13*2]; i += 13*13*13*2)
+ for (j = &a[0]; j < &a[13*13*13*2]; j += 13*13*2)
+ for (n = &a[0]; n < &a[13*13*2]; n += 13*2)
+ for (o = &a[0]; o < &a[13*2]; o += 2)
+ q[k - &a[0]] *= p[k - &a[0]] + 7 * (i-&a[0]) + 14 * (j-&a[0]) + 21 * (n-&a[0]) + 28 * (o-&a[0]), k += m + 1;
+}
+
+void
+bar ()
+{
+ int *i;
+ #pragma omp simd safelen(16) aligned(a, b : 32)
+ for (i = &a[0]; i < &a[1024]; i++)
+ *i *= b[i - &a[0]];
+}
--- gcc/testsuite/c-c++-common/gomp/simd4.c.jj 2013-04-23 14:40:26.431515790 +0200
+++ gcc/testsuite/c-c++-common/gomp/simd4.c 2013-04-23 14:44:17.550158780 +0200
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { ! c } } } */
+/* { dg-options "-fopenmp" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+
+struct S *p; /* { dg-error "forward declaration" } */
+float f;
+int j;
+
+void
+foo (void)
+{
+#pragma omp simd linear(p) linear(f : 1)
+ for (int i = 0; i < 10; i++)
+ ;
+#pragma omp simd linear(j : 7.0) /* { dg-error "linear step expression must be integral" } */
+ for (int i = 0; i < 10; i++)
+ ;
+}
+
+/* { dg-error "linear clause applied to" "" { target *-*-* } 12 } */
+/* { dg-error "incomplete type" "" { target *-*-* } 12 } */
--- gcc/testsuite/c-c++-common/gomp/simd5.c.jj 2013-04-23 15:08:28.876696297 +0200
+++ gcc/testsuite/c-c++-common/gomp/simd5.c 2013-04-23 14:52:04.000000000 +0200
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! c } } } */
+/* { dg-options "-fopenmp" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+
+void baz (void) __attribute__((noreturn));
+
+void
+foo (int x)
+{
+ if (x)
+ #pragma omp simd
+ for (int i = 0; i < 10; i++)
+ baz ();
+#pragma omp simd collapse(3)
+ for (int i = 0; i < 10; i++)
+ for (int j = 0; j < 10; j++)
+ for (int k = 0; k < 10; k++)
+ baz ();
+}
Jakub