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