Hi!

In the testcase in the PR (not valid OpenMP, so not adding it to the
testsuite) predictive commoning optimizes a while (!x); loop with
volatile x into if (!x) for (;;);, because, while the stmt has volatile
ops, the COMPONENT_REF created by omp-low.c doesn't have TREE_THIS_VOLATILE
set on it (the FIELD_DECL does as well as the type of COMPONENT_REF).

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk and 4.7 branch.

2012-05-21  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/53436
        * omp-low.c (omp_build_component_ref): New function.
        (build_receiver_ref, build_sender_ref, create_task_copyfn): Use it.

--- gcc/omp-low.c.jj    2012-05-17 08:40:45.000000000 +0200
+++ gcc/omp-low.c       2012-05-21 15:38:25.091066781 +0200
@@ -852,6 +852,19 @@ omp_copy_decl_1 (tree var, omp_context *
   return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
 }
 
+/* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
+   as appropriate.  */
+static tree
+omp_build_component_ref (tree obj, tree field)
+{
+  tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
+  if (TREE_THIS_VOLATILE (field))
+    TREE_THIS_VOLATILE (ret) |= 1;
+  if (TREE_READONLY (field))
+    TREE_READONLY (ret) |= 1;
+  return ret;
+}
+
 /* Build tree nodes to access the field for VAR on the receiver side.  */
 
 static tree
@@ -866,7 +879,7 @@ build_receiver_ref (tree var, bool by_re
     field = x;
 
   x = build_simple_mem_ref (ctx->receiver_decl);
-  x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL);
+  x = omp_build_component_ref (x, field);
   if (by_ref)
     x = build_simple_mem_ref (x);
 
@@ -916,8 +929,7 @@ static tree
 build_sender_ref (tree var, omp_context *ctx)
 {
   tree field = lookup_sfield (var, ctx);
-  return build3 (COMPONENT_REF, TREE_TYPE (field),
-                ctx->sender_decl, field, NULL);
+  return omp_build_component_ref (ctx->sender_decl, field);
 }
 
 /* Add a new field for VAR inside the structure CTX->SENDER_DECL.  */
@@ -6529,7 +6541,7 @@ create_task_copyfn (gimple task_stmt, om
          sf = (tree) n->value;
          sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
          src = build_simple_mem_ref_loc (loc, sarg);
-         src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
+         src = omp_build_component_ref (src, sf);
          t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
          append_to_statement_list (t, &list);
        }
@@ -6552,9 +6564,9 @@ create_task_copyfn (gimple task_stmt, om
        if (tcctx.cb.decl_map)
          sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
        src = build_simple_mem_ref_loc (loc, sarg);
-       src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
+       src = omp_build_component_ref (src, sf);
        dst = build_simple_mem_ref_loc (loc, arg);
-       dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
+       dst = omp_build_component_ref (dst, f);
        t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
        append_to_statement_list (t, &list);
        break;
@@ -6575,14 +6587,14 @@ create_task_copyfn (gimple task_stmt, om
            if (tcctx.cb.decl_map)
              sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
            src = build_simple_mem_ref_loc (loc, sarg);
-           src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
+           src = omp_build_component_ref (src, sf);
            if (use_pointer_for_field (decl, NULL) || is_reference (decl))
              src = build_simple_mem_ref_loc (loc, src);
          }
        else
          src = decl;
        dst = build_simple_mem_ref_loc (loc, arg);
-       dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
+       dst = omp_build_component_ref (dst, f);
        t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
        append_to_statement_list (t, &list);
        break;
@@ -6601,14 +6613,14 @@ create_task_copyfn (gimple task_stmt, om
            if (tcctx.cb.decl_map)
              sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
            src = build_simple_mem_ref_loc (loc, sarg);
-           src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
+           src = omp_build_component_ref (src, sf);
            if (use_pointer_for_field (decl, NULL))
              src = build_simple_mem_ref_loc (loc, src);
          }
        else
          src = decl;
        dst = build_simple_mem_ref_loc (loc, arg);
-       dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
+       dst = omp_build_component_ref (dst, f);
        t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
        append_to_statement_list (t, &list);
        break;
@@ -6640,10 +6652,10 @@ create_task_copyfn (gimple task_stmt, om
          sf = (tree) n->value;
          sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
          src = build_simple_mem_ref_loc (loc, sarg);
-         src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
+         src = omp_build_component_ref (src, sf);
          src = build_simple_mem_ref_loc (loc, src);
          dst = build_simple_mem_ref_loc (loc, arg);
-         dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
+         dst = omp_build_component_ref (dst, f);
          t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
          append_to_statement_list (t, &list);
          n = splay_tree_lookup (ctx->field_map,
@@ -6651,7 +6663,7 @@ create_task_copyfn (gimple task_stmt, om
          df = (tree) n->value;
          df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
          ptr = build_simple_mem_ref_loc (loc, arg);
-         ptr = build3 (COMPONENT_REF, TREE_TYPE (df), ptr, df, NULL);
+         ptr = omp_build_component_ref (ptr, df);
          t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
                      build_fold_addr_expr_loc (loc, dst));
          append_to_statement_list (t, &list);

        Jakub

Reply via email to