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  <ja...@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

Reply via email to