While working on another issue I noticed that is_gimple_reg was happily accepting VAR_DECLs with DECL_VALUE_EXPR even when later gimplification would replace them with something that is_gimple_reg doesn't like, leading to trouble. So I've modified is_gimple_reg to check the VALUE_EXPR.

But this breaks a couple of libgomp testcases, namely libgomp.c++/member-[45].C. This seems to be a latent bug in gimplify_omp_for:

      /* If DECL is not a gimple register, create a temporary variable to act
         as an iteration counter.  This is valid, since DECL cannot be
         modified in the body of the loop.  Similarly for any iteration vars
         in simd with collapse > 1 where the iterator vars must be
         lastprivate.  */
      if (orig_for_stmt != for_stmt)
        var = decl;
      else if (!is_gimple_reg (decl)
               || (ort == ORT_SIMD
                   && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
        {
          struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
          /* Make sure omp_add_variable is not called on it prematurely.
             We call it ourselves a few lines later.  */
          gimplify_omp_ctxp = NULL;
          var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
          gimplify_omp_ctxp = ctx;
          TREE_OPERAND (t, 0) = var;

          gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));

So we update DECL from VAR in the loop body, but we don't update it after the last iteration, when we do the increment but then don't enter the body. As a result, this test fails:

  #pragma omp parallel for lastprivate (T<Q>::t)
  for (T<Q>::t = 0; T<Q>::t < 32; T<Q>::t += 3)
    f[T<Q>::t + 2] |= 2;
  if (T<Q>::t != 33)
    __builtin_abort ();

Here T<Q>::t ends up with the value 30 because it doesn't get the last update.

Thoughts?

Jason
commit acd8bc5cb8efa16b913b9a41c25fc8810a4a7461
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Jun 10 14:55:54 2016 -0400

    	* gimple-expr.c (is_gimple_reg): Check DECL_HAS_VALUE_EXPR_P.

diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c
index ed012cc..9016e8c 100644
--- a/gcc/gimple-expr.c
+++ b/gcc/gimple-expr.c
@@ -761,6 +761,14 @@ is_gimple_reg (tree t)
   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
     return false;
 
+  /* A variable with DECL_VALUE_EXPR will be replaced by a more complex
+     expression.  */
+  if ((TREE_CODE (t) == VAR_DECL
+       || TREE_CODE (t) == PARM_DECL
+       || TREE_CODE (t) == RESULT_DECL)
+      && DECL_HAS_VALUE_EXPR_P (t))
+    return is_gimple_reg (DECL_VALUE_EXPR (t));
+
   /* Complex and vector values must have been put into SSA-like form.
      That is, no assignments to the individual components.  */
   if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE

Reply via email to