Hi!

As the patch shows, expand_omp_atomic* was relying on the
gimple_omp_atomic_load_rhs () pointer to be pointer to the type we want to
atomically load.  That doesn't work too well, because pointer conversions
are useless in GIMPLE and so we can end up with a pointer to a different
type like void.

Fixed by ignoring the addr type and instead finding the type from the
reg we want to load into.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk,
should fix a couple of libgomp fortran tests.

2018-01-15  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/83837
        * omp-expand.c (expand_omp_atomic_pipeline): Use loaded_val
        type rather than type addr's type points to.
        (expand_omp_atomic_mutex): Likewise.
        (expand_omp_atomic): Likewise.

--- gcc/omp-expand.c.jj 2018-01-03 10:19:54.483533850 +0100
+++ gcc/omp-expand.c    2018-01-15 16:07:27.626734592 +0100
@@ -6283,7 +6283,7 @@ expand_omp_atomic_pipeline (basic_block
                            int index)
 {
   tree loadedi, storedi, initial, new_storedi, old_vali;
-  tree type, itype, cmpxchg, iaddr;
+  tree type, itype, cmpxchg, iaddr, atype;
   gimple_stmt_iterator si;
   basic_block loop_header = single_succ (load_bb);
   gimple *phi, *stmt;
@@ -6297,7 +6297,8 @@ expand_omp_atomic_pipeline (basic_block
   cmpxchg = builtin_decl_explicit (fncode);
   if (cmpxchg == NULL_TREE)
     return false;
-  type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
+  type = TYPE_MAIN_VARIANT (TREE_TYPE (loaded_val));
+  atype = type;
   itype = TREE_TYPE (TREE_TYPE (cmpxchg));
 
   if (!can_compare_and_swap_p (TYPE_MODE (itype), true)
@@ -6317,6 +6318,7 @@ expand_omp_atomic_pipeline (basic_block
 
       iaddr = create_tmp_reg (build_pointer_type_for_mode (itype, ptr_mode,
                                                           true));
+      atype = itype;
       iaddr_val
        = force_gimple_operand_gsi (&si,
                                    fold_convert (TREE_TYPE (iaddr), addr),
@@ -6337,13 +6339,17 @@ expand_omp_atomic_pipeline (basic_block
   tree loaddecl = builtin_decl_explicit (fncode);
   if (loaddecl)
     initial
-      = fold_convert (TREE_TYPE (TREE_TYPE (iaddr)),
+      = fold_convert (atype,
                      build_call_expr (loaddecl, 2, iaddr,
                                       build_int_cst (NULL_TREE,
                                                      MEMMODEL_RELAXED)));
   else
-    initial = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)), iaddr,
-                     build_int_cst (TREE_TYPE (iaddr), 0));
+    {
+      tree off
+       = build_int_cst (build_pointer_type_for_mode (atype, ptr_mode,
+                                                     true), 0);
+      initial = build2 (MEM_REF, atype, iaddr, off);
+    }
 
   initial
     = force_gimple_operand_gsi (&si, initial, true, NULL_TREE, true,
@@ -6495,15 +6501,20 @@ expand_omp_atomic_mutex (basic_block loa
   t = build_call_expr (t, 0);
   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
 
-  stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
+  tree mem = build_simple_mem_ref (addr);
+  TREE_TYPE (mem) = TREE_TYPE (loaded_val);
+  TREE_OPERAND (mem, 1)
+    = fold_convert (build_pointer_type_for_mode (TREE_TYPE (mem), ptr_mode,
+                                                true),
+                   TREE_OPERAND (mem, 1));
+  stmt = gimple_build_assign (loaded_val, mem);
   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
   gsi_remove (&si, true);
 
   si = gsi_last_nondebug_bb (store_bb);
   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
 
-  stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
-                             stored_val);
+  stmt = gimple_build_assign (unshare_expr (mem), stored_val);
   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
 
   t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
@@ -6532,7 +6543,7 @@ expand_omp_atomic (struct omp_region *re
   tree loaded_val = gimple_omp_atomic_load_lhs (load);
   tree addr = gimple_omp_atomic_load_rhs (load);
   tree stored_val = gimple_omp_atomic_store_val (store);
-  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
+  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (loaded_val));
   HOST_WIDE_INT index;
 
   /* Make sure the type is one of the supported sizes.  */

        Jakub

Reply via email to