diff mbox series

[committed] Fix OpenMP atomic expansion (PR middle-end/83837)

Message ID 20180115215147.GD2063@tucnak
State New
Headers show
Series [committed] Fix OpenMP atomic expansion (PR middle-end/83837) | expand

Commit Message

Jakub Jelinek Jan. 15, 2018, 9:51 p.m. UTC
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  <jakub@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.


	Jakub
diff mbox series

Patch

--- 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.  */