diff options
author | Martin Liska <mliska@suse.cz> | 2021-06-09 13:40:10 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-06-09 13:40:10 +0200 |
commit | 739448cd8af3b3f38e91e53e9971c9ba9dd82313 (patch) | |
tree | 18f107dde85c9da8dd70a25ec52836432a51911d | |
parent | c7768f068398b267756b767f7d2f4d06d1292a8e (diff) | |
parent | ec748dc7dd2d8ca39dc503b2a6dfbe172127cd13 (diff) | |
download | gcc-739448cd8af3b3f38e91e53e9971c9ba9dd82313.zip gcc-739448cd8af3b3f38e91e53e9971c9ba9dd82313.tar.gz gcc-739448cd8af3b3f38e91e53e9971c9ba9dd82313.tar.bz2 |
Merge branch 'master' into devel/sphinx
132 files changed, 3096 insertions, 982 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b9001dd..aeec6b4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,143 @@ +2021-06-08 Andrew Pinski <apinski@marvell.com> + + PR tree-optimization/25290 + * tree-ssa-phiopt.c (xor_replacement): Delete. + (tree_ssa_phiopt_worker): Delete use of xor_replacement. + (match_simplify_replacement): Allow one cheap preparation + statement that can be moved to before the if. + +2021-06-08 Pat Haugen <pthaugen@linux.ibm.com> + + * config/rs6000/power10.md (power10-fused-load, power10-fused-store, + power10-fused_alu, power10-fused-vec, power10-fused-branch): New. + +2021-06-08 Jeff Law <jeffreyalaw@gmail.com> + + * config/h8300/logical.md (andqi3_1): Move BCLR case into define_insn_and_split. + Create length attribute on define_insn_and_split. Only split for cases which we + know will use AND. + (andqi3_1<cczn>): Renamed from andqi3_1_clobber_flags. Only handle AND here and + fix length computation. + (b<code><mode>msx): Combine QImode and HImode H8/SX patterns using iterator. + +2021-06-08 Richard Biener <rguenther@suse.de> + + PR tree-optimization/100923 + * tree-ssa-sccvn.c (valueize_refs_1): Take a pointer to + the operand vector to be valueized. + (valueize_refs): Likewise. + (valueize_shared_reference_ops_from_ref): Adjust. + (valueize_shared_reference_ops_from_call): Likewise. + (vn_reference_lookup_3): Likewise. + (vn_reference_lookup_pieces): Likewise. Re-valueize + with honoring availability when we are about to create + the ao_ref and valueized before. + (vn_reference_lookup): Likewise. + (vn_reference_insert_pieces): Adjust. + +2021-06-08 Richard Biener <rguenther@suse.de> + + * tree-vectorizer.h (_slp_instance::root_stmt): Change to... + (_slp_instance::root_stmts): ... a vector. + (SLP_INSTANCE_ROOT_STMT): Rename to ... + (SLP_INSTANCE_ROOT_STMTS): ... this. + (slp_root::root): Change to... + (slp_root::roots): ... a vector. + (slp_root::slp_root): Adjust. + * tree-vect-slp.c (_slp_instance::location): Adjust. + (vect_free_slp_instance): Release the root stmt vector. + (vect_build_slp_instance): Adjust. + (vect_analyze_slp): Likewise. + (_bb_vec_info::~_bb_vec_info): Likewise. + (vect_slp_analyze_operations): Likewise. + (vect_bb_vectorization_profitable_p): Likewise. Adjust + costs for the root stmt. + (vect_slp_check_for_constructors): Gather all BIT_INSERT_EXPRs + as root stmts. + (vect_slp_analyze_bb_1): Simplify by marking all root stmts + as pure_slp. + (vectorize_slp_instance_root_stmt): Adjust. + (vect_schedule_slp): Likewise. + +2021-06-08 Aldy Hernandez <aldyh@redhat.com> + + * gimple-ssa-evrp.c (class ssa_equiv_stack): New. + (ssa_equiv_stack::ssa_equiv_stack): New. + (ssa_equiv_stack::~ssa_equiv_stack): New. + (ssa_equiv_stack::enter): New. + (ssa_equiv_stack::leave): New. + (ssa_equiv_stack::push_replacement): New. + (ssa_equiv_stack::get_replacement): New. + (is_pointer_ssa): New. + (class pointer_equiv_analyzer): New. + (pointer_equiv_analyzer::pointer_equiv_analyzer): New. + (pointer_equiv_analyzer::~pointer_equiv_analyzer): New. + (pointer_equiv_analyzer::set_global_equiv): New. + (pointer_equiv_analyzer::set_cond_equiv): New. + (pointer_equiv_analyzer::get_equiv): New. + (pointer_equiv_analyzer::enter): New. + (pointer_equiv_analyzer::leave): New. + (pointer_equiv_analyzer::get_equiv_expr): New. + (pta_valueize): New. + (pointer_equiv_analyzer::visit_stmt): New. + (pointer_equiv_analyzer::visit_edge): New. + (hybrid_folder::value_of_expr): Call PTA. + (hybrid_folder::value_on_edge): Same. + (hybrid_folder::pre_fold_bb): New. + (hybrid_folder::post_fold_bb): New. + (hybrid_folder::pre_fold_stmt): New. + (rvrp_folder::pre_fold_bb): New. + (rvrp_folder::post_fold_bb): New. + (rvrp_folder::pre_fold_stmt): New. + (rvrp_folder::value_of_expr): Call PTA. + (rvrp_folder::value_on_edge): Same. + +2021-06-08 Jakub Jelinek <jakub@redhat.com> + + PR c++/100957 + * tree-inline.c (copy_tree_body_r): For OMP_CLAUSE_DEPEND don't + check TREE_CODE if OMP_CLAUSE_DECL is NULL. + +2021-06-08 Richard Biener <rguenther@suse.de> + + PR middle-end/100951 + * tree-vect-generic.c (expand_vector_piecewise): Build a + VECTOR_CST if all elements are constant. + (expand_vector_condition): Likewise. + (lower_vec_perm): Likewise. + (expand_vector_conversion): Likewise. + +2021-06-08 Martin Liska <mliska@suse.cz> + + * doc/invoke.texi: Document new param evrp-sparse-threshold. + +2021-06-08 Martin Liska <mliska@suse.cz> + + * genautomata.c (create_automata): Fix typo. + +2021-06-08 Kewen Lin <linkw@linux.ibm.com> + + PR tree-optimization/100794 + * tree-predcom.c (tree_predictive_commoning_loop): Add parameter + allow_unroll_p and only allow unrolling when it's true. + (tree_predictive_commoning): Add parameter allow_unroll_p and + adjust for it. + (run_tree_predictive_commoning): Likewise. + (pass_predcom::gate): Check flag_tree_loop_vectorize and + global_options_set.x_flag_predictive_commoning. + (pass_predcom::execute): Adjust for allow_unroll_p. + +2021-06-08 Kewen Lin <linkw@linux.ibm.com> + + * tree-predcom.c (execute_pred_commoning): Remove update_ssa call. + (tree_predictive_commoning_loop): Factor some cleanup stuffs into + lambda function cleanup, remove scev_reset call, and adjust return + value. + (tree_predictive_commoning): Adjust for different changed values, + only set flag TODO_update_ssa_only_virtuals if changed. + (pass_data pass_data_predcom): Remove TODO_update_ssa_only_virtuals + from todo_flags_finish. + 2021-06-07 Andrew MacLeod <amacleod@redhat.com> * gimple-range-cache.cc (class sbr_sparse_bitmap): New. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 504c3fa..217a880 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210608 +20210609 diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 838d5f1..c3a3d39 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,49 @@ +2021-06-08 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/99212 + * region-model-manager.cc + (region_model_manager::maybe_fold_binop): Add support for folding + BIT_AND_EXPR of compound_svalue and a mask constant. + * region-model.cc (region_model::get_rvalue_1): Implement + BIT_FIELD_REF in terms of... + (region_model::get_rvalue_for_bits): New function. + * region-model.h (region_model::get_rvalue_for_bits): New decl. + * store.cc (bit_range::from_mask): New function. + (selftest::test_bit_range_intersects_p): New selftest. + (selftest::assert_bit_range_from_mask_eq): New. + (ASSERT_BIT_RANGE_FROM_MASK_EQ): New macro. + (selftest::assert_no_bit_range_from_mask_eq): New. + (ASSERT_NO_BIT_RANGE_FROM_MASK): New macro. + (selftest::test_bit_range_from_mask): New selftest. + (selftest::analyzer_store_cc_tests): Call the new selftests. + * store.h (bit_range::intersects_p): New. + (bit_range::from_mask): New decl. + (concrete_binding::get_bit_range): New accessor. + (store_manager::get_concrete_binding): New overload taking + const bit_range &. + +2021-06-08 David Malcolm <dmalcolm@redhat.com> + + * analyzer.h (int_size_in_bits): New decl. + * region.cc (int_size_in_bits): New function. + (region::get_bit_size): Reimplement in terms of the above. + +2021-06-08 David Malcolm <dmalcolm@redhat.com> + + * store.cc (concrete_binding::dump_to_pp): Move bulk of + implementation to... + (bit_range::dump_to_pp): ...this new function. + (bit_range::cmp): New. + (concrete_binding::overlaps_p): Update for use of bit_range. + (concrete_binding::cmp_ptr_ptr): Likewise. + * store.h (struct bit_range): New. + (class concrete_binding): Replace fields m_start_bit_offset and + m_size_in_bits with new field m_bit_range. + +2021-06-08 David Malcolm <dmalcolm@redhat.com> + + * svalue.h (conjured_svalue::iterator_t): Delete. + 2021-06-03 David Malcolm <dmalcolm@redhat.com> * store.h (store::get_direct_binding): Remove unused decl. diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h index fb568e4..525eb06 100644 --- a/gcc/analyzer/analyzer.h +++ b/gcc/analyzer/analyzer.h @@ -144,6 +144,8 @@ typedef offset_int bit_offset_t; typedef offset_int bit_size_t; typedef offset_int byte_size_t; +extern bool int_size_in_bits (const_tree type, bit_size_t *out); + /* The location of a region expressesd as an offset relative to a base region. */ diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index dfd2413..0ca0c8a 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -480,9 +480,49 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op, break; case BIT_AND_EXPR: if (cst1) - if (zerop (cst1) && INTEGRAL_TYPE_P (type)) - /* "(ARG0 & 0)" -> "0". */ - return get_or_create_constant_svalue (build_int_cst (type, 0)); + { + if (zerop (cst1) && INTEGRAL_TYPE_P (type)) + /* "(ARG0 & 0)" -> "0". */ + return get_or_create_constant_svalue (build_int_cst (type, 0)); + + /* Support masking out bits from a compound_svalue, as this + is generated when accessing bitfields. */ + if (const compound_svalue *compound_sval + = arg0->dyn_cast_compound_svalue ()) + { + const binding_map &map = compound_sval->get_map (); + unsigned HOST_WIDE_INT mask = TREE_INT_CST_LOW (cst1); + /* If "mask" is a contiguous range of set bits, see if the + compound_sval has a value for those bits. */ + bit_range bits (0, 0); + if (bit_range::from_mask (mask, &bits)) + { + const concrete_binding *conc + = get_store_manager ()->get_concrete_binding (bits, + BK_direct); + if (const svalue *sval = map.get (conc)) + { + /* We have a value; + shift it by the correct number of bits. */ + const svalue *lhs = get_or_create_cast (type, sval); + HOST_WIDE_INT bit_offset + = bits.get_start_bit_offset ().to_shwi (); + tree shift_amt = build_int_cst (type, bit_offset); + const svalue *shift_sval + = get_or_create_constant_svalue (shift_amt); + const svalue *shifted_sval + = get_or_create_binop (type, + LSHIFT_EXPR, + lhs, shift_sval); + /* Reapply the mask (needed for negative + signed bitfields). */ + return get_or_create_binop (type, + BIT_AND_EXPR, + shifted_sval, arg1); + } + } + } + } break; case TRUTH_ANDIF_EXPR: case TRUTH_AND_EXPR: diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index c7038dd..0d363fb 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -1357,7 +1357,18 @@ region_model::get_rvalue_1 (path_var pv, region_model_context *ctxt) break; case BIT_FIELD_REF: - return m_mgr->get_or_create_unknown_svalue (TREE_TYPE (pv.m_tree)); + { + tree expr = pv.m_tree; + tree op0 = TREE_OPERAND (expr, 0); + const region *reg = get_lvalue (op0, ctxt); + tree num_bits = TREE_OPERAND (expr, 1); + tree first_bit_offset = TREE_OPERAND (expr, 2); + gcc_assert (TREE_CODE (num_bits) == INTEGER_CST); + gcc_assert (TREE_CODE (first_bit_offset) == INTEGER_CST); + bit_range bits (TREE_INT_CST_LOW (first_bit_offset), + TREE_INT_CST_LOW (num_bits)); + return get_rvalue_for_bits (TREE_TYPE (expr), reg, bits); + } case SSA_NAME: case VAR_DECL: @@ -1686,6 +1697,58 @@ region_model::deref_rvalue (const svalue *ptr_sval, tree ptr_tree, return m_mgr->get_symbolic_region (ptr_sval); } +/* Attempt to get BITS within any value of REG, as TYPE. + In particular, extract values from compound_svalues for the case + where there's a concrete binding at BITS. + Return an unknown svalue if we can't handle the given case. */ + +const svalue * +region_model::get_rvalue_for_bits (tree type, + const region *reg, + const bit_range &bits) +{ + const svalue *sval = get_store_value (reg); + if (const compound_svalue *compound_sval = sval->dyn_cast_compound_svalue ()) + { + const binding_map &map = compound_sval->get_map (); + binding_map result_map; + for (auto iter : map) + { + const binding_key *key = iter.first; + if (const concrete_binding *conc_key + = key->dyn_cast_concrete_binding ()) + { + /* Ignore concrete bindings outside BITS. */ + if (!conc_key->get_bit_range ().intersects_p (bits)) + continue; + if ((conc_key->get_start_bit_offset () + < bits.get_start_bit_offset ()) + || (conc_key->get_next_bit_offset () + > bits.get_next_bit_offset ())) + { + /* If we have any concrete keys that aren't fully within BITS, + then bail out. */ + return m_mgr->get_or_create_unknown_svalue (type); + } + const concrete_binding *offset_conc_key + = m_mgr->get_store_manager ()->get_concrete_binding + (conc_key->get_start_bit_offset () + - bits.get_start_bit_offset (), + conc_key->get_size_in_bits (), + conc_key->get_kind ()); + const svalue *sval = iter.second; + result_map.put (offset_conc_key, sval); + } + else + /* If we have any symbolic keys we can't get it as bits. */ + return m_mgr->get_or_create_unknown_svalue (type); + } + return m_mgr->get_or_create_compound_svalue (type, result_map); + } + + return m_mgr->get_or_create_unknown_svalue (type); +} + /* A subclass of pending_diagnostic for complaining about writes to constant regions of memory. */ diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index a169396..5e43e54 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -509,6 +509,10 @@ class region_model const region *deref_rvalue (const svalue *ptr_sval, tree ptr_tree, region_model_context *ctxt); + const svalue *get_rvalue_for_bits (tree type, + const region *reg, + const bit_range &bits); + void set_value (const region *lhs_reg, const svalue *rhs_sval, region_model_context *ctxt); void set_value (tree lhs, tree rhs, region_model_context *ctxt); diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index 6db1fc9..5f246df 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -208,6 +208,29 @@ region::get_byte_size (byte_size_t *out) const return true; } +/* If the size of TYPE (in bits) is constant, write it to *OUT + and return true. + Otherwise return false. */ + +bool +int_size_in_bits (const_tree type, bit_size_t *out) +{ + if (INTEGRAL_TYPE_P (type)) + { + *out = TYPE_PRECISION (type); + return true; + } + + tree sz = TYPE_SIZE (type); + if (sz && tree_fits_uhwi_p (sz)) + { + *out = TREE_INT_CST_LOW (sz); + return true; + } + else + return false; +} + /* If the size of this region (in bits) is known statically, write it to *OUT and return true. Otherwise return false. */ @@ -215,11 +238,13 @@ region::get_byte_size (byte_size_t *out) const bool region::get_bit_size (bit_size_t *out) const { - byte_size_t byte_size; - if (!get_byte_size (&byte_size)) + tree type = get_type (); + + /* Bail out e.g. for heap-allocated regions. */ + if (!type) return false; - *out = byte_size * BITS_PER_UNIT; - return true; + + return int_size_in_bits (type, out); } /* Get the field within RECORD_TYPE at BIT_OFFSET. */ diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index b1874a5..699de94 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -236,15 +236,12 @@ binding_key::cmp (const binding_key *k1, const binding_key *k2) } } -/* class concrete_binding : public binding_key. */ - -/* Implementation of binding_key::dump_to_pp vfunc for concrete_binding. */ +/* struct struct bit_range. */ void -concrete_binding::dump_to_pp (pretty_printer *pp, bool simple) const +bit_range::dump_to_pp (pretty_printer *pp) const { - binding_key::dump_to_pp (pp, simple); - pp_string (pp, ", start: "); + pp_string (pp, "start: "); pp_wide_int (pp, m_start_bit_offset, SIGNED); pp_string (pp, ", size: "); pp_wide_int (pp, m_size_in_bits, SIGNED); @@ -252,12 +249,92 @@ concrete_binding::dump_to_pp (pretty_printer *pp, bool simple) const pp_wide_int (pp, get_next_bit_offset (), SIGNED); } +int +bit_range::cmp (const bit_range &br1, const bit_range &br2) +{ + if (int start_cmp = wi::cmps (br1.m_start_bit_offset, + br2.m_start_bit_offset)) + return start_cmp; + + return wi::cmpu (br1.m_size_in_bits, br2.m_size_in_bits); +} + +/* If MASK is a contiguous range of set bits, write them + to *OUT and return true. + Otherwise return false. */ + +bool +bit_range::from_mask (unsigned HOST_WIDE_INT mask, bit_range *out) +{ + unsigned iter_bit_idx = 0; + unsigned HOST_WIDE_INT iter_bit_mask = 1; + + /* Find the first contiguous run of set bits in MASK. */ + + /* Find first set bit in MASK. */ + while (iter_bit_idx < HOST_BITS_PER_WIDE_INT) + { + if (mask & iter_bit_mask) + break; + iter_bit_idx++; + iter_bit_mask <<= 1; + } + if (iter_bit_idx == HOST_BITS_PER_WIDE_INT) + /* MASK is zero. */ + return false; + + unsigned first_set_iter_bit_idx = iter_bit_idx; + unsigned num_set_bits = 1; + iter_bit_idx++; + iter_bit_mask <<= 1; + + /* Find next unset bit in MASK. */ + while (iter_bit_idx < HOST_BITS_PER_WIDE_INT) + { + if (!(mask & iter_bit_mask)) + break; + num_set_bits++; + iter_bit_idx++; + iter_bit_mask <<= 1; + } + if (iter_bit_idx == HOST_BITS_PER_WIDE_INT) + { + *out = bit_range (first_set_iter_bit_idx, num_set_bits); + return true; + } + + /* We now have the first contiguous run of set bits in MASK. + Fail if any other bits are set. */ + while (iter_bit_idx < HOST_BITS_PER_WIDE_INT) + { + if (mask & iter_bit_mask) + return false; + iter_bit_idx++; + iter_bit_mask <<= 1; + } + + *out = bit_range (first_set_iter_bit_idx, num_set_bits); + return true; +} + +/* class concrete_binding : public binding_key. */ + +/* Implementation of binding_key::dump_to_pp vfunc for concrete_binding. */ + +void +concrete_binding::dump_to_pp (pretty_printer *pp, bool simple) const +{ + binding_key::dump_to_pp (pp, simple); + pp_string (pp, ", "); + m_bit_range.dump_to_pp (pp); +} + /* Return true if this binding overlaps with OTHER. */ bool concrete_binding::overlaps_p (const concrete_binding &other) const { - if (m_start_bit_offset < other.get_next_bit_offset () + if (get_start_bit_offset () < other.get_next_bit_offset () && get_next_bit_offset () > other.get_start_bit_offset ()) return true; return false; @@ -274,10 +351,7 @@ concrete_binding::cmp_ptr_ptr (const void *p1, const void *p2) if (int kind_cmp = b1->get_kind () - b2->get_kind ()) return kind_cmp; - if (int start_cmp = wi::cmps (b1->m_start_bit_offset, b2->m_start_bit_offset)) - return start_cmp; - - return wi::cmpu (b1->m_size_in_bits, b2->m_size_in_bits); + return bit_range::cmp (b1->m_bit_range, b2->m_bit_range); } /* class symbolic_binding : public binding_key. */ @@ -2432,6 +2506,132 @@ store::loop_replay_fixup (const store *other_store, namespace selftest { +/* Verify that bit_range::intersects_p works as expected. */ + +static void +test_bit_range_intersects_p () +{ + bit_range b0 (0, 1); + bit_range b1 (1, 1); + bit_range b2 (2, 1); + bit_range b3 (3, 1); + bit_range b4 (4, 1); + bit_range b5 (5, 1); + bit_range b6 (6, 1); + bit_range b7 (7, 1); + bit_range b1_to_6 (1, 6); + bit_range b0_to_7 (0, 8); + bit_range b3_to_5 (3, 3); + bit_range b6_to_7 (6, 2); + + /* self-intersection is true. */ + ASSERT_TRUE (b0.intersects_p (b0)); + ASSERT_TRUE (b7.intersects_p (b7)); + ASSERT_TRUE (b1_to_6.intersects_p (b1_to_6)); + ASSERT_TRUE (b0_to_7.intersects_p (b0_to_7)); + + ASSERT_FALSE (b0.intersects_p (b1)); + ASSERT_FALSE (b1.intersects_p (b0)); + ASSERT_FALSE (b0.intersects_p (b7)); + ASSERT_FALSE (b7.intersects_p (b0)); + + ASSERT_TRUE (b0_to_7.intersects_p (b0)); + ASSERT_TRUE (b0_to_7.intersects_p (b7)); + ASSERT_TRUE (b0.intersects_p (b0_to_7)); + ASSERT_TRUE (b7.intersects_p (b0_to_7)); + + ASSERT_FALSE (b0.intersects_p (b1_to_6)); + ASSERT_FALSE (b1_to_6.intersects_p (b0)); + ASSERT_TRUE (b1.intersects_p (b1_to_6)); + ASSERT_TRUE (b1_to_6.intersects_p (b1)); + ASSERT_TRUE (b1_to_6.intersects_p (b6)); + ASSERT_FALSE (b1_to_6.intersects_p (b7)); + + ASSERT_TRUE (b1_to_6.intersects_p (b0_to_7)); + ASSERT_TRUE (b0_to_7.intersects_p (b1_to_6)); + + ASSERT_FALSE (b3_to_5.intersects_p (b6_to_7)); + ASSERT_FALSE (b6_to_7.intersects_p (b3_to_5)); +} + +/* Implementation detail of ASSERT_BIT_RANGE_FROM_MASK_EQ. */ + +static void +assert_bit_range_from_mask_eq (const location &loc, + unsigned HOST_WIDE_INT mask, + const bit_range &expected) +{ + bit_range actual (0, 0); + bool ok = bit_range::from_mask (mask, &actual); + ASSERT_TRUE_AT (loc, ok); + ASSERT_EQ_AT (loc, actual, expected); +} + +/* Assert that bit_range::from_mask (MASK) returns true, and writes + out EXPECTED_BIT_RANGE. */ + +#define ASSERT_BIT_RANGE_FROM_MASK_EQ(MASK, EXPECTED_BIT_RANGE) \ + SELFTEST_BEGIN_STMT \ + assert_bit_range_from_mask_eq (SELFTEST_LOCATION, MASK, \ + EXPECTED_BIT_RANGE); \ + SELFTEST_END_STMT + +/* Implementation detail of ASSERT_NO_BIT_RANGE_FROM_MASK. */ + +static void +assert_no_bit_range_from_mask_eq (const location &loc, + unsigned HOST_WIDE_INT mask) +{ + bit_range actual (0, 0); + bool ok = bit_range::from_mask (mask, &actual); + ASSERT_FALSE_AT (loc, ok); +} + +/* Assert that bit_range::from_mask (MASK) returns false. */ + +#define ASSERT_NO_BIT_RANGE_FROM_MASK(MASK) \ + SELFTEST_BEGIN_STMT \ + assert_no_bit_range_from_mask_eq (SELFTEST_LOCATION, MASK); \ + SELFTEST_END_STMT + +/* Verify that bit_range::from_mask works as expected. */ + +static void +test_bit_range_from_mask () +{ + /* Should fail on zero. */ + ASSERT_NO_BIT_RANGE_FROM_MASK (0); + + /* Verify 1-bit masks. */ + ASSERT_BIT_RANGE_FROM_MASK_EQ (1, bit_range (0, 1)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (2, bit_range (1, 1)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (4, bit_range (2, 1)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (8, bit_range (3, 1)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (16, bit_range (4, 1)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (32, bit_range (5, 1)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (64, bit_range (6, 1)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (128, bit_range (7, 1)); + + /* Verify N-bit masks starting at bit 0. */ + ASSERT_BIT_RANGE_FROM_MASK_EQ (3, bit_range (0, 2)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (7, bit_range (0, 3)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (15, bit_range (0, 4)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (31, bit_range (0, 5)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (63, bit_range (0, 6)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (127, bit_range (0, 7)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (255, bit_range (0, 8)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (0xffff, bit_range (0, 16)); + + /* Various other tests. */ + ASSERT_BIT_RANGE_FROM_MASK_EQ (0x30, bit_range (4, 2)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (0x700, bit_range (8, 3)); + ASSERT_BIT_RANGE_FROM_MASK_EQ (0x600, bit_range (9, 2)); + + /* Multiple ranges of set bits should fail. */ + ASSERT_NO_BIT_RANGE_FROM_MASK (0x101); + ASSERT_NO_BIT_RANGE_FROM_MASK (0xf0f0f0f0); +} + /* Implementation detail of ASSERT_OVERLAP. */ static void @@ -2530,6 +2730,8 @@ test_binding_key_overlap () void analyzer_store_cc_tests () { + test_bit_range_intersects_p (); + test_bit_range_from_mask (); test_binding_key_overlap (); } diff --git a/gcc/analyzer/store.h b/gcc/analyzer/store.h index d68513c..7bd2824 100644 --- a/gcc/analyzer/store.h +++ b/gcc/analyzer/store.h @@ -267,6 +267,50 @@ private: enum binding_kind m_kind; }; +struct bit_range +{ + bit_range (bit_offset_t start_bit_offset, bit_size_t size_in_bits) + : m_start_bit_offset (start_bit_offset), + m_size_in_bits (size_in_bits) + {} + + void dump_to_pp (pretty_printer *pp) const; + + bit_offset_t get_start_bit_offset () const + { + return m_start_bit_offset; + } + bit_offset_t get_next_bit_offset () const + { + return m_start_bit_offset + m_size_in_bits; + } + + bool contains_p (bit_offset_t offset) const + { + return (offset >= get_start_bit_offset () + && offset < get_next_bit_offset ()); + } + + bool operator== (const bit_range &other) const + { + return (m_start_bit_offset == other.m_start_bit_offset + && m_size_in_bits == other.m_size_in_bits); + } + + bool intersects_p (const bit_range &other) const + { + return (get_start_bit_offset () < other.get_next_bit_offset () + && other.get_start_bit_offset () < get_next_bit_offset ()); + } + + static int cmp (const bit_range &br1, const bit_range &br2); + + static bool from_mask (unsigned HOST_WIDE_INT mask, bit_range *out); + + bit_offset_t m_start_bit_offset; + bit_size_t m_size_in_bits; +}; + /* Concrete subclass of binding_key, for describing a concrete range of bits within the binding_map (e.g. "bits 8-15"). */ @@ -279,24 +323,22 @@ public: concrete_binding (bit_offset_t start_bit_offset, bit_size_t size_in_bits, enum binding_kind kind) : binding_key (kind), - m_start_bit_offset (start_bit_offset), - m_size_in_bits (size_in_bits) + m_bit_range (start_bit_offset, size_in_bits) {} bool concrete_p () const FINAL OVERRIDE { return true; } hashval_t hash () const { inchash::hash hstate; - hstate.add_wide_int (m_start_bit_offset); - hstate.add_wide_int (m_size_in_bits); + hstate.add_wide_int (m_bit_range.m_start_bit_offset); + hstate.add_wide_int (m_bit_range.m_size_in_bits); return hstate.end () ^ binding_key::impl_hash (); } bool operator== (const concrete_binding &other) const { if (!binding_key::impl_eq (other)) return false; - return (m_start_bit_offset == other.m_start_bit_offset - && m_size_in_bits == other.m_size_in_bits); + return m_bit_range == other.m_bit_range; } void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE; @@ -304,12 +346,20 @@ public: const concrete_binding *dyn_cast_concrete_binding () const FINAL OVERRIDE { return this; } - bit_offset_t get_start_bit_offset () const { return m_start_bit_offset; } - bit_size_t get_size_in_bits () const { return m_size_in_bits; } + const bit_range &get_bit_range () const { return m_bit_range; } + + bit_offset_t get_start_bit_offset () const + { + return m_bit_range.m_start_bit_offset; + } + bit_size_t get_size_in_bits () const + { + return m_bit_range.m_size_in_bits; + } /* Return the next bit offset after the end of this binding. */ bit_offset_t get_next_bit_offset () const { - return m_start_bit_offset + m_size_in_bits; + return m_bit_range.get_next_bit_offset (); } bool overlaps_p (const concrete_binding &other) const; @@ -317,8 +367,7 @@ public: static int cmp_ptr_ptr (const void *, const void *); private: - bit_offset_t m_start_bit_offset; - bit_size_t m_size_in_bits; + bit_range m_bit_range; }; } // namespace ana @@ -700,6 +749,14 @@ public: get_concrete_binding (bit_offset_t start_bit_offset, bit_offset_t size_in_bits, enum binding_kind kind); + const concrete_binding * + get_concrete_binding (const bit_range &bits, + enum binding_kind kind) + { + return get_concrete_binding (bits.get_start_bit_offset (), + bits.m_size_in_bits, + kind); + } const symbolic_binding * get_symbolic_binding (const region *region, enum binding_kind kind); diff --git a/gcc/analyzer/svalue.h b/gcc/analyzer/svalue.h index 7fe0ba3..d9e34aa 100644 --- a/gcc/analyzer/svalue.h +++ b/gcc/analyzer/svalue.h @@ -1073,8 +1073,6 @@ namespace ana { class conjured_svalue : public svalue { public: - typedef binding_map::iterator_t iterator_t; - /* A support class for uniquifying instances of conjured_svalue. */ struct key_t { diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index a587b99..cd3c99e 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -2240,18 +2240,6 @@ warn_for_sign_compare (location_t location, int op1_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op1)); int unsignedp0, unsignedp1; - /* In C++, check for comparison of different enum types. */ - if (c_dialect_cxx() - && TREE_CODE (TREE_TYPE (orig_op0)) == ENUMERAL_TYPE - && TREE_CODE (TREE_TYPE (orig_op1)) == ENUMERAL_TYPE - && TYPE_MAIN_VARIANT (TREE_TYPE (orig_op0)) - != TYPE_MAIN_VARIANT (TREE_TYPE (orig_op1))) - { - warning_at (location, - OPT_Wsign_compare, "comparison between types %qT and %qT", - TREE_TYPE (orig_op0), TREE_TYPE (orig_op1)); - } - /* Do not warn if the comparison is being done in a signed type, since the signed type will only be chosen if it can represent all the values of the unsigned type. */ diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h index 1f56a0d..62d7e45 100644 --- a/gcc/config/arc/arc-protos.h +++ b/gcc/config/arc/arc-protos.h @@ -50,6 +50,7 @@ extern void arc_split_ior (rtx *); extern bool arc_check_mov_const (HOST_WIDE_INT ); extern bool arc_split_mov_const (rtx *); extern bool arc_can_use_return_insn (void); +extern bool arc_split_move_p (rtx *); #endif /* RTX_CODE */ extern bool arc_ccfsm_branch_deleted_p (void); diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 0d34c96..69f6ae4 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -10108,6 +10108,31 @@ arc_process_double_reg_moves (rtx *operands) return true; } + +/* Check if we need to split a 64bit move. We do not need to split it if we can + use vadd2 or ldd/std instructions. */ + +bool +arc_split_move_p (rtx *operands) +{ + machine_mode mode = GET_MODE (operands[0]); + + if (TARGET_LL64 + && ((memory_operand (operands[0], mode) + && (even_register_operand (operands[1], mode) + || satisfies_constraint_Cm3 (operands[1]))) + || (memory_operand (operands[1], mode) + && even_register_operand (operands[0], mode)))) + return false; + + if (TARGET_PLUS_QMACW + && even_register_operand (operands[0], mode) + && even_register_operand (operands[1], mode)) + return false; + + return true; +} + /* operands 0..1 are the operands of a 64 bit move instruction. split it into two moves with operands 2/3 and 4/5. */ @@ -10125,25 +10150,6 @@ arc_split_move (rtx *operands) return; } - if (TARGET_LL64 - && ((memory_operand (operands[0], mode) - && (even_register_operand (operands[1], mode) - || satisfies_constraint_Cm3 (operands[1]))) - || (memory_operand (operands[1], mode) - && even_register_operand (operands[0], mode)))) - { - emit_move_insn (operands[0], operands[1]); - return; - } - - if (TARGET_PLUS_QMACW - && even_register_operand (operands[0], mode) - && even_register_operand (operands[1], mode)) - { - emit_move_insn (operands[0], operands[1]); - return; - } - if (TARGET_PLUS_QMACW && GET_CODE (operands[1]) == CONST_VECTOR) { diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index de61b2b..90ba85e 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -1330,47 +1330,20 @@ core_3, archs4x, archs4xd, archs4xd_slow" "register_operand (operands[0], DImode) || register_operand (operands[1], DImode) || (satisfies_constraint_Cm3 (operands[1]) - && memory_operand (operands[0], DImode))" - "* -{ - switch (which_alternative) - { - default: - return \"#\"; - - case 0: - if (TARGET_PLUS_QMACW - && even_register_operand (operands[0], DImode) - && even_register_operand (operands[1], DImode)) - return \"vadd2%?\\t%0,%1,0\"; - return \"#\"; - - case 2: - if (TARGET_LL64 - && memory_operand (operands[1], DImode) - && even_register_operand (operands[0], DImode)) - return \"ldd%U1%V1 %0,%1%&\"; - return \"#\"; - - case 3: - if (TARGET_LL64 - && memory_operand (operands[0], DImode) - && (even_register_operand (operands[1], DImode) - || satisfies_constraint_Cm3 (operands[1]))) - return \"std%U0%V0 %1,%0\"; - return \"#\"; - } -}" - "&& reload_completed" + && memory_operand (operands[0], DImode))" + "@ + vadd2\\t%0,%1,0 + # + ldd%U1%V1\\t%0,%1 + std%U0%V0\\t%1,%0" + "&& reload_completed && arc_split_move_p (operands)" [(const_int 0)] { arc_split_move (operands); DONE; } [(set_attr "type" "move,move,load,store") - ;; ??? The ld/st values could be 4 if it's [reg,bignum]. - (set_attr "length" "8,16,*,*")]) - + (set_attr "length" "8,16,16,16")]) ;; Floating point move insns. @@ -1409,50 +1382,22 @@ core_3, archs4x, archs4xd, archs4xd_slow" (define_insn_and_split "*movdf_insn" [(set (match_operand:DF 0 "move_dest_operand" "=D,r,r,r,r,m") (match_operand:DF 1 "move_double_src_operand" "r,D,r,E,m,r"))] - "register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode)" - "* -{ - switch (which_alternative) - { - default: - return \"#\"; - - case 2: - if (TARGET_PLUS_QMACW - && even_register_operand (operands[0], DFmode) - && even_register_operand (operands[1], DFmode)) - return \"vadd2%?\\t%0,%1,0\"; - return \"#\"; - - case 4: - if (TARGET_LL64 - && ((even_register_operand (operands[0], DFmode) - && memory_operand (operands[1], DFmode)) - || (memory_operand (operands[0], DFmode) - && even_register_operand (operands[1], DFmode)))) - return \"ldd%U1%V1 %0,%1%&\"; - return \"#\"; - - case 5: - if (TARGET_LL64 - && ((even_register_operand (operands[0], DFmode) - && memory_operand (operands[1], DFmode)) - || (memory_operand (operands[0], DFmode) - && even_register_operand (operands[1], DFmode)))) - return \"std%U0%V0 %1,%0\"; - return \"#\"; - } -}" - "reload_completed" + "(register_operand (operands[0], DFmode) + || register_operand (operands[1], DFmode))" + "@ + # + # + vadd2\\t%0,%1,0 + # + ldd%U1%V1\\t%0,%1 + std%U0%V0\\t%1,%0" + "&& reload_completed && arc_split_move_p (operands)" [(const_int 0)] { arc_split_move (operands); DONE; } [(set_attr "type" "move,move,move,move,load,store") - (set_attr "predicable" "no,no,no,yes,no,no") - ;; ??? The ld/st values could be 16 if it's [reg,bignum]. (set_attr "length" "4,16,8,16,16,16")]) (define_insn_and_split "*movdf_insn_nolrsr" @@ -5017,7 +4962,7 @@ core_3, archs4x, archs4xd, archs4xd_slow" (define_expand "doloop_end" [(parallel [(set (pc) (if_then_else - (ne (match_operand 0 "" "") + (ne (match_operand 0 "nonimmediate_operand") (const_int 1)) (label_ref (match_operand 1 "" "")) (pc))) @@ -5043,44 +4988,38 @@ core_3, archs4x, archs4xd, archs4xd_slow" ;; if by any chance the lp_count is not used, then use an 'r' ;; register, instead of going to memory. -(define_insn "loop_end" - [(set (pc) - (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,m") - (const_int 1)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_operand:SI 0 "nonimmediate_operand" "=r,m") - (plus (match_dup 2) (const_int -1))) - (unspec [(const_int 0)] UNSPEC_ARC_LP) - (clobber (match_scratch:SI 3 "=X,&r"))] - "" - "; ZOL_END, begins @%l1" - [(set_attr "length" "0") - (set_attr "predicable" "no") - (set_attr "type" "loop_end")]) - ;; split pattern for the very slim chance when the loop register is ;; memory. -(define_split +(define_insn_and_split "loop_end" [(set (pc) - (if_then_else (ne (match_operand:SI 0 "memory_operand") + (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+r,!m") (const_int 1)) - (label_ref (match_operand 1 "")) + (label_ref (match_operand 1 "" "")) (pc))) (set (match_dup 0) (plus (match_dup 0) (const_int -1))) (unspec [(const_int 0)] UNSPEC_ARC_LP) - (clobber (match_scratch:SI 2))] - "memory_operand (operands[0], SImode)" + (clobber (match_scratch:SI 2 "=X,&r"))] + "" + "@ + ; ZOL_END, begins @%l1 + #" + "reload_completed && memory_operand (operands[0], Pmode)" [(set (match_dup 2) (match_dup 0)) - (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1))) + (parallel + [(set (reg:CC_ZN CC_REG) + (compare:CC_ZN (plus:SI (match_dup 2) (const_int -1)) + (const_int 0))) + (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))]) (set (match_dup 0) (match_dup 2)) - (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0))) (set (pc) - (if_then_else (ne (reg:CC CC_REG) + (if_then_else (ne (reg:CC_ZN CC_REG) (const_int 0)) (label_ref (match_dup 1)) (pc)))] - "") + "" + [(set_attr "length" "0,24") + (set_attr "predicable" "no") + (set_attr "type" "loop_end")]) (define_insn "loop_fail" [(set (reg:SI LP_COUNT) @@ -6080,48 +6019,64 @@ core_3, archs4x, archs4xd, archs4xd_slow" ;; MAC and DMPY instructions -; Use MAC instruction to emulate 16bit mac. +; Use VMAC2H(U) instruction to emulate scalar 16bit mac. (define_expand "maddhisi4" [(match_operand:SI 0 "register_operand" "") (match_operand:HI 1 "register_operand" "") (match_operand:HI 2 "extend_operand" "") (match_operand:SI 3 "register_operand" "")] - "TARGET_PLUS_DMPY" + "TARGET_PLUS_MACD" "{ - rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST); - rtx tmp1 = gen_reg_rtx (SImode); - rtx tmp2 = gen_reg_rtx (SImode); - rtx accl = gen_lowpart (SImode, acc_reg); - - emit_move_insn (accl, operands[3]); - emit_insn (gen_rtx_SET (tmp1, gen_rtx_SIGN_EXTEND (SImode, operands[1]))); - emit_insn (gen_rtx_SET (tmp2, gen_rtx_SIGN_EXTEND (SImode, operands[2]))); - emit_insn (gen_mac (tmp1, tmp2)); - emit_move_insn (operands[0], accl); + rtx acc_reg = gen_rtx_REG (SImode, ACC_REG_FIRST); + + emit_move_insn (acc_reg, operands[3]); + emit_insn (gen_machi (operands[1], operands[2])); + emit_move_insn (operands[0], acc_reg); DONE; }") -; The same for the unsigned variant, but using MACU instruction. +(define_insn "machi" + [(set (reg:SI ARCV2_ACC) + (plus:SI + (mult:SI (sign_extend:SI (match_operand:HI 0 "register_operand" "%r")) + (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))) + (reg:SI ARCV2_ACC)))] + "TARGET_PLUS_MACD" + "vmac2h\\t0,%0,%1" + [(set_attr "length" "4") + (set_attr "type" "multi") + (set_attr "predicable" "no") + (set_attr "cond" "nocond")]) + +; The same for the unsigned variant, but using VMAC2HU instruction. (define_expand "umaddhisi4" [(match_operand:SI 0 "register_operand" "") (match_operand:HI 1 "register_operand" "") - (match_operand:HI 2 "extend_operand" "") + (match_operand:HI 2 "register_operand" "") (match_operand:SI 3 "register_operand" "")] - "TARGET_PLUS_DMPY" + "TARGET_PLUS_MACD" "{ - rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST); - rtx tmp1 = gen_reg_rtx (SImode); - rtx tmp2 = gen_reg_rtx (SImode); - rtx accl = gen_lowpart (SImode, acc_reg); - - emit_move_insn (accl, operands[3]); - emit_insn (gen_rtx_SET (tmp1, gen_rtx_ZERO_EXTEND (SImode, operands[1]))); - emit_insn (gen_rtx_SET (tmp2, gen_rtx_ZERO_EXTEND (SImode, operands[2]))); - emit_insn (gen_macu (tmp1, tmp2)); - emit_move_insn (operands[0], accl); + rtx acc_reg = gen_rtx_REG (SImode, ACC_REG_FIRST); + + emit_move_insn (acc_reg, operands[3]); + emit_insn (gen_umachi (operands[1], operands[2])); + emit_move_insn (operands[0], acc_reg); DONE; }") +(define_insn "umachi" + [(set (reg:SI ARCV2_ACC) + (plus:SI + (mult:SI (zero_extend:SI (match_operand:HI 0 "register_operand" "%r")) + (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))) + (reg:SI ARCV2_ACC)))] + "TARGET_PLUS_MACD" + "vmac2hu\\t0,%0,%1" + [(set_attr "length" "4") + (set_attr "type" "multi") + (set_attr "predicable" "no") + (set_attr "cond" "nocond")]) + (define_expand "maddsidi4" [(match_operand:DI 0 "register_operand" "") (match_operand:SI 1 "register_operand" "") diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md index dd63f93..303f52c 100644 --- a/gcc/config/arc/simdext.md +++ b/gcc/config/arc/simdext.md @@ -1472,41 +1472,19 @@ (match_operand:VWH 1 "general_operand" "i,r,m,r"))] "(register_operand (operands[0], <MODE>mode) || register_operand (operands[1], <MODE>mode))" - "* -{ - switch (which_alternative) - { - default: - return \"#\"; - - case 1: - if (TARGET_PLUS_QMACW - && even_register_operand (operands[0], <MODE>mode) - && even_register_operand (operands[1], <MODE>mode)) - return \"vadd2%?\\t%0,%1,0\"; - return \"#\"; - - case 2: - if (TARGET_LL64) - return \"ldd%U1%V1\\t%0,%1\"; - return \"#\"; - - case 3: - if (TARGET_LL64) - return \"std%U0%V0\\t%1,%0\"; - return \"#\"; - } -}" - "reload_completed" + "@ + # + vadd2\\t%0,%1,0 + ldd%U1%V1\\t%0,%1 + std%U0%V0\\t%1,%0" + "&& reload_completed && arc_split_move_p (operands)" [(const_int 0)] { arc_split_move (operands); DONE; } - [(set_attr "type" "move,multi,load,store") - (set_attr "predicable" "no,no,no,no") - (set_attr "iscompact" "false,false,false,false") - ]) + [(set_attr "type" "move,move,load,store") + (set_attr "length" "16,8,16,16")]) (define_expand "movmisalign<mode>" [(set (match_operand:VWH 0 "general_operand" "") diff --git a/gcc/config/h8300/logical.md b/gcc/config/h8300/logical.md index 34cf74e..fae3c7c 100644 --- a/gcc/config/h8300/logical.md +++ b/gcc/config/h8300/logical.md @@ -62,22 +62,21 @@ (match_operand:QI 2 "h8300_src_operand" "Y0,rn")))] "register_operand (operands[0], QImode) || single_zero_operand (operands[2], QImode)" - "#" - "&& reload_completed" + "bclr %W2,%R0" + "&& reload_completed && !single_zero_operand (operands[2], QImode)" [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2))) - (clobber (reg:CC CC_REG))])]) + (clobber (reg:CC CC_REG))])] + "" + [(set_attr "length" "8,2")]) -(define_insn "andqi3_1_clobber_flags" - [(set (match_operand:QI 0 "bit_operand" "=U,r") - (and:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "h8300_src_operand" "Y0,rn"))) +(define_insn "*andqi3_1<cczn>" + [(set (match_operand:QI 0 "register_operand" "=r") + (and:QI (match_operand:QI 1 "register_operand" "%0") + (match_operand:QI 2 "h8300_src_operand" "rn"))) (clobber (reg:CC CC_REG))] - "register_operand (operands[0], QImode) - || single_zero_operand (operands[2], QImode)" - "@ - bclr %W2,%R0 - and %X2,%X0" - [(set_attr "length" "2,8")]) + "" + "and %X2,%X0" + [(set_attr "length" "2")]) (define_insn_and_split "*andor<mode>3" [(set (match_operand:QHSI 0 "register_operand" "=r") @@ -166,22 +165,14 @@ ;; OR/XOR INSTRUCTIONS ;; ---------------------------------------------------------------------- -(define_insn "b<code>qi_msx" - [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU") - (ors:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0") - (match_operand:QI 2 "single_one_operand" "Y2")))] +(define_insn "b<code><mode>_msx" + [(set (match_operand:QHI 0 "bit_register_indirect_operand" "=WU") + (ors:QHI (match_operand:QHI 1 "bit_register_indirect_operand" "%0") + (match_operand:QHI 2 "single_one_operand" "Y2")))] "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])" { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; } [(set_attr "length" "8")]) -(define_insn "b<code>hi_msx" - [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m") - (ors:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0") - (match_operand:HI 2 "single_one_operand" "Y2")))] - "TARGET_H8300SX" - { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; } - [(set_attr "length" "8")]) - (define_insn_and_split "<code>qi3_1" [(set (match_operand:QI 0 "bit_operand" "=U,rQ") (ors:QI (match_operand:QI 1 "bit_operand" "%0,0") diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b0d19a6..05b8dc8 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13531,7 +13531,7 @@ ix86_print_operand_punct_valid_p (unsigned char code) static void ix86_print_operand_address_as (FILE *file, rtx addr, - addr_space_t as, bool no_rip) + addr_space_t as, bool raw) { struct ix86_address parts; rtx base, index, disp; @@ -13570,7 +13570,7 @@ ix86_print_operand_address_as (FILE *file, rtx addr, else gcc_assert (ADDR_SPACE_GENERIC_P (parts.seg)); - if (!ADDR_SPACE_GENERIC_P (as)) + if (!ADDR_SPACE_GENERIC_P (as) && !raw) { if (ASSEMBLER_DIALECT == ASM_ATT) putc ('%', file); @@ -13589,7 +13589,7 @@ ix86_print_operand_address_as (FILE *file, rtx addr, } /* Use one byte shorter RIP relative addressing for 64bit mode. */ - if (TARGET_64BIT && !base && !index && !no_rip) + if (TARGET_64BIT && !base && !index && !raw) { rtx symbol = disp; diff --git a/gcc/config/rs6000/power10.md b/gcc/config/rs6000/power10.md index 665f0f2..0186ae9 100644 --- a/gcc/config/rs6000/power10.md +++ b/gcc/config/rs6000/power10.md @@ -100,6 +100,11 @@ (eq_attr "cpu" "power10")) "DU_any_power10,LU_power10") +(define_insn_reservation "power10-fused-load" 4 + (and (eq_attr "type" "fused_load_cmpi,fused_addis_load,fused_load_load") + (eq_attr "cpu" "power10")) + "DU_even_power10,LU_power10") + (define_insn_reservation "power10-prefixed-load" 4 (and (eq_attr "type" "load") (eq_attr "update" "no") @@ -176,6 +181,11 @@ (eq_attr "cpu" "power10")) "DU_any_power10,STU_power10") +(define_insn_reservation "power10-fused-store" 0 + (and (eq_attr "type" "fused_store_store") + (eq_attr "cpu" "power10")) + "DU_even_power10,STU_power10") + (define_insn_reservation "power10-prefixed-store" 0 (and (eq_attr "type" "store,fpstore,vecstore") (eq_attr "prefixed" "yes") @@ -244,6 +254,11 @@ (define_bypass 4 "power10-alu" "power10-crlogical,power10-mfcr,power10-mfcrf") +(define_insn_reservation "power10-fused_alu" 2 + (and (eq_attr "type" "fused_arith_logical,fused_cmp_isel,fused_carry") + (eq_attr "cpu" "power10")) + "DU_even_power10,EXU_power10") + ; paddi (define_insn_reservation "power10-paddi" 2 (and (eq_attr "type" "add") @@ -403,6 +418,11 @@ (eq_attr "cpu" "power10")) "DU_any_power10,EXU_power10") +(define_insn_reservation "power10-fused-vec" 2 + (and (eq_attr "type" "fused_vector") + (eq_attr "cpu" "power10")) + "DU_even_power10,EXU_power10") + (define_insn_reservation "power10-veccmp" 3 (and (eq_attr "type" "veccmp") (eq_attr "cpu" "power10")) @@ -490,6 +510,11 @@ (eq_attr "cpu" "power10")) "DU_any_power10,STU_power10") +(define_insn_reservation "power10-fused-branch" 3 + (and (eq_attr "type" "fused_mtbc") + (eq_attr "cpu" "power10")) + "DU_even_power10,STU_power10") + ; Crypto (define_insn_reservation "power10-crypto" 4 diff --git a/gcc/config/rs6000/rs6000-p8swap.c b/gcc/config/rs6000/rs6000-p8swap.c index ad2b302..21cbcb2 100644 --- a/gcc/config/rs6000/rs6000-p8swap.c +++ b/gcc/config/rs6000/rs6000-p8swap.c @@ -250,6 +250,21 @@ union_uses (swap_web_entry *insn_entry, rtx insn, df_ref def) } } +/* Return 1 iff PAT (a SINGLE_SET) is a rotate 64 bit expression; else return + 0. */ + +static bool +pattern_is_rotate64 (rtx pat) +{ + rtx rot = SET_SRC (pat); + + if (GET_CODE (rot) == ROTATE && CONST_INT_P (XEXP (rot, 1)) + && INTVAL (XEXP (rot, 1)) == 64) + return true; + + return false; +} + /* Return 1 iff INSN is a load insn, including permuting loads that represent an lvxd2x instruction; else return 0. */ static unsigned int @@ -266,6 +281,9 @@ insn_is_load_p (rtx insn) && MEM_P (XEXP (SET_SRC (body), 0))) return 1; + if (pattern_is_rotate64 (body) && MEM_P (XEXP (SET_SRC (body), 0))) + return 1; + return 0; } @@ -305,6 +323,8 @@ insn_is_swap_p (rtx insn) if (GET_CODE (body) != SET) return 0; rtx rhs = SET_SRC (body); + if (pattern_is_rotate64 (body)) + return 1; if (GET_CODE (rhs) != VEC_SELECT) return 0; rtx parallel = XEXP (rhs, 1); @@ -392,7 +412,8 @@ quad_aligned_load_p (swap_web_entry *insn_entry, rtx_insn *insn) false. */ rtx body = PATTERN (def_insn); if (GET_CODE (body) != SET - || GET_CODE (SET_SRC (body)) != VEC_SELECT + || !(GET_CODE (SET_SRC (body)) == VEC_SELECT + || pattern_is_rotate64 (body)) || !MEM_P (XEXP (SET_SRC (body), 0))) return false; @@ -531,7 +552,8 @@ const_load_sequence_p (swap_web_entry *insn_entry, rtx insn) false. */ rtx body = PATTERN (def_insn); if (GET_CODE (body) != SET - || GET_CODE (SET_SRC (body)) != VEC_SELECT + || !(GET_CODE (SET_SRC (body)) == VEC_SELECT + || pattern_is_rotate64 (body)) || !MEM_P (XEXP (SET_SRC (body), 0))) return false; @@ -1732,7 +1754,8 @@ replace_swapped_aligned_load (swap_web_entry *insn_entry, rtx swap_insn) swap (indicated by code VEC_SELECT). */ rtx body = PATTERN (def_insn); gcc_assert ((GET_CODE (body) == SET) - && (GET_CODE (SET_SRC (body)) == VEC_SELECT) + && (GET_CODE (SET_SRC (body)) == VEC_SELECT + || pattern_is_rotate64 (body)) && MEM_P (XEXP (SET_SRC (body), 0))); rtx src_exp = XEXP (SET_SRC (body), 0); @@ -2150,7 +2173,8 @@ recombine_lvx_pattern (rtx_insn *insn, del_info *to_delete) { rtx body = PATTERN (insn); gcc_assert (GET_CODE (body) == SET - && GET_CODE (SET_SRC (body)) == VEC_SELECT + && (GET_CODE (SET_SRC (body)) == VEC_SELECT + || pattern_is_rotate64 (body)) && MEM_P (XEXP (SET_SRC (body), 0))); rtx mem = XEXP (SET_SRC (body), 0); @@ -2227,7 +2251,8 @@ recombine_stvx_pattern (rtx_insn *insn, del_info *to_delete) rtx body = PATTERN (insn); gcc_assert (GET_CODE (body) == SET && MEM_P (SET_DEST (body)) - && GET_CODE (SET_SRC (body)) == VEC_SELECT); + && (GET_CODE (SET_SRC (body)) == VEC_SELECT + || pattern_is_rotate64 (body))); rtx mem = SET_DEST (body); rtx base_reg = XEXP (mem, 0); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 225b8917..5a97fc8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,43 @@ +2021-06-08 Marek Polacek <polacek@redhat.com> + + PR c++/100065 + * decl.c (grokdeclarator): Store a value-dependent + explicit-specifier even for deduction guides. + +2021-06-08 Jason Merrill <jason@redhat.com> + + * parser.c (cp_parser_string_literal): Adjust diagnostic. + +2021-06-08 Jason Merrill <jason@redhat.com> + + PR c++/100963 + * call.c (perfect_conversion_p): Check check_narrowing. + +2021-06-08 Jason Merrill <jason@redhat.com> + + PR c++/91706 + * name-lookup.c (get_class_binding): Keep a BASELINK. + (set_inherited_value_binding_p): Adjust. + * lambda.c (is_lambda_ignored_entity): Adjust. + * pt.c (lookup_template_function): Copy a BASELINK before + modifying it. + +2021-06-08 Jason Merrill <jason@redhat.com> + + PR c++/91706 + * semantics.c (baselink_for_fns): Fix BASELINK_BINFO. + +2021-06-08 Jason Merrill <jason@redhat.com> + + * module.cc (duplicate_hash::hash): Comment out. + (trees_in::tree_value): Adjust loop counter. + +2021-06-08 Jason Merrill <jason@redhat.com> + + PR c++/100102 + * init.c (build_offset_ref): Return the BASELINK for a static + member function. + 2021-06-07 Patrick Palka <ppalka@redhat.com> PR c++/100918 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 17fc60c..d2f6ca8 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5880,6 +5880,9 @@ perfect_conversion_p (conversion *conv) next_conversion (conv)->type)) return false; } + if (conv->check_narrowing) + /* Brace elision is imperfect. */ + return false; return true; } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a3687db..cbf647d 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -14043,6 +14043,8 @@ grokdeclarator (const cp_declarator *declarator, storage_class = sc_none; } } + if (declspecs->explicit_specifier) + store_explicit_specifier (decl, declspecs->explicit_specifier); } else { diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 24f248a..d59a829 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4378,8 +4378,8 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok, rich_location rich_loc (line_table, tok->location); rich_loc.add_range (last_tok_loc); error_at (&rich_loc, - "unsupported non-standard concatenation " - "of string literals"); + "concatenation of string literals with " + "conflicting encoding prefixes"); } } diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 12b932f..554afaa 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,19 @@ +2021-06-08 Tobias Burnus <tobias@codesourcery.com> + + PR middle-end/99928 + * trans-openmp.c (gfc_add_clause_implicitly): New. + (gfc_split_omp_clauses): Use it. + (gfc_free_split_omp_clauses): New. + (gfc_trans_omp_do_simd, gfc_trans_omp_parallel_do, + gfc_trans_omp_parallel_do_simd, gfc_trans_omp_distribute, + gfc_trans_omp_teams, gfc_trans_omp_target, gfc_trans_omp_taskloop, + gfc_trans_omp_master_taskloop, gfc_trans_omp_parallel_master): Use it. + +2021-06-08 Martin Liska <mliska@suse.cz> + + * intrinsic.texi: Fix typo. + * trans-expr.c (gfc_trans_pointer_assignment): Likewise. + 2021-06-05 José Rui Faustino de Sousa <jrfsousa@gmail.com> PR fortran/100120 diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 0a52b49..e56c40a 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -446,7 +446,7 @@ end program test_abs @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ABS(A)} @tab @code{REAL(4) A} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{CABS(A)} @tab @code{COMPLEX(4) A} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DABS(A)} @tab @code{REAL(8) A} @tab @code{REAL(8)} @tab Fortran 77 and later @@ -611,7 +611,7 @@ end program test_acos @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ACOS(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DACOS(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -670,7 +670,7 @@ end program test_acosd @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ACOSD(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension @item @code{DACOSD(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @@ -726,7 +726,7 @@ END PROGRAM @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DACOSH(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @@ -875,7 +875,7 @@ end program test_aimag @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{AIMAG(Z)} @tab @code{COMPLEX Z} @tab @code{REAL} @tab Fortran 77 and later @item @code{DIMAG(Z)} @tab @code{COMPLEX(8) Z} @tab @code{REAL(8)} @tab GNU extension @item @code{IMAG(Z)} @tab @code{COMPLEX Z} @tab @code{REAL} @tab GNU extension @@ -935,7 +935,7 @@ end program test_aint @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{AINT(A)} @tab @code{REAL(4) A} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DINT(A)} @tab @code{REAL(8) A} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -1215,7 +1215,7 @@ end program test_anint @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ANINT(A)} @tab @code{REAL(4) A} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DNINT(A)} @tab @code{REAL(8) A} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -1331,7 +1331,7 @@ end program test_asin @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ASIN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DASIN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -1390,7 +1390,7 @@ end program test_asind @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ASIND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension @item @code{DASIND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @@ -1446,7 +1446,7 @@ END PROGRAM @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DASINH(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension. @end multitable @@ -1582,7 +1582,7 @@ end program test_atan @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ATAN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DATAN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -1647,7 +1647,7 @@ end program test_atand @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ATAND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension @item @code{DATAND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @@ -1712,7 +1712,7 @@ end program test_atan2 @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ATAN2(X, Y)} @tab @code{REAL(4) X, Y} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DATAN2(X, Y)} @tab @code{REAL(8) X, Y} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -1780,7 +1780,7 @@ end program test_atan2d @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ATAN2D(X, Y)} @tab @code{REAL(4) X, Y} @tab @code{REAL(4)} @tab GNU extension @item @code{DATAN2D(X, Y)} @tab @code{REAL(8) X, Y} @tab @code{REAL(8)} @tab GNU extension @end multitable @@ -1836,7 +1836,7 @@ END PROGRAM @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DATANH(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @@ -2525,7 +2525,7 @@ end program test_besj0 @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DBESJ0(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @end table @@ -2574,7 +2574,7 @@ end program test_besj1 @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DBESJ1(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @end table @@ -2639,7 +2639,7 @@ end program test_besjn @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DBESJN(N, X)} @tab @code{INTEGER N} @tab @code{REAL(8)} @tab GNU extension @item @tab @code{REAL(8) X} @tab @tab @end multitable @@ -2687,7 +2687,7 @@ end program test_besy0 @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DBESY0(X)}@tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @end table @@ -2734,7 +2734,7 @@ end program test_besy1 @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DBESY1(X)}@tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @end table @@ -2799,7 +2799,7 @@ end program test_besyn @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DBESYN(N,X)} @tab @code{INTEGER N} @tab @code{REAL(8)} @tab GNU extension @item @tab @code{REAL(8) X} @tab @tab @end multitable @@ -3042,7 +3042,7 @@ end program test_btest @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{BTEST(I,POS)} @tab @code{INTEGER I,POS} @tab @code{LOGICAL} @tab Fortran 95 and later @item @code{BBTEST(I,POS)} @tab @code{INTEGER(1) I,POS} @tab @code{LOGICAL(1)} @tab GNU extension @item @code{BITEST(I,POS)} @tab @code{INTEGER(2) I,POS} @tab @code{LOGICAL(2)} @tab GNU extension @@ -3459,7 +3459,7 @@ end program test_char @item @emph{Specific names}: @multitable @columnfractions .18 .18 .24 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{CHAR(I)} @tab @code{INTEGER I} @tab @code{CHARACTER(LEN=1)} @tab Fortran 77 and later @end multitable @@ -4188,7 +4188,7 @@ end program test_conjg @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DCONJG(Z)} @tab @code{COMPLEX(8) Z} @tab @code{COMPLEX(8)} @tab GNU extension @end multitable @end table @@ -4239,7 +4239,7 @@ end program test_cos @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{COS(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DCOS(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @item @code{CCOS(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab Fortran 77 and later @@ -4303,7 +4303,7 @@ end program test_cosd @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{COSD(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension @item @code{DCOSD(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @item @code{CCOSD(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab GNU extension @@ -4362,7 +4362,7 @@ end program test_cosh @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{COSH(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DCOSH(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -4416,7 +4416,7 @@ end program test_cotan @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{COTAN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension @item @code{DCOTAN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @@ -4472,7 +4472,7 @@ end program test_cotand @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{COTAND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension @item @code{DCOTAND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @@ -4987,7 +4987,7 @@ end program test_dim @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DIM(X,Y)} @tab @code{REAL(4) X, Y} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{IDIM(X,Y)} @tab @code{INTEGER(4) X, Y} @tab @code{INTEGER(4)} @tab Fortran 77 and later @item @code{DDIM(X,Y)} @tab @code{REAL(8) X, Y} @tab @code{REAL(8)} @tab Fortran 77 and later @@ -5090,7 +5090,7 @@ end program test_dprod @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DPROD(X,Y)} @tab @code{REAL(4) X, Y} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -5459,7 +5459,7 @@ end program test_erf @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DERF(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @end table @@ -5503,7 +5503,7 @@ end program test_erfc @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DERFC(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @end table @@ -5847,7 +5847,7 @@ end program test_exp @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{EXP(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DEXP(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @item @code{CEXP(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab Fortran 77 and later @@ -6787,7 +6787,7 @@ end program test_gamma @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DGAMMA(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @@ -7676,7 +7676,7 @@ END PROGRAM @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{IAND(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BIAND(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIAND(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @@ -7839,7 +7839,7 @@ The return value is of type @code{INTEGER} and of the same kind as @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{IBCLR(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BBCLR(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIBCLR(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @@ -7898,7 +7898,7 @@ The return value is of type @code{INTEGER} and of the same kind as @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{IBITS(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BBITS(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIBITS(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @@ -7952,7 +7952,7 @@ The return value is of type @code{INTEGER} and of the same kind as @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{IBSET(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BBSET(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIBSET(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @@ -8013,7 +8013,7 @@ end program test_ichar @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ICHAR(C)} @tab @code{CHARACTER C} @tab @code{INTEGER(4)} @tab Fortran 77 and later @end multitable @@ -8140,7 +8140,7 @@ type parameter of the other argument as-if a call to @ref{INT} occurred. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{IEOR(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BIEOR(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIEOR(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @@ -8277,7 +8277,7 @@ The return value is of type @code{INTEGER} and of kind @var{KIND}. If @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{INDEX(STRING, SUBSTRING)} @tab @code{CHARACTER} @tab @code{INTEGER(4)} @tab Fortran 77 and later @end multitable @@ -8344,7 +8344,7 @@ end program @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{INT(A)} @tab @code{REAL(4) A} @tab @code{INTEGER} @tab Fortran 77 and later @item @code{IFIX(A)} @tab @code{REAL(4) A} @tab @code{INTEGER} @tab Fortran 77 and later @item @code{IDINT(A)} @tab @code{REAL(8) A} @tab @code{INTEGER} @tab Fortran 77 and later @@ -8470,7 +8470,7 @@ type parameter of the other argument as-if a call to @ref{INT} occurred. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{IOR(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BIOR(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIOR(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @@ -8824,7 +8824,7 @@ The return value is of type @code{INTEGER} and of the same kind as @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ISHFT(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BSHFT(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IISHFT(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @@ -8882,7 +8882,7 @@ The return value is of type @code{INTEGER} and of the same kind as @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ISHFTC(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BSHFTC(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IISHFTC(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @@ -9243,7 +9243,7 @@ The return value is of type @code{INTEGER} and of kind @var{KIND}. If @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{LEN(STRING)} @tab @code{CHARACTER} @tab @code{INTEGER} @tab Fortran 77 and later @end multitable @@ -9336,7 +9336,7 @@ otherwise, based on the ASCII ordering. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{LGE(STRING_A, STRING_B)} @tab @code{CHARACTER} @tab @code{LOGICAL} @tab Fortran 77 and later @end multitable @@ -9390,7 +9390,7 @@ otherwise, based on the ASCII ordering. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{LGT(STRING_A, STRING_B)} @tab @code{CHARACTER} @tab @code{LOGICAL} @tab Fortran 77 and later @end multitable @@ -9488,7 +9488,7 @@ otherwise, based on the ASCII ordering. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{LLE(STRING_A, STRING_B)} @tab @code{CHARACTER} @tab @code{LOGICAL} @tab Fortran 77 and later @end multitable @@ -9542,7 +9542,7 @@ otherwise, based on the ASCII ordering. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{LLT(STRING_A, STRING_B)} @tab @code{CHARACTER} @tab @code{LOGICAL} @tab Fortran 77 and later @end multitable @@ -9681,7 +9681,7 @@ end program test_log @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ALOG(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 or later @item @code{DLOG(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 or later @item @code{CLOG(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab Fortran 77 or later @@ -9733,7 +9733,7 @@ end program test_log10 @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{ALOG10(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DLOG10(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -9782,7 +9782,7 @@ end program test_log_gamma @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{LGAMMA(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension @item @code{ALGAMA(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension @item @code{DLGAMA(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @@ -10241,7 +10241,7 @@ and has the same type and kind as the first argument. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{MAX0(A1)} @tab @code{INTEGER(4) A1} @tab @code{INTEGER(4)} @tab Fortran 77 and later @item @code{AMAX0(A1)} @tab @code{INTEGER(4) A1} @tab @code{REAL(MAX(X))} @tab Fortran 77 and later @item @code{MAX1(A1)} @tab @code{REAL A1} @tab @code{INT(MAX(X))} @tab Fortran 77 and later @@ -10616,7 +10616,7 @@ and has the same type and kind as the first argument. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{MIN0(A1)} @tab @code{INTEGER(4) A1} @tab @code{INTEGER(4)} @tab Fortran 77 and later @item @code{AMIN0(A1)} @tab @code{INTEGER(4) A1} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{MIN1(A1)} @tab @code{REAL A1} @tab @code{INTEGER(4)} @tab Fortran 77 and later @@ -10849,7 +10849,7 @@ end program test_mod @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Arguments @tab Return type @tab Standard +@headitem Name @tab Arguments @tab Return type @tab Standard @item @code{MOD(A,P)} @tab @code{INTEGER A,P} @tab @code{INTEGER} @tab Fortran 77 and later @item @code{AMOD(A,P)} @tab @code{REAL(4) A,P} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DMOD(A,P)} @tab @code{REAL(8) A,P} @tab @code{REAL(8)} @tab Fortran 77 and later @@ -11014,7 +11014,7 @@ same kind as @var{FROM}. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{MVBITS(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BMVBITS(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IMVBITS(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @@ -11164,7 +11164,7 @@ end program test_nint @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return Type @tab Standard +@headitem Name @tab Argument @tab Return Type @tab Standard @item @code{NINT(A)} @tab @code{REAL(4) A} @tab @code{INTEGER} @tab Fortran 77 and later @item @code{IDNINT(A)} @tab @code{REAL(8) A} @tab @code{INTEGER} @tab Fortran 77 and later @end multitable @@ -11262,7 +11262,7 @@ argument. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{NOT(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 95 and later @item @code{BNOT(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{INOT(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @@ -12278,7 +12278,7 @@ end program test_real @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{FLOAT(A)} @tab @code{INTEGER(4)} @tab @code{REAL(4)} @tab GNU extension @item @code{DFLOAT(A)} @tab @code{INTEGER(4)} @tab @code{REAL(8)} @tab GNU extension @item @code{FLOATI(A)} @tab @code{INTEGER(2)} @tab @code{REAL(4)} @tab GNU extension @@ -13182,7 +13182,7 @@ end program test_sign @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Arguments @tab Return type @tab Standard +@headitem Name @tab Arguments @tab Return type @tab Standard @item @code{SIGN(A,B)} @tab @code{REAL(4) A, B} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{ISIGN(A,B)} @tab @code{INTEGER(4) A, B} @tab @code{INTEGER(4)} @tab Fortran 77 and later @item @code{DSIGN(A,B)} @tab @code{REAL(8) A, B} @tab @code{REAL(8)} @tab Fortran 77 and later @@ -13291,7 +13291,7 @@ end program test_sin @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{SIN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DSIN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @item @code{CSIN(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab Fortran 77 and later @@ -13353,7 +13353,7 @@ end program test_sind @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{SIND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension @item @code{DSIND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @item @code{CSIND(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab GNU extension @@ -13410,7 +13410,7 @@ end program test_sinh @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{DSINH(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 90 and later @end multitable @@ -13695,7 +13695,7 @@ end program test_sqrt @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{SQRT(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DSQRT(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @item @code{CSQRT(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab Fortran 77 and later @@ -14146,7 +14146,7 @@ end program test_tan @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{TAN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DTAN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -14201,7 +14201,7 @@ end program test_tand @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{TAND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension @item @code{DTAND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @@ -14257,7 +14257,7 @@ end program test_tanh @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 -@item Name @tab Argument @tab Return type @tab Standard +@headitem Name @tab Argument @tab Return type @tab Standard @item @code{TANH(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later @item @code{DTANH(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @@ -15181,7 +15181,7 @@ Furthermore, if @code{__float128} is supported in C, the named constants @code{C_FLOAT128, C_FLOAT128_COMPLEX} are defined. @multitable @columnfractions .15 .35 .35 .35 -@item Fortran Type @tab Named constant @tab C type @tab Extension +@headitem Fortran Type @tab Named constant @tab C type @tab Extension @item @code{INTEGER}@tab @code{C_INT} @tab @code{int} @item @code{INTEGER}@tab @code{C_SHORT} @tab @code{short int} @item @code{INTEGER}@tab @code{C_LONG} @tab @code{long int} @@ -15222,7 +15222,7 @@ Additionally, the following parameters of type @code{CHARACTER(KIND=C_CHAR)} are defined. @multitable @columnfractions .20 .45 .15 -@item Name @tab C definition @tab Value +@headitem Name @tab C definition @tab Value @item @code{C_NULL_CHAR} @tab null character @tab @code{'\0'} @item @code{C_ALERT} @tab alert @tab @code{'\a'} @item @code{C_BACKSPACE} @tab backspace @tab @code{'\b'} @@ -15236,7 +15236,7 @@ are defined. Moreover, the following two named constants are defined: @multitable @columnfractions .20 .80 -@item Name @tab Type +@headitem Name @tab Type @item @code{C_NULL_PTR} @tab @code{C_PTR} @item @code{C_NULL_FUNPTR} @tab @code{C_FUNPTR} @end multitable diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 1e22cdb..f466ab6 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -1639,6 +1639,9 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool openacc) OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl) : TYPE_SIZE_UNIT (TREE_TYPE (decl)); + if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, + NULL, is_gimple_val, fb_rvalue) == GS_ERROR) + OMP_CLAUSE_SIZE (c) = size_int (0); if (c2) { OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (last); @@ -5358,6 +5361,147 @@ enum GFC_OMP_MASK_TASKLOOP = (1 << GFC_OMP_SPLIT_TASKLOOP) }; +/* If a var is in lastprivate/firstprivate/reduction but not in a + data mapping/sharing clause, add it to 'map(tofrom:' if is_target + and to 'shared' otherwise. */ +static void +gfc_add_clause_implicitly (gfc_omp_clauses *clauses_out, + gfc_omp_clauses *clauses_in, + bool is_target, bool is_parallel_do) +{ + int clauselist_to_add = is_target ? OMP_LIST_MAP : OMP_LIST_SHARED; + gfc_omp_namelist *tail = NULL; + for (int i = 0; i < 5; ++i) + { + gfc_omp_namelist *n; + switch (i) + { + case 0: n = clauses_in->lists[OMP_LIST_FIRSTPRIVATE]; break; + case 1: n = clauses_in->lists[OMP_LIST_LASTPRIVATE]; break; + case 2: n = clauses_in->lists[OMP_LIST_REDUCTION]; break; + case 3: n = clauses_in->lists[OMP_LIST_REDUCTION_INSCAN]; break; + case 4: n = clauses_in->lists[OMP_LIST_REDUCTION_TASK]; break; + default: gcc_unreachable (); + } + for (; n != NULL; n = n->next) + { + gfc_omp_namelist *n2, **n_firstp = NULL, **n_lastp = NULL; + for (int j = 0; j < 6; ++j) + { + gfc_omp_namelist **n2ref = NULL, *prev2 = NULL; + switch (j) + { + case 0: + n2ref = &clauses_out->lists[clauselist_to_add]; + break; + case 1: + n2ref = &clauses_out->lists[OMP_LIST_FIRSTPRIVATE]; + break; + case 2: + if (is_target) + n2ref = &clauses_in->lists[OMP_LIST_LASTPRIVATE]; + else + n2ref = &clauses_out->lists[OMP_LIST_LASTPRIVATE]; + break; + case 3: n2ref = &clauses_out->lists[OMP_LIST_REDUCTION]; break; + case 4: + n2ref = &clauses_out->lists[OMP_LIST_REDUCTION_INSCAN]; + break; + case 5: + n2ref = &clauses_out->lists[OMP_LIST_REDUCTION_TASK]; + break; + default: gcc_unreachable (); + } + for (n2 = *n2ref; n2 != NULL; prev2 = n2, n2 = n2->next) + if (n2->sym == n->sym) + break; + if (n2) + { + if (j == 0 /* clauselist_to_add */) + break; /* Already present. */ + if (j == 1 /* OMP_LIST_FIRSTPRIVATE */) + { + n_firstp = prev2 ? &prev2->next : n2ref; + continue; + } + if (j == 2 /* OMP_LIST_LASTPRIVATE */) + { + n_lastp = prev2 ? &prev2->next : n2ref; + continue; + } + break; + } + } + if (n_firstp && n_lastp) + { + /* For parallel do, GCC puts firstprivatee/lastprivate + on the parallel. */ + if (is_parallel_do) + continue; + *n_firstp = (*n_firstp)->next; + if (!is_target) + *n_lastp = (*n_lastp)->next; + } + else if (is_target && n_lastp) + ; + else if (n2 || n_firstp || n_lastp) + continue; + if (clauses_out->lists[clauselist_to_add] + && (clauses_out->lists[clauselist_to_add] + == clauses_in->lists[clauselist_to_add])) + { + gfc_omp_namelist *p = NULL; + for (n2 = clauses_in->lists[clauselist_to_add]; n2; n2 = n2->next) + { + if (p) + { + p->next = gfc_get_omp_namelist (); + p = p->next; + } + else + { + p = gfc_get_omp_namelist (); + clauses_out->lists[clauselist_to_add] = p; + } + *p = *n2; + } + } + if (!tail) + { + tail = clauses_out->lists[clauselist_to_add]; + for (; tail && tail->next; tail = tail->next) + ; + } + n2 = gfc_get_omp_namelist (); + n2->where = n->where; + n2->sym = n->sym; + if (is_target) + n2->u.map_op = OMP_MAP_TOFROM; + if (tail) + { + tail->next = n2; + tail = n2; + } + else + clauses_out->lists[clauselist_to_add] = n2; + } + } +} + +static void +gfc_free_split_omp_clauses (gfc_code *code, gfc_omp_clauses *clausesa) +{ + for (int i = 0; i < GFC_OMP_SPLIT_NUM; ++i) + for (int j = 0; j < OMP_LIST_NUM; ++j) + if (clausesa[i].lists[j] && clausesa[i].lists[j] != code->ext.omp_clauses->lists[j]) + for (gfc_omp_namelist *n = clausesa[i].lists[j]; n;) + { + gfc_omp_namelist *p = n; + n = n->next; + free (p); + } +} + static void gfc_split_omp_clauses (gfc_code *code, gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM]) @@ -5689,7 +5833,8 @@ gfc_split_omp_clauses (gfc_code *code, if (mask & GFC_OMP_MASK_TASKLOOP) clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_FIRSTPRIVATE] = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE]; - if (mask & GFC_OMP_MASK_PARALLEL) + if ((mask & GFC_OMP_MASK_PARALLEL) + && !(mask & GFC_OMP_MASK_TASKLOOP)) clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_FIRSTPRIVATE] = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE]; else if ((mask & GFC_OMP_MASK_DO) && !is_loop) @@ -5704,7 +5849,8 @@ gfc_split_omp_clauses (gfc_code *code, if (mask & GFC_OMP_MASK_TASKLOOP) clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_LASTPRIVATE] = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE]; - if ((mask & GFC_OMP_MASK_PARALLEL) && !is_loop) + if ((mask & GFC_OMP_MASK_PARALLEL) && !is_loop + && !(mask & GFC_OMP_MASK_TASKLOOP)) clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_LASTPRIVATE] = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE]; else if (mask & GFC_OMP_MASK_DO) @@ -5731,6 +5877,7 @@ gfc_split_omp_clauses (gfc_code *code, = code->ext.omp_clauses->lists[i]; if (mask & GFC_OMP_MASK_PARALLEL && i != OMP_LIST_REDUCTION_INSCAN + && !(mask & GFC_OMP_MASK_TASKLOOP) && !is_loop) clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i] = code->ext.omp_clauses->lists[i]; @@ -5752,6 +5899,18 @@ gfc_split_omp_clauses (gfc_code *code, clausesa[innermost].lists[OMP_LIST_LINEAR] = code->ext.omp_clauses->lists[OMP_LIST_LINEAR]; } + /* Propagate firstprivate/lastprivate/reduction vars to + shared (parallel, teams) and map-tofrom (target). */ + if (mask & GFC_OMP_MASK_TARGET) + gfc_add_clause_implicitly (&clausesa[GFC_OMP_SPLIT_TARGET], + code->ext.omp_clauses, true, false); + if ((mask & GFC_OMP_MASK_PARALLEL) && innermost != GFC_OMP_MASK_PARALLEL) + gfc_add_clause_implicitly (&clausesa[GFC_OMP_SPLIT_PARALLEL], + code->ext.omp_clauses, false, + mask & GFC_OMP_MASK_DO); + if (mask & GFC_OMP_MASK_TEAMS && innermost != GFC_OMP_MASK_TEAMS) + gfc_add_clause_implicitly (&clausesa[GFC_OMP_SPLIT_TEAMS], + code->ext.omp_clauses, false, false); if (((mask & (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO)) == (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO)) && !is_loop) @@ -5765,6 +5924,7 @@ gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock, stmtblock_t block; gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM]; tree stmt, body, omp_do_clauses = NULL_TREE; + bool free_clausesa = false; if (pblock == NULL) gfc_start_block (&block); @@ -5775,6 +5935,7 @@ gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock, { clausesa = clausesa_buf; gfc_split_omp_clauses (code, clausesa); + free_clausesa = true; } if (flag_openmp) omp_do_clauses @@ -5800,6 +5961,8 @@ gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock, else stmt = body; gfc_add_expr_to_block (&block, stmt); + if (free_clausesa) + gfc_free_split_omp_clauses (code, clausesa); return gfc_finish_block (&block); } @@ -5810,6 +5973,7 @@ gfc_trans_omp_parallel_do (gfc_code *code, bool is_loop, stmtblock_t *pblock, stmtblock_t block, *new_pblock = pblock; gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM]; tree stmt, omp_clauses = NULL_TREE; + bool free_clausesa = false; if (pblock == NULL) gfc_start_block (&block); @@ -5820,6 +5984,7 @@ gfc_trans_omp_parallel_do (gfc_code *code, bool is_loop, stmtblock_t *pblock, { clausesa = clausesa_buf; gfc_split_omp_clauses (code, clausesa); + free_clausesa = true; } omp_clauses = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL], @@ -5848,6 +6013,8 @@ gfc_trans_omp_parallel_do (gfc_code *code, bool is_loop, stmtblock_t *pblock, void_type_node, stmt, omp_clauses); OMP_PARALLEL_COMBINED (stmt) = 1; gfc_add_expr_to_block (&block, stmt); + if (free_clausesa) + gfc_free_split_omp_clauses (code, clausesa); return gfc_finish_block (&block); } @@ -5858,6 +6025,7 @@ gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock, stmtblock_t block; gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM]; tree stmt, omp_clauses = NULL_TREE; + bool free_clausesa = false; if (pblock == NULL) gfc_start_block (&block); @@ -5868,6 +6036,7 @@ gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock, { clausesa = clausesa_buf; gfc_split_omp_clauses (code, clausesa); + free_clausesa = true; } if (flag_openmp) omp_clauses @@ -5892,6 +6061,8 @@ gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock, OMP_PARALLEL_COMBINED (stmt) = 1; } gfc_add_expr_to_block (&block, stmt); + if (free_clausesa) + gfc_free_split_omp_clauses (code, clausesa); return gfc_finish_block (&block); } @@ -6049,12 +6220,14 @@ gfc_trans_omp_distribute (gfc_code *code, gfc_omp_clauses *clausesa) stmtblock_t block; gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM]; tree stmt, omp_clauses = NULL_TREE; + bool free_clausesa = false; gfc_start_block (&block); if (clausesa == NULL) { clausesa = clausesa_buf; gfc_split_omp_clauses (code, clausesa); + free_clausesa = true; } if (flag_openmp) omp_clauses @@ -6108,6 +6281,8 @@ gfc_trans_omp_distribute (gfc_code *code, gfc_omp_clauses *clausesa) stmt = distribute; } gfc_add_expr_to_block (&block, stmt); + if (free_clausesa) + gfc_free_split_omp_clauses (code, clausesa); return gfc_finish_block (&block); } @@ -6118,13 +6293,14 @@ gfc_trans_omp_teams (gfc_code *code, gfc_omp_clauses *clausesa, stmtblock_t block; gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM]; tree stmt; - bool combined = true; + bool combined = true, free_clausesa = false; gfc_start_block (&block); if (clausesa == NULL) { clausesa = clausesa_buf; gfc_split_omp_clauses (code, clausesa); + free_clausesa = true; } if (flag_openmp) { @@ -6167,6 +6343,8 @@ gfc_trans_omp_teams (gfc_code *code, gfc_omp_clauses *clausesa, OMP_TEAMS_COMBINED (stmt) = 1; } gfc_add_expr_to_block (&block, stmt); + if (free_clausesa) + gfc_free_split_omp_clauses (code, clausesa); return gfc_finish_block (&block); } @@ -6276,6 +6454,7 @@ gfc_trans_omp_target (gfc_code *code) cfun->has_omp_target = true; } gfc_add_expr_to_block (&block, stmt); + gfc_free_split_omp_clauses (code, clausesa); return gfc_finish_block (&block); } @@ -6318,6 +6497,7 @@ gfc_trans_omp_taskloop (gfc_code *code, gfc_exec_op op) stmt = taskloop; } gfc_add_expr_to_block (&block, stmt); + gfc_free_split_omp_clauses (code, clausesa); return gfc_finish_block (&block); } @@ -6341,6 +6521,8 @@ gfc_trans_omp_master_taskloop (gfc_code *code, gfc_exec_op op) op != code->op ? &clausesa[GFC_OMP_SPLIT_TASKLOOP] : code->ext.omp_clauses, NULL); + if (op != code->op) + gfc_free_split_omp_clauses (code, clausesa); } if (TREE_CODE (stmt) != BIND_EXPR) stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0)); @@ -6367,6 +6549,8 @@ gfc_trans_omp_parallel_master (gfc_code *code) ? code->ext.omp_clauses : &clausesa[GFC_OMP_SPLIT_PARALLEL], code->loc); + if (code->op != EXEC_OMP_PARALLEL_MASTER) + gfc_free_split_omp_clauses (code, clausesa); pushlevel (); if (code->op == EXEC_OMP_PARALLEL_MASTER) stmt = gfc_trans_omp_master (code); diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 2c53606..09dcd69 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -1008,7 +1008,7 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name, if (!stmt) return false; - fur_source src (&q, NULL, e, stmt); + fur_stmt src (stmt, &q); // If NAME can be calculated on the edge, use that. if (is_export_p (name, e->src)) diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index db8419b..b534b8e 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -49,19 +49,284 @@ along with GCC; see the file COPYING3. If not see // Evaluate expression EXPR using the source information the class was // instantiated with. Place the result in R, and return TRUE. If a range -// cannot be calcluated, return FALSE. +// cannot be calculated, return FALSE. bool fur_source::get_operand (irange &r, tree expr) { - // First look for a stmt. - if (m_stmt) - return m_query->range_of_expr (r, expr, m_stmt); + return get_range_query (cfun)->range_of_expr (r, expr); +} + +// Evaluate EXPR for this stmt as a PHI argument on edge E. Use the current +// range_query to get the range on the edge. + +bool +fur_source::get_phi_operand (irange &r, tree expr, edge e) +{ + return get_range_query (cfun)->range_on_edge (r, e, expr); +} + +// Default is to not register any dependencies from fold_using_range. + +void +fur_source::register_dependency (tree lhs ATTRIBUTE_UNUSED, + tree rhs ATTRIBUTE_UNUSED) +{ +} + +// Default object is the current range query. + +range_query * +fur_source::query () +{ + return get_range_query (cfun); +} + +// This version of fur_source will pick a range up off an edge. - // Finally must be on an edge. +class fur_edge : public fur_source +{ +public: + fur_edge (edge e, range_query *q = NULL); + virtual bool get_operand (irange &r, tree expr) OVERRIDE; + virtual bool get_phi_operand (irange &r, tree expr, edge e) OVERRIDE; + virtual range_query *query () OVERRIDE; +private: + range_query *m_query; + edge m_edge; +}; + +// Instantiate an edge based fur_source. + +inline +fur_edge::fur_edge (edge e, range_query *q) +{ + m_edge = e; + if (q) + m_query = q; + else + m_query = get_range_query (cfun); +} + +// Get the value of EXPR on edge m_edge. + +bool +fur_edge::get_operand (irange &r, tree expr) +{ return m_query->range_on_edge (r, m_edge, expr); } +// Evaluate EXPR for this stmt as a PHI argument on edge E. Use the current +// range_query to get the range on the edge. + +bool +fur_edge::get_phi_operand (irange &r, tree expr, edge e) +{ + // edge to edge recalculations not supoprted yet, until we sort it out. + gcc_checking_assert (e == m_edge); + return m_query->range_on_edge (r, e, expr); +} + +// Return the current range_query object. + +range_query * +fur_edge::query () +{ + return m_query; +} + + +// Instantiate a stmt based fur_source. + + +fur_stmt::fur_stmt (gimple *s, range_query *q) +{ + m_stmt= s; + if (q) + m_query = q; + else + m_query = get_global_range_query (); +} + +// Retirenve range of EXPR as it occurs as a use on stmt M_STMT. + +bool +fur_stmt::get_operand (irange &r, tree expr) +{ + return m_query->range_of_expr (r, expr, m_stmt); +} + +// Evaluate EXPR for this stmt as a PHI argument on edge E. Use the current +// range_query to get the range on the edge. + +bool +fur_stmt::get_phi_operand (irange &r, tree expr, edge e) +{ + // Pick up the range of expr from edge E. + fur_edge e_src (e, m_query); + return e_src.get_operand (r, expr); +} + +// Return the current range_query object. + +range_query * +fur_stmt::query () +{ + return m_query; +} + +// This version of fur_source will pick a range from a stmt, and register +// also dependencies via a gori_compute object. This is mostly an internal API. + +class fur_depend : public fur_stmt +{ +public: + fur_depend (gimple *s, gori_compute *gori, range_query *q = NULL); + virtual void register_dependency (tree lhs, tree rhs) OVERRIDE; +private: + gori_compute *m_gori; +}; + +// Instantiate a stmt based fur_source witrh a GORI object +inline +fur_depend::fur_depend (gimple *s, gori_compute *gori, range_query *q) + : fur_stmt (s, q) +{ + gcc_checking_assert (gori); + m_gori = gori; +} + + +// find and add any dependnecy between LHS and RHS + +void +fur_depend::register_dependency (tree lhs, tree rhs) +{ + m_gori->register_dependency (lhs, rhs); +} + + +// This version of fur_source will pick a range up from a list of ranges +// supplied by the caller. + +class fur_list : public fur_source +{ +public: + fur_list (irange &r1); + fur_list (irange &r1, irange &r2); + fur_list (unsigned num, irange *list); + virtual bool get_operand (irange &r, tree expr) OVERRIDE; + virtual bool get_phi_operand (irange &r, tree expr, edge e) OVERRIDE; +private: + int_range_max m_local[2]; + irange *m_list; + unsigned m_index; + unsigned m_limit; +}; + +// One range supplied for unary operations. + +fur_list::fur_list (irange &r1) +{ + m_list = m_local; + m_index = 0; + m_limit = 1; + m_local[0] = r1; +} + +// Two ranges supplied for binary operations. + +fur_list::fur_list (irange &r1, irange &r2) +{ + m_list = m_local; + m_index = 0; + m_limit = 2; + m_local[0] = r1; + m_local[0] = r2; +} + +// Arbitrary number of ranges in a vector. + +fur_list::fur_list (unsigned num, irange *list) +{ + m_list = list; + m_index = 0; + m_limit = num; +} + +// Get the next operand from the vector, ensure types are compatible, + +bool +fur_list::get_operand (irange &r, tree expr) +{ + if (m_index >= m_limit) + return get_range_query (cfun)->range_of_expr (r, expr); + r = m_list[m_index++]; + gcc_checking_assert (range_compatible_p (TREE_TYPE (expr), r.type ())); + return true; +} + +// This will simply pick the next operand from the vector. +bool +fur_list::get_phi_operand (irange &r, tree expr, edge e ATTRIBUTE_UNUSED) +{ + return get_operand (r, expr); +} + +// Fold stmt S into range R using R1 as the first operand. + +bool +fold_range (irange &r, gimple *s, irange &r1) +{ + fold_using_range f; + fur_list src (r1); + return f.fold_stmt (r, s, src); +} + +// Fold stmt S into range R using R1 and R2 as the first two operands. + +bool +fold_range (irange &r, gimple *s, irange &r1, irange &r2) +{ + fold_using_range f; + fur_list src (r1, r2); + return f.fold_stmt (r, s, src); +} + + +// Fold stmt S into range R using NUM_ELEMENTS from VECTOR as the initial +// operands encountered. + +bool +fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector) +{ + fold_using_range f; + fur_list src (num_elements, vector); + return f.fold_stmt (r, s, src); +} + + +// Fold stmt S into range R using range query Q. + +bool +fold_range (irange &r, gimple *s, range_query *q) +{ + fold_using_range f; + fur_stmt src (s, q); + return f.fold_stmt (r, s, src); +} + +// Recalculate stmt S into R using range query Q as if it were on edge ON_EDGE. + +bool +fold_range (irange &r, gimple *s, edge on_edge, range_query *q) +{ + fold_using_range f; + fur_edge src (on_edge, q); + return f.fold_stmt (r, s, src); +} + +// ------------------------------------------------------------------------- // Adjust the range for a pointer difference where the operands came // from a memchr. @@ -375,17 +640,17 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src) // Fold range, and register any dependency if available. int_range<2> r2 (type); handler->fold_range (r, type, range1, r2); - if (lhs && src.m_gori) - src.m_gori->register_dependency (lhs, op1); + if (lhs) + src.register_dependency (lhs, op1); } else if (src.get_operand (range2, op2)) { // Fold range, and register any dependency if available. handler->fold_range (r, type, range1, range2); - if (lhs && src.m_gori) + if (lhs) { - src.m_gori->register_dependency (lhs, op1); - src.m_gori->register_dependency (lhs, op2); + src.register_dependency (lhs, op1); + src.register_dependency (lhs, op2); } } else @@ -425,8 +690,8 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src) { tree ssa = TREE_OPERAND (base, 0); tree lhs = gimple_get_lhs (stmt); - if (src.m_gori && lhs && gimple_range_ssa_p (ssa)) - src.m_gori->register_dependency (lhs, ssa); + if (lhs && gimple_range_ssa_p (ssa)) + src.register_dependency (lhs, ssa); gcc_checking_assert (irange::supports_type_p (TREE_TYPE (ssa))); src.get_operand (r, ssa); range_cast (r, TREE_TYPE (gimple_assign_rhs1 (stmt))); @@ -503,19 +768,12 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src) edge e = gimple_phi_arg_edge (phi, x); // Register potential dependencies for stale value tracking. - if (src.m_gori && gimple_range_ssa_p (arg)) - src.m_gori->register_dependency (phi_def, arg); + if (gimple_range_ssa_p (arg)) + src.register_dependency (phi_def, arg); // Get the range of the argument on its edge. - fur_source e_src (src.m_query, e); - e_src.get_operand (arg_range, arg); + src.get_phi_operand (arg_range, arg, e); // If we're recomputing the argument elsewhere, try to refine it. - if (src.m_stmt != phi) - { - int_range_max tmp; - e_src.get_operand (tmp, arg); - arg_range.intersect (tmp); - } r.union_ (arg_range); // Once the value reaches varying, stop looking. if (r.varying_p ()) @@ -1012,7 +1270,7 @@ bool gimple_ranger::fold_range_internal (irange &r, gimple *s, tree name) { fold_using_range f; - fur_source src (this, &(gori ()), NULL, s); + fur_depend src (s, &(gori ()), this); return f.fold_stmt (r, s, src, name); } @@ -1191,22 +1449,18 @@ fold_using_range::range_of_ssa_name_with_loop_info (irange &r, tree name, { gcc_checking_assert (TREE_CODE (name) == SSA_NAME); tree min, max, type = TREE_TYPE (name); - if (bounds_of_var_in_loop (&min, &max, src.m_query, l, phi, name)) + if (bounds_of_var_in_loop (&min, &max, src.query (), l, phi, name)) { if (TREE_CODE (min) != INTEGER_CST) { - if (src.m_query - && src.m_query->range_of_expr (r, min, phi) - && !r.undefined_p ()) + if (src.query ()->range_of_expr (r, min, phi) && !r.undefined_p ()) min = wide_int_to_tree (type, r.lower_bound ()); else min = vrp_val_min (type); } if (TREE_CODE (max) != INTEGER_CST) { - if (src.m_query - && src.m_query->range_of_expr (r, max, phi) - && !r.undefined_p ()) + if (src.query ()->range_of_expr (r, max, phi) && !r.undefined_p ()) max = wide_int_to_tree (type, r.upper_bound ()); else max = vrp_val_max (type); diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h index 02b891f..9ac779a 100644 --- a/gcc/gimple-range.h +++ b/gcc/gimple-range.h @@ -73,28 +73,45 @@ protected: ranger_cache m_cache; }; -// Source of an operand for fold_using_range. -// It can specify a stmt or and edge, or thru an internal API which uses -// the ranger cache. -// Its primary function is to retreive an operand from the source via a -// call thru the range_query object. +// Source of all operands for fold_using_range and gori_compute. +// It abstracts out the source of an operand so it can come from a stmt or +// and edge or anywhere a derived classof fur_source wants. class fur_source { - friend class fold_using_range; public: - inline fur_source (range_query *q, edge e); - inline fur_source (range_query *q, gimple *s); - inline fur_source (range_query *q, gori_compute *g, edge e, gimple *s); - bool get_operand (irange &r, tree expr); -protected: - gori_compute *m_gori; + virtual bool get_operand (irange &r, tree expr); + virtual bool get_phi_operand (irange &r, tree expr, edge e); + virtual void register_dependency (tree lhs, tree rhs); + virtual range_query *query (); +}; + +// fur_stmt is the specification for drawing an operand from range_query Q +// via a range_of_Expr call on stmt S. + +class fur_stmt : public fur_source +{ +public: + fur_stmt (gimple *s, range_query *q = NULL); + virtual bool get_operand (irange &r, tree expr) OVERRIDE; + virtual bool get_phi_operand (irange &r, tree expr, edge e) OVERRIDE; + virtual range_query *query () OVERRIDE; +private: range_query *m_query; - edge m_edge; gimple *m_stmt; }; +// Fold stmt S into range R using range query Q. +bool fold_range (irange &r, gimple *s, range_query *q = NULL); +// Recalculate stmt S into R using range query Q as if it were on edge ON_EDGE. +bool fold_range (irange &r, gimple *s, edge on_edge, range_query *q = NULL); +// These routines allow you to specify the operands to use when folding. +// Any excess queries will be drawn from the current range_query. +bool fold_range (irange &r, gimple *s, irange &r1); +bool fold_range (irange &r, gimple *s, irange &r1, irange &r2); +bool fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector); + // This class uses ranges to fold a gimple statement producinf a range for // the LHS. The source of all operands is supplied via the fur_source class // which provides a range_query as well as a source location and any other @@ -119,64 +136,6 @@ protected: }; -// Create a source for a query on an edge. - -inline -fur_source::fur_source (range_query *q, edge e) -{ - m_query = q; - m_gori = NULL; - m_edge = e; - m_stmt = NULL; -} - -// Create a source for a query at a statement. - -inline -fur_source::fur_source (range_query *q, gimple *s) -{ - m_query = q; - m_gori = NULL; - m_edge = NULL; - m_stmt = s; -} - -// Create a source for Ranger. THis can recalculate from a different location -// and can also set the dependency information as appropriate when invoked. - -inline -fur_source::fur_source (range_query *q, gori_compute *g, edge e, gimple *s) -{ - m_query = q; - m_gori = g; - m_edge = e; - m_stmt = s; -} - -// Fold stmt S into range R using range query Q. - -inline bool -fold_range (irange &r, gimple *s, range_query *q = NULL) -{ - fold_using_range f; - if (q == NULL) - q = get_global_range_query (); - fur_source src (q, s); - return f.fold_stmt (r, s, src); -} - -// Recalculate stmt S into R using range query Q as if it were on edge ON_EDGE. - -inline bool -fold_range (irange &r, gimple *s, edge on_edge, range_query *q = NULL) -{ - fold_using_range f; - if (q == NULL) - q = get_global_range_query (); - fur_source src (q, on_edge); - return f.fold_stmt (r, s, src); -} - // These routines provide a GIMPLE interface to the range-ops code. extern tree gimple_range_operand1 (const gimple *s); extern tree gimple_range_operand2 (const gimple *s); diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index 118d103..7e1cf51 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -42,6 +42,307 @@ along with GCC; see the file COPYING3. If not see #include "vr-values.h" #include "gimple-ssa-evrp-analyze.h" #include "gimple-range.h" +#include "fold-const.h" + +// Unwindable SSA equivalence table for pointers. +// +// The main query point is get_replacement() which returns what a +// given SSA can be replaced with in the current scope. + +class ssa_equiv_stack +{ +public: + ssa_equiv_stack (); + ~ssa_equiv_stack (); + void enter (basic_block); + void leave (basic_block); + void push_replacement (tree name, tree replacement); + tree get_replacement (tree name) const; + +private: + auto_vec<std::pair <tree, tree>> m_stack; + tree *m_replacements; + const std::pair <tree, tree> m_marker = std::make_pair (NULL, NULL); +}; + +ssa_equiv_stack::ssa_equiv_stack () +{ + m_replacements = new tree[num_ssa_names] (); +} + +ssa_equiv_stack::~ssa_equiv_stack () +{ + m_stack.release (); + delete m_replacements; +} + +// Pushes a marker at the given point. + +void +ssa_equiv_stack::enter (basic_block) +{ + m_stack.safe_push (m_marker); +} + +// Pops the stack to the last marker, while performing replacements +// along the way. + +void +ssa_equiv_stack::leave (basic_block) +{ + gcc_checking_assert (!m_stack.is_empty ()); + while (m_stack.last () != m_marker) + { + std::pair<tree, tree> e = m_stack.pop (); + m_replacements[SSA_NAME_VERSION (e.first)] = e.second; + } + m_stack.pop (); +} + +// Set the equivalence of NAME to REPLACEMENT. + +void +ssa_equiv_stack::push_replacement (tree name, tree replacement) +{ + tree old = m_replacements[SSA_NAME_VERSION (name)]; + m_replacements[SSA_NAME_VERSION (name)] = replacement; + m_stack.safe_push (std::make_pair (name, old)); +} + +// Return the equivalence of NAME. + +tree +ssa_equiv_stack::get_replacement (tree name) const +{ + return m_replacements[SSA_NAME_VERSION (name)]; +} + +// Return TRUE if EXPR is an SSA holding a pointer. + +static bool inline +is_pointer_ssa (tree expr) +{ + return TREE_CODE (expr) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (expr)); +} + +// Simple context-aware pointer equivalency analyzer that returns what +// a pointer SSA name is equivalent to at a given point during a walk +// of the IL. +// +// Note that global equivalency take priority over conditional +// equivalency. That is, p = &q takes priority over a later p == &t. +// +// This class is meant to be called during a DOM walk. + +class pointer_equiv_analyzer +{ +public: + pointer_equiv_analyzer (gimple_ranger *r); + ~pointer_equiv_analyzer (); + void enter (basic_block); + void leave (basic_block); + void visit_stmt (gimple *stmt); + tree get_equiv (tree ssa) const; + +private: + void visit_edge (edge e); + tree get_equiv_expr (tree_code code, tree expr) const; + void set_global_equiv (tree ssa, tree pointee); + void set_cond_equiv (tree ssa, tree pointee); + + gimple_ranger *m_ranger; + // Global pointer equivalency indexed by SSA_NAME_VERSION. + tree *m_global_points; + // Conditional pointer equivalency. + ssa_equiv_stack m_cond_points; +}; + +pointer_equiv_analyzer::pointer_equiv_analyzer (gimple_ranger *r) +{ + m_ranger = r; + m_global_points = new tree[num_ssa_names] (); +} + +pointer_equiv_analyzer::~pointer_equiv_analyzer () +{ + delete m_global_points; +} + +// Set the global pointer equivalency for SSA to POINTEE. + +void +pointer_equiv_analyzer::set_global_equiv (tree ssa, tree pointee) +{ + m_global_points[SSA_NAME_VERSION (ssa)] = pointee; +} + +// Set the conditional pointer equivalency for SSA to POINTEE. + +void +pointer_equiv_analyzer::set_cond_equiv (tree ssa, tree pointee) +{ + m_cond_points.push_replacement (ssa, pointee); +} + +// Return the current pointer equivalency info for SSA, or NULL if +// none is available. Note that global info takes priority over +// conditional info. + +tree +pointer_equiv_analyzer::get_equiv (tree ssa) const +{ + tree ret = m_global_points[SSA_NAME_VERSION (ssa)]; + if (ret) + return ret; + return m_cond_points.get_replacement (ssa); +} + +// Method to be called on entry to a BB. + +void +pointer_equiv_analyzer::enter (basic_block bb) +{ + m_cond_points.enter (bb); + + for (gphi_iterator iter = gsi_start_phis (bb); + !gsi_end_p (iter); + gsi_next (&iter)) + { + gphi *phi = iter.phi (); + tree lhs = gimple_phi_result (phi); + if (!POINTER_TYPE_P (TREE_TYPE (lhs))) + continue; + tree arg0 = gimple_phi_arg_def (phi, 0); + if (TREE_CODE (arg0) == SSA_NAME && !is_gimple_min_invariant (arg0)) + arg0 = get_equiv (arg0); + if (arg0 && is_gimple_min_invariant (arg0)) + { + // If all the PHI args point to the same place, set the + // pointer equivalency info for the PHI result. This can + // happen for passes that create redundant PHIs like + // PHI<&foo, &foo> or PHI<&foo>. + for (size_t i = 1; i < gimple_phi_num_args (phi); ++i) + { + tree argi = gimple_phi_arg_def (phi, i); + if (TREE_CODE (argi) == SSA_NAME + && !is_gimple_min_invariant (argi)) + argi = get_equiv (argi); + if (!argi || !operand_equal_p (arg0, argi)) + return; + } + set_global_equiv (lhs, arg0); + } + } + + edge pred = single_pred_edge_ignoring_loop_edges (bb, false); + if (pred) + visit_edge (pred); +} + +// Method to be called on exit from a BB. + +void +pointer_equiv_analyzer::leave (basic_block bb) +{ + m_cond_points.leave (bb); +} + +// Helper function to return the pointer equivalency information for +// EXPR from a gimple statement with CODE. This returns either the +// cached pointer equivalency info for an SSA, or an invariant in case +// EXPR is one (i.e. &foo). Returns NULL if EXPR is neither an SSA +// nor an invariant. + +tree +pointer_equiv_analyzer::get_equiv_expr (tree_code code, tree expr) const +{ + if (code == SSA_NAME) + return get_equiv (expr); + + if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS + && is_gimple_min_invariant (expr)) + return expr; + + return NULL; +} + +// Hack to provide context to the gimple fold callback. +static struct +{ + gimple *m_stmt; + gimple_ranger *m_ranger; + pointer_equiv_analyzer *m_pta; +} x_fold_context; + +// Gimple fold callback. +static tree +pta_valueize (tree name) +{ + tree ret + = x_fold_context.m_ranger->value_of_expr (name, x_fold_context.m_stmt); + + if (!ret && is_pointer_ssa (name)) + ret = x_fold_context.m_pta->get_equiv (name); + + return ret ? ret : name; +} + +// Method to be called on gimple statements during traversal of the IL. + +void +pointer_equiv_analyzer::visit_stmt (gimple *stmt) +{ + if (gimple_code (stmt) != GIMPLE_ASSIGN) + return; + + tree lhs = gimple_assign_lhs (stmt); + if (!is_pointer_ssa (lhs)) + return; + + tree rhs = gimple_assign_rhs1 (stmt); + rhs = get_equiv_expr (gimple_assign_rhs_code (stmt), rhs); + if (rhs) + { + set_global_equiv (lhs, rhs); + return; + } + + // If we couldn't find anything, try fold. + x_fold_context = { stmt, m_ranger, this}; + rhs = gimple_fold_stmt_to_constant_1 (stmt, pta_valueize, pta_valueize); + if (rhs) + { + rhs = get_equiv_expr (TREE_CODE (rhs), rhs); + if (rhs) + { + set_global_equiv (lhs, rhs); + return; + } + } +} + +// If the edge in E is a conditional that sets a pointer equality, set the +// conditional pointer equivalency information. + +void +pointer_equiv_analyzer::visit_edge (edge e) +{ + gimple *stmt = last_stmt (e->src); + tree lhs; + // Recognize: x_13 [==,!=] &foo. + if (stmt + && gimple_code (stmt) == GIMPLE_COND + && (lhs = gimple_cond_lhs (stmt)) + && TREE_CODE (lhs) == SSA_NAME + && POINTER_TYPE_P (TREE_TYPE (lhs)) + && TREE_CODE (gimple_cond_rhs (stmt)) == ADDR_EXPR) + { + tree_code code = gimple_cond_code (stmt); + if ((code == EQ_EXPR && e->flags & EDGE_TRUE_VALUE) + || ((code == NE_EXPR && e->flags & EDGE_FALSE_VALUE))) + set_cond_equiv (lhs, gimple_cond_rhs (stmt)); + } +} // This is the classic EVRP folder which uses a dominator walk and pushes // ranges into the next block if it is a single predecessor block. @@ -120,6 +421,7 @@ public: { m_ranger = enable_ranger (cfun); m_simplifier.set_range_query (m_ranger); + m_pta = new pointer_equiv_analyzer (m_ranger); } ~rvrp_folder () @@ -129,16 +431,23 @@ public: m_ranger->export_global_ranges (); disable_ranger (cfun); + delete m_pta; } tree value_of_expr (tree name, gimple *s = NULL) OVERRIDE { - return m_ranger->value_of_expr (name, s); + tree ret = m_ranger->value_of_expr (name, s); + if (!ret && is_pointer_ssa (name)) + ret = m_pta->get_equiv (name); + return ret; } tree value_on_edge (edge e, tree name) OVERRIDE { - return m_ranger->value_on_edge (e, name); + tree ret = m_ranger->value_on_edge (e, name); + if (!ret && is_pointer_ssa (name)) + ret = m_pta->get_equiv (name); + return ret; } tree value_of_stmt (gimple *s, tree name = NULL) OVERRIDE @@ -146,6 +455,21 @@ public: return m_ranger->value_of_stmt (s, name); } + void pre_fold_bb (basic_block bb) OVERRIDE + { + m_pta->enter (bb); + } + + void post_fold_bb (basic_block bb) OVERRIDE + { + m_pta->leave (bb); + } + + void pre_fold_stmt (gimple *stmt) OVERRIDE + { + m_pta->visit_stmt (stmt); + } + bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE { return m_simplifier.simplify (gsi); @@ -155,6 +479,7 @@ private: DISABLE_COPY_AND_ASSIGN (rvrp_folder); gimple_ranger *m_ranger; simplify_using_ranges m_simplifier; + pointer_equiv_analyzer *m_pta; }; // In a hybrid folder, start with an EVRP folder, and add the required @@ -186,6 +511,7 @@ public: first = m_ranger; second = &m_range_analyzer; } + m_pta = new pointer_equiv_analyzer (m_ranger); } ~hybrid_folder () @@ -195,6 +521,7 @@ public: m_ranger->export_global_ranges (); disable_ranger (cfun); + delete m_pta; } bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE @@ -213,6 +540,24 @@ public: return false; } + void pre_fold_stmt (gimple *stmt) OVERRIDE + { + evrp_folder::pre_fold_stmt (stmt); + m_pta->visit_stmt (stmt); + } + + void pre_fold_bb (basic_block bb) OVERRIDE + { + evrp_folder::pre_fold_bb (bb); + m_pta->enter (bb); + } + + void post_fold_bb (basic_block bb) OVERRIDE + { + evrp_folder::post_fold_bb (bb); + m_pta->leave (bb); + } + tree value_of_expr (tree name, gimple *) OVERRIDE; tree value_on_edge (edge, tree name) OVERRIDE; tree value_of_stmt (gimple *, tree name) OVERRIDE; @@ -222,6 +567,7 @@ private: gimple_ranger *m_ranger; range_query *first; range_query *second; + pointer_equiv_analyzer *m_pta; tree choose_value (tree evrp_val, tree ranger_val); }; @@ -231,6 +577,8 @@ hybrid_folder::value_of_expr (tree op, gimple *stmt) { tree evrp_ret = evrp_folder::value_of_expr (op, stmt); tree ranger_ret = m_ranger->value_of_expr (op, stmt); + if (!ranger_ret && is_pointer_ssa (op)) + ranger_ret = m_pta->get_equiv (op); return choose_value (evrp_ret, ranger_ret); } @@ -241,6 +589,8 @@ hybrid_folder::value_on_edge (edge e, tree op) // via hybrid_folder::value_of_expr, but without an edge. tree evrp_ret = evrp_folder::value_of_expr (op, NULL); tree ranger_ret = m_ranger->value_on_edge (e, op); + if (!ranger_ret && is_pointer_ssa (op)) + ranger_ret = m_pta->get_equiv (op); return choose_value (evrp_ret, ranger_ret); } diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 6a3d66e..2c8acae 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,4 +1,9 @@ -2021-06-07 Bernd Edlinger <bernd.edlinger@softing.com> +2021-06-08 Bernd Edlinger <bernd.edlinger@hotmail.de> + + * Make-lang.in (cc1-obj-checksum.c): Check previous + stage checksum exists. + +2021-06-07 Bernd Edlinger <bernd.edlinger@hotmail.de> * Make-lang.in (cc1obj-checksum.c): For stage-final re-use the checksum from the previous stage. diff --git a/gcc/objc/Make-lang.in b/gcc/objc/Make-lang.in index 9011140..8215283 100644 --- a/gcc/objc/Make-lang.in +++ b/gcc/objc/Make-lang.in @@ -63,7 +63,8 @@ objc_OBJS = $(OBJC_OBJS) cc1obj-checksum.o cc1obj-checksum.c : build/genchecksum$(build_exeext) checksum-options \ $(OBJC_OBJS) $(C_AND_OBJC_OBJS) $(BACKEND) $(LIBDEPS) if [ -f ../stage_final ] \ - && cmp -s ../stage_current ../stage_final; then \ + && cmp -s ../stage_current ../stage_final \ + && [ -f ../prev-gcc/$@ ]; then \ cp ../prev-gcc/$@ $@; \ else \ build/genchecksum$(build_exeext) $(OBJC_OBJS) $(C_AND_OBJC_OBJS) \ diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog index f3ef33a..5d6187b 100644 --- a/gcc/objcp/ChangeLog +++ b/gcc/objcp/ChangeLog @@ -1,4 +1,9 @@ -2021-06-07 Bernd Edlinger <bernd.edlinger@softing.com> +2021-06-08 Bernd Edlinger <bernd.edlinger@hotmail.de> + + * Make-lang.in (cc1objplus-checksum.c): Check previous + stage checksum exists. + +2021-06-07 Bernd Edlinger <bernd.edlinger@hotmai.de> * Make-lang.in (cc1objplus-checksum.c): For stage-final re-use the checksum from the previous stage. diff --git a/gcc/objcp/Make-lang.in b/gcc/objcp/Make-lang.in index 3ecc50b..0f890d8 100644 --- a/gcc/objcp/Make-lang.in +++ b/gcc/objcp/Make-lang.in @@ -66,7 +66,8 @@ obj-c++_OBJS = $(OBJCXX_OBJS) cc1objplus-checksum.o cc1objplus-checksum.c : build/genchecksum$(build_exeext) checksum-options \ $(OBJCXX_OBJS) $(BACKEND) $(CODYLIB) $(LIBDEPS) if [ -f ../stage_final ] \ - && cmp -s ../stage_current ../stage_final; then \ + && cmp -s ../stage_current ../stage_final \ + && [ -f ../prev-gcc/$@ ]; then \ cp ../prev-gcc/$@ $@; \ else \ build/genchecksum$(build_exeext) $(OBJCXX_OBJS) $(BACKEND) \ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 272bad0..640fcbe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,99 @@ +2021-06-08 Marek Polacek <polacek@redhat.com> + + PR c++/100065 + * g++.dg/cpp2a/explicit18.C: New test. + +2021-06-08 Andrew Pinski <apinski@marvell.com> + + * gcc.dg/tree-ssa/pr96928-1.c: Fix testcase for now that ~ + happens on the outside of the bit_xor. + +2021-06-08 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp0x/pr60209-neg.C: Update diagnostic. + * g++.dg/diagnostic/string-literal-concat.C: Likewise. + * g++.dg/ext/utf-badconcat.C: Likewise. + * g++.dg/ext/utf-badconcat2.C: Likewise. + +2021-06-08 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp23/mixed-concat1.C: New test. + +2021-06-08 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp23/whitespace-splice1.C: New test. + +2021-06-08 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp23/narrowing-bool1.C: New test. + +2021-06-08 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/99212 + * gcc.dg/analyzer/bitfields-1.c: New test. + * gcc.dg/analyzer/data-model-1.c (struct sbits): Make bitfields + explicitly signed. + (test_44): Update test values assigned to the bits to ones that + fit in the range of the bitfield type. Remove xfails. + (test_45): Remove xfails. + +2021-06-08 Jason Merrill <jason@redhat.com> + + PR c++/100963 + * g++.dg/cpp0x/initlist124.C: New test. + +2021-06-08 Richard Biener <rguenther@suse.de> + + PR tree-optimization/100923 + * gcc.dg/torture/pr100923.c: New testcase. + +2021-06-08 Jakub Jelinek <jakub@redhat.com> + + PR c++/100957 + * g++.dg/gomp/doacross-2.C: New test. + +2021-06-08 H.J. Lu <hjl.tools@gmail.com> + + PR middle-end/100951 + * gcc.target/i386/pr100951.c: New test. + +2021-06-08 Jakub Jelinek <jakub@redhat.com> + + PR target/100887 + PR testsuite/100943 + * gcc.dg/pr100887.c: Add -Wno-psabi -w to dg-options. + +2021-06-08 Tobias Burnus <tobias@codesourcery.com> + + PR middle-end/99928 + * gfortran.dg/gomp/openmp-simd-6.f90: Update scan-tree-dump. + * gfortran.dg/gomp/scan-5.f90: Likewise. + * gfortran.dg/gomp/loop-1.f90: Likewise; remove xfail. + * gfortran.dg/gomp/pr99928-1.f90: Remove xfail. + * gfortran.dg/gomp/pr99928-2.f90: Likewise. + * gfortran.dg/gomp/pr99928-3.f90: Likewise. + * gfortran.dg/gomp/pr99928-8.f90: Likewise. + +2021-06-08 Martin Liska <mliska@suse.cz> + + * gcc.dg/format/strfmon-1.c: Fix typo. + * gfortran.dg/char4-subscript.f90: Likewise. + +2021-06-08 Kewen Lin <linkw@linux.ibm.com> + + PR tree-optimization/100794 + * gcc.dg/tree-ssa/pr100794.c: New test. + +2021-06-08 Jason Merrill <jason@redhat.com> + + PR c++/91706 + * g++.dg/template/lookup17.C: New test. + +2021-06-08 Jason Merrill <jason@redhat.com> + + PR c++/100102 + * g++.dg/cpp0x/alias-decl-73.C: New test. + 2021-06-07 Uroš Bizjak <ubizjak@gmail.com> PR target/100637 diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist124.C b/gcc/testsuite/g++.dg/cpp0x/initlist124.C new file mode 100644 index 0000000..45dcbb3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist124.C @@ -0,0 +1,13 @@ +// PR c++/100963 +// { dg-do compile { target c++11 } } + +#include <initializer_list> + +struct B { + B(int) = delete; + template<class T> B(std::initializer_list<T>); +}; + +int main() { + B({0}); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/pr60209-neg.C b/gcc/testsuite/g++.dg/cpp0x/pr60209-neg.C index 77fd3d8..6c3ad0c 100644 --- a/gcc/testsuite/g++.dg/cpp0x/pr60209-neg.C +++ b/gcc/testsuite/g++.dg/cpp0x/pr60209-neg.C @@ -17,7 +17,7 @@ void operator L"" "" _x(unsigned long long); // { dg-error "invalid encoding pre void operator u8"" "" _y(unsigned long long); // { dg-error "invalid encoding prefix in literal operator" } -void operator u"" L"" _z(unsigned long long); // { dg-error "unsupported non-standard concatenation of string literals" } +void operator u"" L"" _z(unsigned long long); // { dg-error "concatenation of string literals with conflicting encoding prefixes" } void operator ""_p ""_q(unsigned long long); // { dg-error "inconsistent user-defined literal suffixes" } diff --git a/gcc/testsuite/g++.dg/cpp23/mixed-concat1.C b/gcc/testsuite/g++.dg/cpp23/mixed-concat1.C new file mode 100644 index 0000000..d69fafc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/mixed-concat1.C @@ -0,0 +1,21 @@ +// Test from P2201R1 +// { dg-do compile { target c++11 } } + +void f() { + + { auto a = L"" u""; } // { dg-error "concatenation" } + { auto a = L"" u8""; } // { dg-error "concatenation" } + { auto a = L"" U""; } // { dg-error "concatenation" } + + { auto a = u8"" L""; } // { dg-error "concatenation" } + { auto a = u8"" u""; } // { dg-error "concatenation" } + { auto a = u8"" U""; } // { dg-error "concatenation" } + + { auto a = u"" L""; } // { dg-error "concatenation" } + { auto a = u"" u8""; } // { dg-error "concatenation" } + { auto a = u"" U""; } // { dg-error "concatenation" } + + { auto a = U"" L""; } // { dg-error "concatenation" } + { auto a = U"" u""; } // { dg-error "concatenation" } + { auto a = U"" u8""; } // { dg-error "concatenation" } +} diff --git a/gcc/testsuite/g++.dg/cpp23/narrowing-bool1.C b/gcc/testsuite/g++.dg/cpp23/narrowing-bool1.C new file mode 100644 index 0000000..54906c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/narrowing-bool1.C @@ -0,0 +1,22 @@ +// P1401R5: Narrowing contextual conversions to bool +// { dg-do compile { target c++11 } } + +void f() noexcept(sizeof(char[2])); // { dg-error "narrowing" } conversion of value 2 to type bool +void g() noexcept(sizeof(char)); // OK, conversion of value 1 to type bool is non-narrowing + +#if __cpp_conditional_explicit +struct S { + explicit(sizeof(char[2])) S(char); // { dg-error "narrowing" "" { target c++20 } } + explicit(sizeof(char)) S(bool); // OK, conversion of value 1 to type bool is non-narrowing +}; +#endif + +static_assert(sizeof(int[2]), ""); // OK, narrowing allowed + +#if __cpp_if_constexpr +int main() +{ + if constexpr (sizeof(int[2])) // OK, narrowing allowed + {} +} +#endif diff --git a/gcc/testsuite/g++.dg/cpp23/whitespace-splice1.C b/gcc/testsuite/g++.dg/cpp23/whitespace-splice1.C new file mode 100644 index 0000000..f115ce0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/whitespace-splice1.C @@ -0,0 +1,15 @@ +// Tests from P2223R2 +// { dg-additional-options -w } +// { dg-do compile { target c++11 } } + +constexpr auto str = "\ +"; + +static_assert(__builtin_strlen(str) == 0, ""); + +constexpr int i = 1 + // \ + + 42 + ; + +static_assert(i == 1, ""); diff --git a/gcc/testsuite/g++.dg/cpp2a/explicit18.C b/gcc/testsuite/g++.dg/cpp2a/explicit18.C new file mode 100644 index 0000000..c8916fa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/explicit18.C @@ -0,0 +1,23 @@ +// PR c++/100065 +// { dg-do compile { target c++20 } } + +template<bool B> +struct bool_constant { + static constexpr bool value = B; + constexpr operator bool() const { return value; } +}; + +using true_type = bool_constant<true>; +using false_type = bool_constant<false>; + +template<bool> +struct X { + template<typename T> + X(T); +}; + +template<bool b> +explicit(b) X(bool_constant<b>) -> X<b>; + +X false_ = false_type{}; // OK +X true_ = true_type{}; // { dg-error "explicit deduction guide" } diff --git a/gcc/testsuite/g++.dg/diagnostic/enum3.C b/gcc/testsuite/g++.dg/diagnostic/enum3.C new file mode 100644 index 0000000..d51aa8a --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/enum3.C @@ -0,0 +1,9 @@ +// PR c++/100879 +// { dg-additional-options -Werror=sign-compare } + +enum e1 { e1val }; +enum e2 { e3val }; + +int main( int, char * [] ) { + if ( e1val == e3val ) return 1; // { dg-warning -Wenum-compare } +} diff --git a/gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C b/gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C index 4ede799..326520e 100644 --- a/gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C +++ b/gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C @@ -1,12 +1,12 @@ /* { dg-options "-fdiagnostics-show-caret -std=c++11" } */ -const void *s = u8"a" u"b"; // { dg-error "24: non-standard concatenation" } +const void *s = u8"a" u"b"; // { dg-error "24: concatenation" } /* { dg-begin-multiline-output "" } const void *s = u8"a" u"b"; ~~~~~ ^~~~ { dg-end-multiline-output "" } */ -const void *s2 = u"a" u"b" u8"c"; // { dg-error "30: non-standard concatenation" } +const void *s2 = u"a" u"b" u8"c"; // { dg-error "30: concatenation" } /* { dg-begin-multiline-output "" } const void *s2 = u"a" u"b" u8"c"; ~~~~ ^~~~~ @@ -16,7 +16,7 @@ const void *s2 = u"a" u"b" u8"c"; // { dg-error "30: non-standard concatenati const void *s3 = TEST_U8_LITERAL u8"b"; -const void *s4 = TEST_U8_LITERAL u"b"; // { dg-error "34: non-standard concatenation" } +const void *s4 = TEST_U8_LITERAL u"b"; // { dg-error "34: concatenation" } /* { dg-begin-multiline-output "" } const void *s4 = TEST_U8_LITERAL u"b"; ^~~~ diff --git a/gcc/testsuite/g++.dg/ext/utf-badconcat.C b/gcc/testsuite/g++.dg/ext/utf-badconcat.C index 4079b83..550e0da 100644 --- a/gcc/testsuite/g++.dg/ext/utf-badconcat.C +++ b/gcc/testsuite/g++.dg/ext/utf-badconcat.C @@ -4,15 +4,15 @@ const void *s0 = u"a" "b"; const void *s1 = "a" u"b"; -const void *s2 = u"a" U"b"; /* { dg-error "non-standard concatenation" } */ -const void *s3 = U"a" u"b"; /* { dg-error "non-standard concatenation" } */ -const void *s4 = u"a" L"b"; /* { dg-error "non-standard concatenation" } */ -const void *s5 = L"a" u"b"; /* { dg-error "non-standard concatenation" } */ +const void *s2 = u"a" U"b"; /* { dg-error "concatenation" } */ +const void *s3 = U"a" u"b"; /* { dg-error "concatenation" } */ +const void *s4 = u"a" L"b"; /* { dg-error "concatenation" } */ +const void *s5 = L"a" u"b"; /* { dg-error "concatenation" } */ const void *s6 = u"a" u"b"; const void *s7 = U"a" "b"; const void *s8 = "a" U"b"; -const void *s9 = U"a" L"b"; /* { dg-error "non-standard concatenation" } */ -const void *sa = L"a" U"b"; /* { dg-error "non-standard concatenation" } */ +const void *s9 = U"a" L"b"; /* { dg-error "concatenation" } */ +const void *sa = L"a" U"b"; /* { dg-error "concatenation" } */ const void *sb = U"a" U"b"; const void *sc = L"a" "b"; const void *sd = "a" L"b"; diff --git a/gcc/testsuite/g++.dg/ext/utf-badconcat2.C b/gcc/testsuite/g++.dg/ext/utf-badconcat2.C index 0d3fe33..535d926 100644 --- a/gcc/testsuite/g++.dg/ext/utf-badconcat2.C +++ b/gcc/testsuite/g++.dg/ext/utf-badconcat2.C @@ -4,11 +4,11 @@ const void *s0 = u8"a" "b"; const void *s1 = "a" u8"b"; const void *s2 = u8"a" u8"b"; -const void *s3 = u8"a" u"b"; // { dg-error "non-standard concatenation" } -const void *s4 = u"a" u8"b"; // { dg-error "non-standard concatenation" } -const void *s5 = u8"a" U"b"; // { dg-error "non-standard concatenation" } -const void *s6 = U"a" u8"b"; // { dg-error "non-standard concatenation" } -const void *s7 = u8"a" L"b"; // { dg-error "non-standard concatenation" } -const void *s8 = L"a" u8"b"; // { dg-error "non-standard concatenation" } +const void *s3 = u8"a" u"b"; // { dg-error "concatenation" } +const void *s4 = u"a" u8"b"; // { dg-error "concatenation" } +const void *s5 = u8"a" U"b"; // { dg-error "concatenation" } +const void *s6 = U"a" u8"b"; // { dg-error "concatenation" } +const void *s7 = u8"a" L"b"; // { dg-error "concatenation" } +const void *s8 = L"a" u8"b"; // { dg-error "concatenation" } int main () {} diff --git a/gcc/testsuite/g++.dg/gomp/doacross-2.C b/gcc/testsuite/g++.dg/gomp/doacross-2.C new file mode 100644 index 0000000..1fd6357 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/doacross-2.C @@ -0,0 +1,16 @@ +// PR c++/100957 +// { dg-do compile } + +struct S { + S () + { + #pragma omp for ordered(2) + for (int i = 0; i < 32; ++i) + for (int j = 0; j < 32; ++j) + { + #pragma omp ordered depend(source) + ; + #pragma omp ordered depend(sink: i - 1, j - 1) + } + } +}; diff --git a/gcc/testsuite/gcc.dg/analyzer/bitfields-1.c b/gcc/testsuite/gcc.dg/analyzer/bitfields-1.c new file mode 100644 index 0000000..8bbe76b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/bitfields-1.c @@ -0,0 +1,144 @@ +#include "analyzer-decls.h" + +typedef unsigned char u8; +typedef unsigned __INT16_TYPE__ u16; +typedef unsigned __INT32_TYPE__ u32; + +struct st1 +{ + u16 nonzero_offset; + unsigned int f0 : 1; + unsigned int f1 : 1; + unsigned int f2 : 1; + unsigned int f3 : 1; + unsigned int f4 : 1; + unsigned int f5 : 1; + unsigned int f6 : 1; + unsigned int f7 : 1; +}; + +void test_1 (void) +{ + struct st1 s; + s.f0 = 0; + __analyzer_eval (s.f0 == 0); /* { dg-warning "TRUE" } */ + s.f0 = 1; + __analyzer_eval (s.f0 == 1); /* { dg-warning "TRUE" } */ + + s.f1 = 0; + __analyzer_eval (s.f1 == 0); /* { dg-warning "TRUE" } */ + s.f1 = 1; + __analyzer_eval (s.f1 == 1); /* { dg-warning "TRUE" } */ + + /* etc */ + + s.f6 = 0; + __analyzer_eval (s.f6 == 0); /* { dg-warning "TRUE" } */ + s.f6 = 1; + __analyzer_eval (s.f6 == 1); /* { dg-warning "TRUE" } */ + + s.f7 = 0; + __analyzer_eval (s.f7 == 0); /* { dg-warning "TRUE" } */ + s.f7 = 1; + __analyzer_eval (s.f7 == 1); /* { dg-warning "TRUE" } */ +}; + +void test_2 (_Bool v0, _Bool v1, _Bool v2, _Bool v3, + _Bool v4, _Bool v5, _Bool v6, _Bool v7) +{ + struct st1 s; + s.f0 = v0; + s.f1 = v1; + s.f2 = v2; + s.f3 = v3; + s.f4 = v4; + s.f5 = v5; + s.f6 = v6; + s.f7 = v7; + + __analyzer_eval (s.f0 == v0); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f1 == v1); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f2 == v2); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f3 == v3); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f4 == v4); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f5 == v5); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f6 == v6); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f7 == v7); /* { dg-warning "TRUE" } */ +}; + +struct st3 +{ + unsigned int f01 : 2; + unsigned int f23 : 2; + unsigned int f34 : 2; + unsigned int f56 : 2; +}; + +void test_3 (void) +{ + struct st3 s; + s.f01 = 0; + __analyzer_eval (s.f01 == 0); /* { dg-warning "TRUE" } */ + s.f01 = 1; + __analyzer_eval (s.f01 == 1); /* { dg-warning "TRUE" } */ + s.f01 = 2; + __analyzer_eval (s.f01 == 2); /* { dg-warning "TRUE" } */ + s.f01 = 3; + __analyzer_eval (s.f01 == 3); /* { dg-warning "TRUE" } */ + + /* etc */ + + s.f56 = 0; + __analyzer_eval (s.f56 == 0); /* { dg-warning "TRUE" } */ + s.f56 = 1; + __analyzer_eval (s.f56 == 1); /* { dg-warning "TRUE" } */ + s.f56 = 2; + __analyzer_eval (s.f56 == 2); /* { dg-warning "TRUE" } */ + s.f56 = 3; + __analyzer_eval (s.f56 == 3); /* { dg-warning "TRUE" } */ +}; + +/* A signed bitfield. */ + +struct st4 +{ + signed int f012 : 3; + signed int f345 : 3; +}; + +void test_4 (void) +{ + struct st4 s; + s.f345 = -4; + __analyzer_eval (s.f345 == -4); /* { dg-warning "TRUE" } */ + s.f345 = -3; + __analyzer_eval (s.f345 == -3); /* { dg-warning "TRUE" } */ + s.f345 = -2; + __analyzer_eval (s.f345 == -2); /* { dg-warning "TRUE" } */ + s.f345 = -1; + __analyzer_eval (s.f345 == -1); /* { dg-warning "TRUE" } */ + s.f345 = 0; + __analyzer_eval (s.f345 == 0); /* { dg-warning "TRUE" } */ + s.f345 = 1; + __analyzer_eval (s.f345 == 1); /* { dg-warning "TRUE" } */ + s.f345 = 2; + __analyzer_eval (s.f345 == 2); /* { dg-warning "TRUE" } */ + s.f345 = 3; + __analyzer_eval (s.f345 == 3); /* { dg-warning "TRUE" } */ +}; + +/* A zero bitfield to break up padding. */ + +struct st5 +{ + unsigned f0 : 5; + unsigned :0; + unsigned f1 : 16; +}; + +void test_5 (void) +{ + struct st5 s; + s.f1 = 0xcafe; + __analyzer_eval (s.f1 == 0xcafe); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c index c0f5463..4a62a0e 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c @@ -934,24 +934,20 @@ void test_43 (void) struct sbits { - int b0 : 1; - int b123 : 3; - int b456 : 3; - int b7 : 1; + signed int b0 : 1; + signed int b123 : 3; + signed int b456 : 3; + signed int b7 : 1; }; void test_44 (void) { struct sbits bits; - bits.b0 = 1; - __analyzer_eval (bits.b0 == 1); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "FALSE" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): ^^^^ + bits.b0 = -1; + __analyzer_eval (bits.b0 == -1); /* { dg-warning "TRUE" } */ - bits.b456 = 5; - __analyzer_eval (bits.b456 == 5); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "FALSE" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): ^^^^ + bits.b456 = -4; + __analyzer_eval (bits.b456 == -4); /* { dg-warning "TRUE" } */ }; struct ubits @@ -962,20 +958,14 @@ struct ubits unsigned int b7 : 1; }; -/* FIXME: this requires BIT_FIELD_REF to work. */ - void test_45 (void) { struct ubits bits; bits.b0 = 1; - __analyzer_eval (bits.b0 == 1); /* { dg-warning "TRUE" "desired, PR99212" { xfail { ! { cris-*-* } } } } */ - /* { dg-warning "UNKNOWN" "status quo, PR99212" { target { *-*-* } xfail { cris-*-* } } .-1 } */ - // TODO(xfail): ^^^^ + __analyzer_eval (bits.b0 == 1); /* { dg-warning "TRUE" } */ bits.b456 = 5; - __analyzer_eval (bits.b456 == 5); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): ^^^^ + __analyzer_eval (bits.b456 == 5); /* { dg-warning "TRUE" } */ }; extern const char *char_ptr; diff --git a/gcc/testsuite/gcc.dg/pr100887.c b/gcc/testsuite/gcc.dg/pr100887.c index de6b3ef..027025f 100644 --- a/gcc/testsuite/gcc.dg/pr100887.c +++ b/gcc/testsuite/gcc.dg/pr100887.c @@ -1,6 +1,6 @@ /* PR target/100887 */ /* { dg-do compile } */ -/* { dg-options "" } */ +/* { dg-options "-Wno-psabi -w" } */ /* { dg-additional-options "-mavx512f" { target { i?86-*-* x86_64-*-* } } } */ typedef unsigned long long __attribute__((__vector_size__ (2 * sizeof (long long)))) U; diff --git a/gcc/testsuite/gcc.dg/torture/pr100923.c b/gcc/testsuite/gcc.dg/torture/pr100923.c new file mode 100644 index 0000000..05a6341 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100923.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +int a = 1, b, c, *d = &a, *e = &a, f; +void g(int h) {} +void k(int *l) +{ + int ***j; + if (c) + { + *j = &l; + ***j; + } + g(*l); + *e = f; + if (*l) + { + int i = b / a; + a = i; + } +} +int main() +{ + k(d); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c index a2770e5..2e86620 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c @@ -1,9 +1,9 @@ /* PR tree-optimization/96928 */ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-phiopt2" } */ +/* { dg-options "-O2 -fdump-tree-phiopt2 -fdump-tree-optimized" } */ /* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */ /* { dg-final { scan-tree-dump-times " = ~c_\[0-9]*\\\(D\\\);" 1 "phiopt2" } } */ -/* { dg-final { scan-tree-dump-times " = ~" 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = ~" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */ /* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100936.c b/gcc/testsuite/gcc.target/i386/pr100936.c new file mode 100644 index 0000000..c076cbb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr100936.c @@ -0,0 +1,34 @@ +/* PR target/100936 */ +/* { dg-do assemble } */ +/* { dg-options "-O2" } */ + +__seg_gs int var; + +static int +*foo (void) +{ + int *addr; + + asm ("lea %p1, %0" : "=r"(addr) : "m"(var)); + + return addr; +} + +static int +bar (int *addr) +{ + int val; + + asm ("mov %%gs:%1, %0" : "=r"(val) : "m"(*addr)); + + return val; +} + +int +baz (void) +{ + int *addr = foo(); + int val = bar (addr); + + return val; +} diff --git a/gcc/testsuite/gcc.target/i386/pr100951.c b/gcc/testsuite/gcc.target/i386/pr100951.c new file mode 100644 index 0000000..16d8baf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr100951.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -march=x86-64" } */ + +typedef short __attribute__((__vector_size__ (8 * sizeof (short)))) V; +V v, w; + +void +foo (void) +{ + w = __builtin_shuffle (v != v, 0 < (V) {}, (V) {192} >> 5); +} + +/* { dg-final { scan-assembler-not "punpcklwd" } } */ +/* { dg-final { scan-assembler-not "pshufd" } } */ +/* { dg-final { scan-assembler-times "pxor\[\\t \]%xmm\[0-9\]+, %xmm\[0-9\]+" 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/float128-call.c b/gcc/testsuite/gcc.target/powerpc/float128-call.c index 5895416..a1f09df 100644 --- a/gcc/testsuite/gcc.target/powerpc/float128-call.c +++ b/gcc/testsuite/gcc.target/powerpc/float128-call.c @@ -21,5 +21,5 @@ TYPE one (void) { return ONE; } void store (TYPE a, TYPE *p) { *p = a; } -/* { dg-final { scan-assembler "lxvd2x 34" } } */ -/* { dg-final { scan-assembler "stxvd2x 34" } } */ +/* { dg-final { scan-assembler "lvx 2" } } */ +/* { dg-final { scan-assembler "stvx 2" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr100085.c b/gcc/testsuite/gcc.target/powerpc/pr100085.c new file mode 100644 index 0000000..7d8b147 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr100085.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mdejagnu-cpu=power8" } */ + +typedef __vector unsigned __int128 vui128_t; + +typedef union +{ + __float128 vf1; + vui128_t vx1; +} __VF_128; + +vui128_t +vec_xfer_bin128_2_vui128t (__float128 f128) +{ + __VF_128 vunion; + vunion.vf1 = f128; + return (vunion.vx1); +} + +/* { dg-final { scan-assembler-not {\mxxpermdi\M} } } */ +/* { dg-final { scan-assembler-not {\mstxvd2x\M} } } */ +/* { dg-final { scan-assembler-not {\mlxvd2x\M} } } */ + diff --git a/gcc/testsuite/gfortran.dg/gomp/loop-1.f90 b/gcc/testsuite/gfortran.dg/gomp/loop-1.f90 index c112030..7308567 100644 --- a/gcc/testsuite/gfortran.dg/gomp/loop-1.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/loop-1.f90 @@ -46,10 +46,9 @@ end do end -! TODO: xfailed due to PR99928: -! { dg-final { scan-tree-dump-times "#pragma omp target map\\(tofrom:r\\)\[\r\n\]" 2 "original" { xfail *-*-* } } } -! { dg-final { scan-tree-dump-times "#pragma omp parallel\[\r\n\]" 2 "original" } } -! { dg-final { scan-tree-dump-times "#pragma omp teams\[\r\n\]" 2 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp target map\\(tofrom:i\\) map\\(tofrom:r\\)\[\r\n\]" 2 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp parallel shared\\(i\\) shared\\(r\\)\[\r\n\]" 2 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp teams shared\\(i\\) shared\\(r\\)\[\r\n\]" 2 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp loop private\\(q\\) lastprivate\\(i\\) reduction\\(\\+:r\\) order\\(concurrent\\) collapse\\(2\\) bind\\(parallel\\)" 1 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp loop private\\(q\\) lastprivate\\(i\\) reduction\\(\\+:r\\) order\\(concurrent\\) collapse\\(2\\) bind\\(teams\\)" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 index 361e0da..14164b9 100644 --- a/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 @@ -49,7 +49,7 @@ subroutine bar(n, m, u) end -! { dg-final { scan-tree-dump-times "#pragma omp teams firstprivate\\(a1\\) firstprivate\\(b1\\) shared\\(u\\) default\\(none\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp teams firstprivate\\(a1\\) firstprivate\\(b1\\) shared\\(u\\) shared\\(d1\\) default\\(none\\)" 1 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp distribute lastprivate\\(d1\\)" 1 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp parallel firstprivate\\(a1\\) firstprivate\\(b1\\) lastprivate\\(d1\\) shared\\(u\\) default\\(none\\)" 1 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp for nowait" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/pr100965.f90 b/gcc/testsuite/gfortran.dg/gomp/pr100965.f90 new file mode 100644 index 0000000..9044547 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr100965.f90 @@ -0,0 +1,16 @@ +! PR fortran/100965 +! { dg-do compile } + +implicit none + character(len=:), allocatable :: s + logical :: l + !$omp target map(from: l) + l = allocated (s) + !$omp end target + if (l) stop 1 + + !$omp target map(from: l) + l = allocated (s) + !$omp end target + if (l) stop 2 +end diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-1.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-1.f90 index e5be42f..9a59065 100644 --- a/gcc/testsuite/gfortran.dg/gomp/pr99928-1.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-1.f90 @@ -83,14 +83,14 @@ subroutine bar () !$omp parallel master firstprivate (f09) default(none) f09 = f09 + 1 !$omp end parallel master - ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(f10\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(f10\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(f10\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(f10\\)" "gimple" } } !$omp parallel master taskloop firstprivate (f10) default(none) do i = 1, 64 f10 = f10 + 1 end do - ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(f11\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(f11\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(f11\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(f11\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f11\\)" "gimple" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-2.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-2.f90 index fe8a715..4a5b549 100644 --- a/gcc/testsuite/gfortran.dg/gomp/pr99928-2.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-2.f90 @@ -79,7 +79,7 @@ subroutine bar () !$omp parallel loop lastprivate (j00) default(none) do j00 = 1, 64 end do - ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l08\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l08\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l08\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(l08\\)" "gimple" } } ! NOTE: This is implementation detail. ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l08\\)" "gimple" } } @@ -87,7 +87,7 @@ subroutine bar () do i = 1, 64 l08 = i end do - ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l09\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l09\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l09\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(l09\\)" "gimple" } } ! NOTE: This is implementation detail. ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l09\\)" "gimple" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90 index 854b9d6..82bb893 100644 --- a/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90 @@ -59,7 +59,7 @@ subroutine bar () l04 = i end do !$omp end parallel do simd - ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l05\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l05\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l05\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l05\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l05\\)" "gimple" } } @@ -68,7 +68,7 @@ subroutine bar () do i = 1, 64 l05 = i end do - ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l06\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l06\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l06\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l06\\)" "gimple" } } @@ -95,8 +95,8 @@ subroutine bar () !$omp section l07 = 2 !$omp end parallel sections - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l08" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l08\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l08" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l08\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l08\\)" "gimple" } } ! FIXME: This should be on for instead. ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l08\\)" "gimple" } } ! FIXME: This should be on for instead. ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l08\\)" "gimple" } } ! FIXME. @@ -106,8 +106,8 @@ subroutine bar () l08 = i end do !$omp end target parallel do - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l09" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l09\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l09" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l09\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l09\\)" "gimple" } } ! FIXME: This should be on for instead. ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l09\\)" "gimple" } } ! FIXME: This should be on for instead. ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l09\\)" "gimple" } } ! FIXME. @@ -118,8 +118,8 @@ subroutine bar () do i = 1, 64 l09 = i end do - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l10" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l10\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l10" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l10\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l10\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l10\\)" "gimple" } } !$omp target simd firstprivate (l10) lastprivate (l10) ! defaultmap(none) diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-8.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-8.f90 index a5b028b..c5d1eb7 100644 --- a/gcc/testsuite/gfortran.dg/gomp/pr99928-8.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-8.f90 @@ -87,14 +87,14 @@ subroutine bar () !$omp parallel master reduction(+:r09) default(none) r09 = r09 + 1 !$omp end parallel master - ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r10\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r10\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:r10\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:r10\\)" "gimple" } } !$omp parallel master taskloop reduction(+:r10) default(none) do i = 1, 64 r10 = r10 + 1 end do - ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r11\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r11\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:r11\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:r11\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r11\\)" "gimple" } } @@ -110,22 +110,22 @@ subroutine bar () !$omp section r12 = r12 + 1 !$omp end parallel sections - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r13" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r13\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r13" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r13\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r13\\)" "gimple" } } !$omp target parallel reduction(+:r13) default(none) ! defaultmap(none) r13 = r13 + 1 !$omp end target parallel - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r14" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r14\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r14" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r14\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r14\\)" "gimple" } } ! FIXME: This should be on for instead. ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r14\\)" "gimple" } } ! FIXME. !$omp target parallel do reduction(+:r14) default(none) ! defaultmap(none) do i = 1, 64 r14 = r14 + 1 end do - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r15" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r15\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r15" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r15\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r15\\)" "gimple" } } ! FIXME: This should be on for instead. ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r15\\)" "gimple" } } ! FIXME. ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r15\\)" "gimple" } } @@ -133,8 +133,8 @@ subroutine bar () do i = 1, 64 r15 = r15 + 1 end do - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r16" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r16\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r16" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r16\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r16\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r16\\)" "gimple" } } ! NOTE: This is implementation detail. ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r16\\)" "gimple" } } ! NOTE: This is implementation detail. @@ -142,22 +142,22 @@ subroutine bar () do i = 1, 64 r16 = r16 + 1 end do - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r17" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r17\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r17" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r17\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r17\\)" "gimple" } } !$omp target teams reduction(+:r17) default(none) ! defaultmap(none) r17 = r17 + 1 !$omp end target teams - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r18" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r18\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r18" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r18\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r18\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r18\\)" "gimple" } } !$omp target teams distribute reduction(+:r18) default(none) ! defaultmap(none) do i = 1, 64 r18 = r18 + 1 end do - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r19" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r19\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r19" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r19\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } } ! FIXME: This should be on for instead. @@ -166,8 +166,8 @@ subroutine bar () do i = 1, 64 r19 = r19 + 1 end do - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r20" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r20\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r20" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r20\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } } ! FIXME: This should be on for instead. @@ -177,8 +177,8 @@ subroutine bar () do i = 1, 64 r20 = r20 + 1 end do - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r21" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r21\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r21" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r21\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r21\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r21\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r21\\)" "gimple" } } @@ -186,8 +186,8 @@ subroutine bar () do i = 1, 64 r21 = r21 + 1 end do - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r22" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r22\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r22" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r22\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(r22\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*reduction\\(\\+:r22\\)" "gimple" } } ! NOTE: This is implementation detail. ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r22\\)" "gimple" } } ! NOTE: This is implementation detail. @@ -197,8 +197,8 @@ subroutine bar () do i = 1, 64 r22 = r22 + 1 end do - ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r23" "gimple" { xfail *-*-* } } } - ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r23\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r23" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r23\\)" "gimple" } } ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r23\\)" "gimple" } } !$omp target simd reduction(+:r23) ! defaultmap(none) do i = 1, 64 diff --git a/gcc/testsuite/gfortran.dg/gomp/scan-5.f90 b/gcc/testsuite/gfortran.dg/gomp/scan-5.f90 index a3789a5..df12f9f 100644 --- a/gcc/testsuite/gfortran.dg/gomp/scan-5.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/scan-5.f90 @@ -13,6 +13,6 @@ integer function foo(a,b, n) result(r) end do end -! { dg-final { scan-tree-dump-times "#pragma omp parallel firstprivate\\(a\\) firstprivate\\(b\\) default\\(none\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp parallel firstprivate\\(a\\) firstprivate\\(b\\) shared\\(r\\) default\\(none\\)" 1 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(inscan,\\\+:r\\) nowait" 1 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp scan inclusive\\(r\\)" 1 "original" } } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 4250fd8..9eb08d2 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1458,7 +1458,8 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data) || OMP_CLAUSE_CODE (*tp) == OMP_CLAUSE_DEPEND)) { tree t = OMP_CLAUSE_DECL (*tp); - if (TREE_CODE (t) == TREE_LIST + if (t + && TREE_CODE (t) == TREE_LIST && TREE_PURPOSE (t) && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) { diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 969b868..76f4e7e 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "cfghooks.h" #include "tree-pass.h" #include "ssa.h" +#include "tree-ssa.h" #include "optabs-tree.h" #include "insn-config.h" #include "gimple-pretty-print.h" @@ -63,8 +64,6 @@ static bool minmax_replacement (basic_block, basic_block, edge, edge, gphi *, tree, tree); static bool abs_replacement (basic_block, basic_block, edge, edge, gphi *, tree, tree); -static bool xor_replacement (basic_block, basic_block, - edge, edge, gphi *, tree, tree); static bool spaceship_replacement (basic_block, basic_block, edge, edge, gphi *, tree, tree); static bool cond_removal_in_popcount_clz_ctz_pattern (basic_block, basic_block, @@ -353,9 +352,6 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) cfgchanged = true; else if (!early_p - && xor_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) - cfgchanged = true; - else if (!early_p && cond_removal_in_popcount_clz_ctz_pattern (bb, bb1, e1, e2, phi, arg0, arg1)) @@ -801,14 +797,51 @@ match_simplify_replacement (basic_block cond_bb, basic_block middle_bb, edge true_edge, false_edge; gimple_seq seq = NULL; tree result; - - if (!empty_block_p (middle_bb)) - return false; + gimple *stmt_to_move = NULL; /* Special case A ? B : B as this will always simplify to B. */ if (operand_equal_for_phi_arg_p (arg0, arg1)) return false; + /* If the basic block only has a cheap preparation statement, + allow it and move it once the transformation is done. */ + if (!empty_block_p (middle_bb)) + { + stmt_to_move = last_and_only_stmt (middle_bb); + if (!stmt_to_move) + return false; + + if (gimple_vuse (stmt_to_move)) + return false; + + if (gimple_could_trap_p (stmt_to_move) + || gimple_has_side_effects (stmt_to_move)) + return false; + + if (gimple_uses_undefined_value_p (stmt_to_move)) + return false; + + /* Allow assignments and not no calls. + As const calls don't match any of the above, yet they could + still have some side-effects - they could contain + gimple_could_trap_p statements, like floating point + exceptions or integer division by zero. See PR70586. + FIXME: perhaps gimple_has_side_effects or gimple_could_trap_p + should handle this. */ + if (!is_gimple_assign (stmt_to_move)) + return false; + + tree lhs = gimple_assign_lhs (stmt_to_move); + gimple *use_stmt; + use_operand_p use_p; + + /* Allow only a statement which feeds into the phi. */ + if (!lhs || TREE_CODE (lhs) != SSA_NAME + || !single_imm_use (lhs, &use_p, &use_stmt) + || use_stmt != phi) + return false; + } + /* At this point we know we have a GIMPLE_COND with two successors. One successor is BB, the other successor is an empty block which falls through into BB. @@ -844,7 +877,17 @@ match_simplify_replacement (basic_block cond_bb, basic_block middle_bb, return false; gsi = gsi_last_bb (cond_bb); - + if (stmt_to_move) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "statement un-sinked:\n"); + print_gimple_stmt (dump_file, stmt_to_move, 0, + TDF_VOPS|TDF_MEMSYMS); + } + gimple_stmt_iterator gsi1 = gsi_for_stmt (stmt_to_move); + gsi_move_before (&gsi1, &gsi); + } if (seq) gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); @@ -2592,109 +2635,6 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb, return true; } -/* Optimize x < 0 ? ~y : y into (x >> (prec-1)) ^ y. */ - -static bool -xor_replacement (basic_block cond_bb, basic_block middle_bb, - edge e0 ATTRIBUTE_UNUSED, edge e1, - gphi *phi, tree arg0, tree arg1) -{ - if (!INTEGRAL_TYPE_P (TREE_TYPE (arg1))) - return false; - - /* OTHER_BLOCK must have only one executable statement which must have the - form arg0 = ~arg1 or arg1 = ~arg0. */ - - gimple *assign = last_and_only_stmt (middle_bb); - /* If we did not find the proper one's complement assignment, then we cannot - optimize. */ - if (assign == NULL) - return false; - - /* If we got here, then we have found the only executable statement - in OTHER_BLOCK. If it is anything other than arg = ~arg1 or - arg1 = ~arg0, then we cannot optimize. */ - if (!is_gimple_assign (assign)) - return false; - - if (gimple_assign_rhs_code (assign) != BIT_NOT_EXPR) - return false; - - tree lhs = gimple_assign_lhs (assign); - tree rhs = gimple_assign_rhs1 (assign); - - /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */ - if (!(lhs == arg0 && rhs == arg1) && !(lhs == arg1 && rhs == arg0)) - return false; - - gimple *cond = last_stmt (cond_bb); - tree result = PHI_RESULT (phi); - - /* Only relationals comparing arg[01] against zero are interesting. */ - enum tree_code cond_code = gimple_cond_code (cond); - if (cond_code != LT_EXPR && cond_code != GE_EXPR) - return false; - - /* Make sure the conditional is x OP 0. */ - tree clhs = gimple_cond_lhs (cond); - if (TREE_CODE (clhs) != SSA_NAME - || !INTEGRAL_TYPE_P (TREE_TYPE (clhs)) - || TYPE_UNSIGNED (TREE_TYPE (clhs)) - || TYPE_PRECISION (TREE_TYPE (clhs)) != TYPE_PRECISION (TREE_TYPE (arg1)) - || !integer_zerop (gimple_cond_rhs (cond))) - return false; - - /* We need to know which is the true edge and which is the false - edge so that we know if have xor or inverted xor. */ - edge true_edge, false_edge; - extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge); - - /* For GE_EXPR, if the true edge goes to OTHER_BLOCK, then we - will need to invert the result. Similarly for LT_EXPR if - the false edge goes to OTHER_BLOCK. */ - edge e; - if (cond_code == GE_EXPR) - e = true_edge; - else - e = false_edge; - - bool invert = e->dest == middle_bb; - - result = duplicate_ssa_name (result, NULL); - - gimple_stmt_iterator gsi = gsi_last_bb (cond_bb); - - int prec = TYPE_PRECISION (TREE_TYPE (clhs)); - gimple *new_stmt - = gimple_build_assign (make_ssa_name (TREE_TYPE (clhs)), RSHIFT_EXPR, clhs, - build_int_cst (integer_type_node, prec - 1)); - gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); - - if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (clhs))) - { - new_stmt = gimple_build_assign (make_ssa_name (TREE_TYPE (result)), - NOP_EXPR, gimple_assign_lhs (new_stmt)); - gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); - } - lhs = gimple_assign_lhs (new_stmt); - - if (invert) - { - new_stmt = gimple_build_assign (make_ssa_name (TREE_TYPE (result)), - BIT_NOT_EXPR, rhs); - gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); - rhs = gimple_assign_lhs (new_stmt); - } - - new_stmt = gimple_build_assign (result, BIT_XOR_EXPR, lhs, rhs); - gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT); - - replace_phi_edge_with_variable (cond_bb, e1, phi, result); - - /* Note that we optimized this PHI. */ - return true; -} - /* Auxiliary functions to determine the set of memory accesses which can't trap because they are preceded by accesses to the same memory portion. We do that for MEM_REFs, so we only need to track diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index e876121..64e3a70 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -553,7 +553,7 @@ vuse_ssa_val (tree x) return x; } -/* Similar to the above but used as callback for walk_non_aliases_vuses +/* Similar to the above but used as callback for walk_non_aliased_vuses and thus should stop at unvisited VUSE to not walk across region boundaries. */ @@ -1579,8 +1579,8 @@ contains_storage_order_barrier_p (vec<vn_reference_op_s> ops) the vector passed in is returned. *VALUEIZED_ANYTHING will specify whether any operands were valueized. */ -static vec<vn_reference_op_s> -valueize_refs_1 (vec<vn_reference_op_s> orig, bool *valueized_anything, +static void +valueize_refs_1 (vec<vn_reference_op_s> *orig, bool *valueized_anything, bool with_avail = false) { vn_reference_op_t vro; @@ -1588,7 +1588,7 @@ valueize_refs_1 (vec<vn_reference_op_s> orig, bool *valueized_anything, *valueized_anything = false; - FOR_EACH_VEC_ELT (orig, i, vro) + FOR_EACH_VEC_ELT (*orig, i, vro) { if (vro->opcode == SSA_NAME || (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)) @@ -1627,16 +1627,16 @@ valueize_refs_1 (vec<vn_reference_op_s> orig, bool *valueized_anything, if (i > 0 && vro->op0 && TREE_CODE (vro->op0) == ADDR_EXPR - && orig[i - 1].opcode == MEM_REF) + && (*orig)[i - 1].opcode == MEM_REF) { - if (vn_reference_fold_indirect (&orig, &i)) + if (vn_reference_fold_indirect (orig, &i)) *valueized_anything = true; } else if (i > 0 && vro->opcode == SSA_NAME - && orig[i - 1].opcode == MEM_REF) + && (*orig)[i - 1].opcode == MEM_REF) { - if (vn_reference_maybe_forwprop_address (&orig, &i)) + if (vn_reference_maybe_forwprop_address (orig, &i)) *valueized_anything = true; } /* If it transforms a non-constant ARRAY_REF into a constant @@ -1654,15 +1654,13 @@ valueize_refs_1 (vec<vn_reference_op_s> orig, bool *valueized_anything, off.to_shwi (&vro->off); } } - - return orig; } -static vec<vn_reference_op_s> -valueize_refs (vec<vn_reference_op_s> orig) +static void +valueize_refs (vec<vn_reference_op_s> *orig) { bool tem; - return valueize_refs_1 (orig, &tem); + valueize_refs_1 (orig, &tem); } static vec<vn_reference_op_s> shared_lookup_references; @@ -1679,8 +1677,7 @@ valueize_shared_reference_ops_from_ref (tree ref, bool *valueized_anything) return vNULL; shared_lookup_references.truncate (0); copy_reference_ops_from_ref (ref, &shared_lookup_references); - shared_lookup_references = valueize_refs_1 (shared_lookup_references, - valueized_anything); + valueize_refs_1 (&shared_lookup_references, valueized_anything); return shared_lookup_references; } @@ -1695,7 +1692,7 @@ valueize_shared_reference_ops_from_call (gcall *call) return vNULL; shared_lookup_references.truncate (0); copy_reference_ops_from_call (call, &shared_lookup_references); - shared_lookup_references = valueize_refs (shared_lookup_references); + valueize_refs (&shared_lookup_references); return shared_lookup_references; } @@ -2546,7 +2543,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE) { copy_reference_ops_from_ref (lhs, &lhs_ops); - lhs_ops = valueize_refs_1 (lhs_ops, &valueized_anything, true); + valueize_refs_1 (&lhs_ops, &valueized_anything, true); } vn_context_bb = saved_rpo_bb; ao_ref_init (&lhs_ref, lhs); @@ -3225,7 +3222,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, vr->operands.truncate (i + 1 + rhs.length ()); FOR_EACH_VEC_ELT (rhs, j, vro) vr->operands[i + 1 + j] = *vro; - vr->operands = valueize_refs (vr->operands); + valueize_refs (&vr->operands); if (old == shared_lookup_references) shared_lookup_references = vr->operands; vr->hashcode = vn_reference_compute_hash (vr); @@ -3526,8 +3523,9 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set, operands.address (), sizeof (vn_reference_op_s) * operands.length ()); - vr1.operands = operands = shared_lookup_references - = valueize_refs (shared_lookup_references); + bool valueized_p; + valueize_refs_1 (&shared_lookup_references, &valueized_p); + vr1.operands = shared_lookup_references; vr1.type = type; vr1.set = set; vr1.base_set = base_set; @@ -3543,13 +3541,31 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set, ao_ref r; unsigned limit = param_sccvn_max_alias_queries_per_access; vn_walk_cb_data data (&vr1, NULL_TREE, NULL, kind, true, NULL_TREE); + vec<vn_reference_op_s> ops_for_ref; + if (!valueized_p) + ops_for_ref = vr1.operands; + else + { + /* For ao_ref_from_mem we have to ensure only available SSA names + end up in base and the only convenient way to make this work + for PRE is to re-valueize with that in mind. */ + ops_for_ref.create (operands.length ()); + ops_for_ref.quick_grow (operands.length ()); + memcpy (ops_for_ref.address (), + operands.address (), + sizeof (vn_reference_op_s) + * operands.length ()); + valueize_refs_1 (&ops_for_ref, &valueized_p, true); + } if (ao_ref_init_from_vn_reference (&r, set, base_set, type, - vr1.operands)) + ops_for_ref)) *vnresult = ((vn_reference_t) walk_non_aliased_vuses (&r, vr1.vuse, true, vn_reference_lookup_2, vn_reference_lookup_3, vuse_valueize, limit, &data)); + if (ops_for_ref != shared_lookup_references) + ops_for_ref.release (); gcc_checking_assert (vr1.operands == shared_lookup_references); } @@ -3578,14 +3594,14 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind, { vec<vn_reference_op_s> operands; struct vn_reference_s vr1; - bool valuezied_anything; + bool valueized_anything; if (vnresult) *vnresult = NULL; vr1.vuse = vuse_ssa_val (vuse); vr1.operands = operands - = valueize_shared_reference_ops_from_ref (op, &valuezied_anything); + = valueize_shared_reference_ops_from_ref (op, &valueized_anything); vr1.type = TREE_TYPE (op); ao_ref op_ref; ao_ref_init (&op_ref, op); @@ -3601,11 +3617,18 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind, vn_reference_t wvnresult; ao_ref r; unsigned limit = param_sccvn_max_alias_queries_per_access; + auto_vec<vn_reference_op_s> ops_for_ref; + if (valueized_anything) + { + copy_reference_ops_from_ref (op, &ops_for_ref); + bool tem; + valueize_refs_1 (&ops_for_ref, &tem, true); + } /* Make sure to use a valueized reference if we valueized anything. Otherwise preserve the full reference for advanced TBAA. */ - if (!valuezied_anything + if (!valueized_anything || !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.base_set, - vr1.type, vr1.operands)) + vr1.type, ops_for_ref)) ao_ref_init (&r, op); vn_walk_cb_data data (&vr1, r.ref ? NULL_TREE : op, last_vuse_ptr, kind, tbaa_p, mask); @@ -3733,7 +3756,8 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s); vr1->value_id = value_id; vr1->vuse = vuse_ssa_val (vuse); - vr1->operands = valueize_refs (operands); + vr1->operands = operands; + valueize_refs (&vr1->operands); vr1->type = type; vr1->punned = false; vr1->set = set; diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index d9c0ac9..5f3f9fa 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -328,16 +328,22 @@ expand_vector_piecewise (gimple_stmt_iterator *gsi, elem_op_func f, if (!ret_type) ret_type = type; vec_alloc (v, (nunits + delta - 1) / delta); + bool constant_p = true; for (i = 0; i < nunits; i += delta, index = int_const_binop (PLUS_EXPR, index, part_width)) { tree result = f (gsi, inner_type, a, b, index, part_width, code, ret_type); + if (!CONSTANT_CLASS_P (result)) + constant_p = false; constructor_elt ce = {NULL_TREE, result}; v->quick_push (ce); } - return build_constructor (ret_type, v); + if (constant_p) + return build_vector_from_ctor (ret_type, v); + else + return build_constructor (ret_type, v); } /* Expand a vector operation to scalars with the freedom to use @@ -1105,6 +1111,7 @@ expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names) int nunits = nunits_for_known_piecewise_op (type); vec_alloc (v, nunits); + bool constant_p = true; for (int i = 0; i < nunits; i++) { tree aa, result; @@ -1129,6 +1136,8 @@ expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names) else aa = tree_vec_extract (gsi, cond_type, a, width, index); result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc); + if (!CONSTANT_CLASS_P (result)) + constant_p = false; constructor_elt ce = {NULL_TREE, result}; v->quick_push (ce); index = int_const_binop (PLUS_EXPR, index, width); @@ -1138,7 +1147,10 @@ expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names) comp_index = int_const_binop (PLUS_EXPR, comp_index, comp_width); } - constr = build_constructor (type, v); + if (constant_p) + constr = build_vector_from_ctor (type, v); + else + constr = build_constructor (type, v); gimple_assign_set_rhs_from_tree (gsi, constr); update_stmt (gsi_stmt (*gsi)); @@ -1578,6 +1590,7 @@ lower_vec_perm (gimple_stmt_iterator *gsi) "vector shuffling operation will be expanded piecewise"); vec_alloc (v, elements); + bool constant_p = true; for (i = 0; i < elements; i++) { si = size_int (i); @@ -1639,10 +1652,15 @@ lower_vec_perm (gimple_stmt_iterator *gsi) t = v0_val; } + if (!CONSTANT_CLASS_P (t)) + constant_p = false; CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t); } - constr = build_constructor (vect_type, v); + if (constant_p) + constr = build_vector_from_ctor (vect_type, v); + else + constr = build_constructor (vect_type, v); gimple_assign_set_rhs_from_tree (gsi, constr); update_stmt (gsi_stmt (*gsi)); } @@ -2014,6 +2032,7 @@ expand_vector_conversion (gimple_stmt_iterator *gsi) } vec_alloc (v, (nunits + delta - 1) / delta * 2); + bool constant_p = true; for (i = 0; i < nunits; i += delta, index = int_const_binop (PLUS_EXPR, index, part_width)) @@ -2024,12 +2043,19 @@ expand_vector_conversion (gimple_stmt_iterator *gsi) index); tree result = gimplify_build1 (gsi, code1, cretd_type, a); constructor_elt ce = { NULL_TREE, result }; + if (!CONSTANT_CLASS_P (ce.value)) + constant_p = false; v->quick_push (ce); ce.value = gimplify_build1 (gsi, code2, cretd_type, a); + if (!CONSTANT_CLASS_P (ce.value)) + constant_p = false; v->quick_push (ce); } - new_rhs = build_constructor (ret_type, v); + if (constant_p) + new_rhs = build_vector_from_ctor (ret_type, v); + else + new_rhs = build_constructor (ret_type, v); g = gimple_build_assign (lhs, new_rhs); gsi_replace (gsi, g, false); return; diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index ca1539e..cc734e0 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -164,8 +164,8 @@ vect_free_slp_tree (slp_tree node) dump_user_location_t _slp_instance::location () const { - if (root_stmt) - return root_stmt->stmt; + if (!root_stmts.is_empty ()) + return root_stmts[0]->stmt; else return SLP_TREE_SCALAR_STMTS (root)[0]->stmt; } @@ -178,6 +178,7 @@ vect_free_slp_instance (slp_instance instance) { vect_free_slp_tree (SLP_INSTANCE_TREE (instance)); SLP_INSTANCE_LOADS (instance).release (); + SLP_INSTANCE_ROOT_STMTS (instance).release (); instance->subgraph_entries.release (); instance->cost_vec.release (); free (instance); @@ -2503,7 +2504,7 @@ static bool vect_build_slp_instance (vec_info *vinfo, slp_instance_kind kind, vec<stmt_vec_info> &scalar_stmts, - stmt_vec_info root_stmt_info, + vec<stmt_vec_info> &root_stmt_infos, unsigned max_tree_size, unsigned *limit, scalar_stmts_to_slp_tree_map_t *bst_map, /* ??? We need stmt_info for group splitting. */ @@ -2564,7 +2565,7 @@ vect_build_slp_instance (vec_info *vinfo, SLP_INSTANCE_TREE (new_instance) = node; SLP_INSTANCE_UNROLLING_FACTOR (new_instance) = unrolling_factor; SLP_INSTANCE_LOADS (new_instance) = vNULL; - SLP_INSTANCE_ROOT_STMT (new_instance) = root_stmt_info; + SLP_INSTANCE_ROOT_STMTS (new_instance) = root_stmt_infos; SLP_INSTANCE_KIND (new_instance) = kind; new_instance->reduc_phis = NULL; new_instance->cost_vec = vNULL; @@ -2836,13 +2837,20 @@ vect_analyze_slp_instance (vec_info *vinfo, else gcc_unreachable (); + vec<stmt_vec_info> roots = vNULL; + if (kind == slp_inst_kind_ctor) + { + roots.create (1); + roots.quick_push (stmt_info); + } /* Build the tree for the SLP instance. */ bool res = vect_build_slp_instance (vinfo, kind, scalar_stmts, - kind == slp_inst_kind_ctor - ? stmt_info : NULL, + roots, max_tree_size, limit, bst_map, kind == slp_inst_kind_store ? stmt_info : NULL); + if (!res) + roots.release (); /* ??? If this is slp_inst_kind_store and the above succeeded here's where we should do store group splitting. */ @@ -2878,12 +2886,15 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size) { for (unsigned i = 0; i < bb_vinfo->roots.length (); ++i) { - vect_location = bb_vinfo->roots[i].root->stmt; + vect_location = bb_vinfo->roots[i].roots[0]->stmt; if (vect_build_slp_instance (bb_vinfo, bb_vinfo->roots[i].kind, bb_vinfo->roots[i].stmts, - bb_vinfo->roots[i].root, + bb_vinfo->roots[i].roots, max_tree_size, &limit, bst_map, NULL)) - bb_vinfo->roots[i].stmts = vNULL; + { + bb_vinfo->roots[i].stmts = vNULL; + bb_vinfo->roots[i].roots = vNULL; + } } } @@ -3741,7 +3752,10 @@ _bb_vec_info::~_bb_vec_info () } for (unsigned i = 0; i < roots.length (); ++i) - roots[i].stmts.release (); + { + roots[i].stmts.release (); + roots[i].roots.release (); + } roots.release (); } @@ -4154,7 +4168,8 @@ vect_slp_analyze_operations (vec_info *vinfo) &cost_vec) /* Instances with a root stmt require vectorized defs for the SLP tree root. */ - || (SLP_INSTANCE_ROOT_STMT (instance) + /* ??? Do inst->kind check instead. */ + || (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty () && (SLP_TREE_DEF_TYPE (SLP_INSTANCE_TREE (instance)) != vect_internal_def))) { @@ -4460,9 +4475,11 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo, auto_vec<bool, 20> life; life.safe_grow_cleared (SLP_TREE_LANES (SLP_INSTANCE_TREE (instance)), true); - if (SLP_INSTANCE_ROOT_STMT (instance)) - record_stmt_cost (&scalar_costs, 1, scalar_stmt, - SLP_INSTANCE_ROOT_STMT (instance), 0, vect_body); + if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ()) + record_stmt_cost (&scalar_costs, + SLP_INSTANCE_ROOT_STMTS (instance).length (), + scalar_stmt, + SLP_INSTANCE_ROOT_STMTS (instance)[0], 0, vect_body); vect_bb_slp_scalar_cost (bb_vinfo, SLP_INSTANCE_TREE (instance), &life, &scalar_costs, visited); @@ -4691,6 +4708,8 @@ vect_slp_check_for_constructors (bb_vec_info bb_vinfo) unsigned lanes_found = 1; /* Start with the use chains, the last stmt will be the root. */ stmt_vec_info last = bb_vinfo->lookup_stmt (assign); + vec<stmt_vec_info> roots = vNULL; + roots.safe_push (last); do { use_operand_p use_p; @@ -4710,9 +4729,12 @@ vect_slp_check_for_constructors (bb_vec_info bb_vinfo) lane_defs.quick_push (std::make_pair (this_lane, gimple_assign_rhs2 (use_ass))); last = bb_vinfo->lookup_stmt (use_ass); + roots.safe_push (last); def = gimple_assign_lhs (use_ass); } while (lanes_found < nlanes); + if (roots.length () > 1) + std::swap(roots[0], roots[roots.length () - 1]); if (lanes_found < nlanes) { /* Now search the def chain. */ @@ -4736,6 +4758,7 @@ vect_slp_check_for_constructors (bb_vec_info bb_vinfo) lane_defs.quick_push (std::make_pair (this_lane, gimple_assign_rhs2 (def_stmt))); + roots.safe_push (bb_vinfo->lookup_stmt (def_stmt)); def = gimple_assign_rhs1 (def_stmt); } while (lanes_found < nlanes); @@ -4749,8 +4772,10 @@ vect_slp_check_for_constructors (bb_vec_info bb_vinfo) for (unsigned i = 0; i < nlanes; ++i) stmts.quick_push (bb_vinfo->lookup_def (lane_defs[i].second)); bb_vinfo->roots.safe_push (slp_root (slp_inst_kind_ctor, - stmts, last)); + stmts, roots)); } + else + roots.release (); } } } @@ -4905,22 +4930,11 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal, relevant. */ vect_mark_slp_stmts (SLP_INSTANCE_TREE (instance)); vect_mark_slp_stmts_relevant (SLP_INSTANCE_TREE (instance)); - if (stmt_vec_info root = SLP_INSTANCE_ROOT_STMT (instance)) - { - STMT_SLP_TYPE (root) = pure_slp; - if (is_gimple_assign (root->stmt) - && gimple_assign_rhs_code (root->stmt) == BIT_INSERT_EXPR) - { - /* ??? We should probably record the whole vector of - root stmts so we do not have to back-track here... */ - for (unsigned n = SLP_TREE_LANES (SLP_INSTANCE_TREE (instance)); - n != 1; --n) - { - root = bb_vinfo->lookup_def (gimple_assign_rhs1 (root->stmt)); - STMT_SLP_TYPE (root) = pure_slp; - } - } - } + unsigned j; + stmt_vec_info root; + /* Likewise consider instance root stmts as vectorized. */ + FOR_EACH_VEC_ELT (SLP_INSTANCE_ROOT_STMTS (instance), j, root) + STMT_SLP_TYPE (root) = pure_slp; i++; } @@ -6357,47 +6371,50 @@ vectorize_slp_instance_root_stmt (slp_tree node, slp_instance instance) { gassign *rstmt = NULL; - if (SLP_TREE_NUMBER_OF_VEC_STMTS (node) == 1) + if (instance->kind == slp_inst_kind_ctor) { - gimple *child_stmt; - int j; - - FOR_EACH_VEC_ELT (SLP_TREE_VEC_STMTS (node), j, child_stmt) + if (SLP_TREE_NUMBER_OF_VEC_STMTS (node) == 1) { - tree vect_lhs = gimple_get_lhs (child_stmt); - tree root_lhs = gimple_get_lhs (instance->root_stmt->stmt); - if (!useless_type_conversion_p (TREE_TYPE (root_lhs), - TREE_TYPE (vect_lhs))) - vect_lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (root_lhs), - vect_lhs); - rstmt = gimple_build_assign (root_lhs, vect_lhs); - break; - } - } - else if (SLP_TREE_NUMBER_OF_VEC_STMTS (node) > 1) - { - int nelts = SLP_TREE_NUMBER_OF_VEC_STMTS (node); - gimple *child_stmt; - int j; - vec<constructor_elt, va_gc> *v; - vec_alloc (v, nelts); + gimple *child_stmt; + int j; - FOR_EACH_VEC_ELT (SLP_TREE_VEC_STMTS (node), j, child_stmt) + FOR_EACH_VEC_ELT (SLP_TREE_VEC_STMTS (node), j, child_stmt) + { + tree vect_lhs = gimple_get_lhs (child_stmt); + tree root_lhs = gimple_get_lhs (instance->root_stmts[0]->stmt); + if (!useless_type_conversion_p (TREE_TYPE (root_lhs), + TREE_TYPE (vect_lhs))) + vect_lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (root_lhs), + vect_lhs); + rstmt = gimple_build_assign (root_lhs, vect_lhs); + break; + } + } + else if (SLP_TREE_NUMBER_OF_VEC_STMTS (node) > 1) { - CONSTRUCTOR_APPEND_ELT (v, - NULL_TREE, - gimple_get_lhs (child_stmt)); + int nelts = SLP_TREE_NUMBER_OF_VEC_STMTS (node); + gimple *child_stmt; + int j; + vec<constructor_elt, va_gc> *v; + vec_alloc (v, nelts); + + FOR_EACH_VEC_ELT (SLP_TREE_VEC_STMTS (node), j, child_stmt) + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + gimple_get_lhs (child_stmt)); + tree lhs = gimple_get_lhs (instance->root_stmts[0]->stmt); + tree rtype + = TREE_TYPE (gimple_assign_rhs1 (instance->root_stmts[0]->stmt)); + tree r_constructor = build_constructor (rtype, v); + rstmt = gimple_build_assign (lhs, r_constructor); } - tree lhs = gimple_get_lhs (instance->root_stmt->stmt); - tree rtype = TREE_TYPE (gimple_assign_rhs1 (instance->root_stmt->stmt)); - tree r_constructor = build_constructor (rtype, v); - rstmt = gimple_build_assign (lhs, r_constructor); } + else + gcc_unreachable (); - gcc_assert (rstmt); + gcc_assert (rstmt); - gimple_stmt_iterator rgsi = gsi_for_stmt (instance->root_stmt->stmt); - gsi_replace (&rgsi, rstmt, true); + gimple_stmt_iterator rgsi = gsi_for_stmt (instance->root_stmts[0]->stmt); + gsi_replace (&rgsi, rstmt, true); } struct slp_scc_info @@ -6567,9 +6584,10 @@ vect_schedule_slp (vec_info *vinfo, vec<slp_instance> slp_instances) { dump_printf_loc (MSG_NOTE, vect_location, "Vectorizing SLP tree:\n"); - if (SLP_INSTANCE_ROOT_STMT (instance)) + /* ??? Dump all? */ + if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ()) dump_printf_loc (MSG_NOTE, vect_location, "Root stmt: %G", - SLP_INSTANCE_ROOT_STMT (instance)->stmt); + SLP_INSTANCE_ROOT_STMTS (instance)[0]->stmt); vect_print_slp_graph (MSG_NOTE, vect_location, SLP_INSTANCE_TREE (instance)); } @@ -6579,7 +6597,7 @@ vect_schedule_slp (vec_info *vinfo, vec<slp_instance> slp_instances) if (!scc_info.get (node)) vect_schedule_scc (vinfo, node, instance, scc_info, maxdfs, stack); - if (SLP_INSTANCE_ROOT_STMT (instance)) + if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ()) vectorize_slp_instance_root_stmt (node, instance); if (dump_enabled_p ()) diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index bd2a1c8..eeef96a 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -11326,17 +11326,7 @@ vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt, { stmt_vinfo = vect_stmt_to_vectorize (stmt_vinfo); def_stmt = stmt_vinfo->stmt; - switch (gimple_code (def_stmt)) - { - case GIMPLE_PHI: - case GIMPLE_ASSIGN: - case GIMPLE_CALL: - *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo); - break; - default: - *dt = vect_unknown_def_type; - break; - } + *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo); if (def_stmt_info_out) *def_stmt_info_out = stmt_vinfo; } diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 7dcb4cd..06d20c7 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -197,7 +197,7 @@ public: /* For vector constructors, the constructor stmt that the SLP tree is built from, NULL otherwise. */ - stmt_vec_info root_stmt; + vec<stmt_vec_info> root_stmts; /* The unrolling factor required to vectorized this SLP instance. */ poly_uint64 unrolling_factor; @@ -226,7 +226,7 @@ public: #define SLP_INSTANCE_TREE(S) (S)->root #define SLP_INSTANCE_UNROLLING_FACTOR(S) (S)->unrolling_factor #define SLP_INSTANCE_LOADS(S) (S)->loads -#define SLP_INSTANCE_ROOT_STMT(S) (S)->root_stmt +#define SLP_INSTANCE_ROOT_STMTS(S) (S)->root_stmts #define SLP_INSTANCE_KIND(S) (S)->kind #define SLP_TREE_CHILDREN(S) (S)->children @@ -861,11 +861,11 @@ loop_vec_info_for_loop (class loop *loop) struct slp_root { slp_root (slp_instance_kind kind_, vec<stmt_vec_info> stmts_, - stmt_vec_info root_) - : kind(kind_), stmts(stmts_), root(root_) {} + vec<stmt_vec_info> roots_) + : kind(kind_), stmts(stmts_), roots(roots_) {} slp_instance_kind kind; vec<stmt_vec_info> stmts; - stmt_vec_info root; + vec<stmt_vec_info> roots; }; typedef class _bb_vec_info : public vec_info diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index f4f5ad4..97bc035 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,8 @@ +2021-06-08 Martin Liska <mliska@suse.cz> + + * intrinsics/chmod.c (chmod_internal): Fix typo. + * io/transfer.c (read_sf): Likewise. + 2021-06-05 José Rui Faustino de Sousa <jrfsousa@gmail.com> PR fortran/100120 diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index aca3504..5ad2693 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,104 @@ +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * plugin/plugin-gcn.c (gcn_exec): Force 'num_workers (1)' + unconditionally. + * testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c: + Update. + * testsuite/libgomp.oacc-c-c++-common/parallel-dims.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/routine-wv-2.c: Likewise. + +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * testsuite/libgomp.oacc-c-c++-common/lib-11.c: Enable for all but + '-DACC_MEM_SHARED=0'. + * testsuite/libgomp.oacc-c-c++-common/lib-13.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-14.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-15.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-20.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-23.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-24.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-34.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-42.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-44.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-48.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-88.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-89.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-92.c: Likewise. + * testsuite/libgomp.oacc-fortran/lib-14.f90: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-5.c: Add + 'acc_device_radeon' testing. + * testsuite/libgomp.oacc-c-c++-common/lib-6.c: Likewise. + * testsuite/libgomp.oacc-fortran/lib-5.f90: Likewise. + * testsuite/libgomp.oacc-fortran/lib-7.f90: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-52.c: Enable for all. + * testsuite/libgomp.oacc-c-c++-common/lib-53.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-54.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-86.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-87.c: Likewise. + * testsuite/libgomp.oacc-fortran/lib-10.f90: Likewise. + * testsuite/libgomp.oacc-fortran/lib-8.f90: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-57.c: Improve checking + for non-'openacc_nvidia_accel_selected'. + * testsuite/libgomp.oacc-c-c++-common/lib-58.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-62.c: Clarify that "Not + all implement this checking". + * testsuite/libgomp.oacc-c-c++-common/lib-63.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-64.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-65.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-67.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-68.c: Likewise. + +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * testsuite/libgomp.oacc-c-c++-common/parallel-dims.c: Simplify. + * testsuite/libgomp.oacc-fortran/parallel-dims-aux.c: Update. + +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c: Fix + for 'acc_device_radeon'. + +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * testsuite/libgomp.oacc-c-c++-common/firstprivate-1.c: Enhance + for non-'acc_device_nvidia'. + +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c: Add + 'acc_device_radeon' testing. + * testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90: Likewise. + * testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f: Likewise. + * testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f: Likewise. + +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * testsuite/libgomp.oacc-c-c++-common/async_queue-1.c: Don't + require 'openacc_nvidia_accel_selected'. Fix up for + 'ACC_DEVICE_TYPE_radeon'. + +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * testsuite/libgomp.oacc-c++/declare-1.C: Don't require + 'openacc_nvidia_accel_selected'. + * testsuite/libgomp.oacc-c-c++-common/declare-3.c: Likewise. + +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * testsuite/lib/libgomp.exp + (check_effective_target_openacc_radeon_accel_selected): + Streamline. + +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * testsuite/libgomp.oacc-c-c++-common/parallel-dims.c: Revert + PR80547 workaround. + +2021-06-08 Thomas Schwinge <thomas@codesourcery.com> + + * testsuite/libgomp.oacc-c-c++-common/parallel-dims.c + <acc_device_nvidia>: Update comment. + 2021-05-28 Tobias Burnus <tobias@codesourcery.com> * testsuite/libgomp.fortran/depend-iterator-2.f90: New test. diff --git a/libgomp/plugin/plugin-gcn.c b/libgomp/plugin/plugin-gcn.c index 8aab708..cfed42a 100644 --- a/libgomp/plugin/plugin-gcn.c +++ b/libgomp/plugin/plugin-gcn.c @@ -3041,10 +3041,9 @@ gcn_exec (struct kernel_info *kernel, size_t mapnum, void **hostaddrs, problem size, so let's do a reasonable number of single-worker gangs. 64 gangs matches a typical Fiji device. */ - /* NOTE: Until support for middle-end worker partitioning is merged, use 1 - for the default number of workers. */ if (dims[0] == 0) dims[0] = get_cu_count (kernel->agent); /* Gangs. */ - if (dims[1] == 0) dims[1] = 1; /* Workers. */ + /* NOTE: Until support for middle-end worker partitioning is merged, force 'num_workers (1)'. */ + if (/*TODO dims[1] == 0*/ true) dims[1] = 1; /* Workers. */ /* The incoming dimensions are expressed in terms of gangs, workers, and vectors. The HSA dimensions are expressed in terms of "work-items", diff --git a/libgomp/testsuite/lib/libgomp.exp b/libgomp/testsuite/lib/libgomp.exp index 0f4eb6f..45c78d8 100644 --- a/libgomp/testsuite/lib/libgomp.exp +++ b/libgomp/testsuite/lib/libgomp.exp @@ -472,11 +472,8 @@ proc check_effective_target_openacc_radeon_accel_selected { } { if { ![check_effective_target_openacc_radeon_accel_present] } { return 0; } - global offload_target - if { [string match "amdgcn*" $offload_target] } { - return 1; - } - return 0; + global openacc_device_type + return [string match "radeon" $openacc_device_type] } # Return 1 if cuda.h and -lcuda are available. diff --git a/libgomp/testsuite/libgomp.oacc-c++/declare-1.C b/libgomp/testsuite/libgomp.oacc-c++/declare-1.C index 0286955..461b778 100644 --- a/libgomp/testsuite/libgomp.oacc-c++/declare-1.C +++ b/libgomp/testsuite/libgomp.oacc-c++/declare-1.C @@ -1,5 +1,3 @@ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ - #include <stdlib.h> template<class T> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c index 8112745..064c6f5 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c @@ -19,6 +19,8 @@ main (int argc, char *argv[]) abort (); if (acc_on_device (acc_device_nvidia)) abort (); + if (acc_on_device (acc_device_radeon)) + abort (); } @@ -34,6 +36,8 @@ main (int argc, char *argv[]) abort (); if (acc_on_device (acc_device_nvidia)) abort (); + if (acc_on_device (acc_device_radeon)) + abort (); } @@ -56,6 +60,13 @@ main (int argc, char *argv[]) if (acc_on_device (acc_device_nvidia)) abort (); #endif +#if ACC_DEVICE_TYPE_radeon + if (!acc_on_device (acc_device_radeon)) + abort (); +#else + if (acc_on_device (acc_device_radeon)) + abort (); +#endif } #endif diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c index ad33f72..6c136c2 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c @@ -93,6 +93,9 @@ static void cb_enqueue_launch_start (acc_prof_info *prof_info, acc_event_info *e } if (num_workers < 1) assert (event_info->launch_event.num_workers >= 1); + /* GCN currently enforces 'num_workers (1)'. */ + else if (acc_device_type == acc_device_radeon) + assert (event_info->launch_event.num_workers == 1); else { #ifdef __OPTIMIZE__ diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/async_queue-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/async_queue-1.c index 4f9e53d..533d498 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/async_queue-1.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/async_queue-1.c @@ -1,5 +1,3 @@ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ - /* Test mapping of async values to specific underlying queues. */ #undef NDEBUG @@ -29,6 +27,8 @@ int main(void) acc_device_t d; #if defined ACC_DEVICE_TYPE_nvidia d = acc_device_nvidia; +#elif defined ACC_DEVICE_TYPE_radeon + d = acc_device_radeon; #elif defined ACC_DEVICE_TYPE_host d = acc_device_host; #else @@ -88,6 +88,9 @@ int main(void) assert (queues[i].cuda_stream == NULL); else assert (queues[i].cuda_stream != NULL); +#elif defined ACC_DEVICE_TYPE_radeon + /* For "acc_device_radeon" there are no CUDA streams. */ + assert (queues[i].cuda_stream == NULL); #elif defined ACC_DEVICE_TYPE_host /* For "acc_device_host" there are no CUDA streams. */ assert (queues[i].cuda_stream == NULL); diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-3.c index c3a2187..dc6c7f3 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-3.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-3.c @@ -1,5 +1,3 @@ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ - #include <stdlib.h> #include <openacc.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/firstprivate-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/firstprivate-1.c index fff0c28..27da765 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/firstprivate-1.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/firstprivate-1.c @@ -79,7 +79,7 @@ void t2 () void t3 () { int a, b[N], c, d, i; - int n = acc_get_device_type () == acc_device_nvidia ? N : 1; + int n = acc_get_device_type () != acc_device_host ? N : 1; a = 5; for (i = 0; i < n; i++) diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-11.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-11.c index 86cfeb6..1f05161 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-11.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-11.c @@ -1,5 +1,4 @@ -/* Only nvptx plugin does the required error checking. - { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdio.h> #include <stdlib.h> @@ -22,6 +21,9 @@ main (int argc, char **argv) return 0; } -/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */ -/* { dg-output "invalid device address" } */ +/* { dg-output "CheCKpOInT(\n|\r\n|\r)+" } */ +/* { dg-output "libgomp: invalid device address(\n|\r\n|\r)+" { target openacc_nvidia_accel_selected } } */ +/* { dg-output "libgomp: GCN fatal error: Could not free device memory(\n|\r\n|\r)+" { target openacc_radeon_accel_selected } } + { dg-output "Runtime message: HSA_STATUS_ERROR_INVALID_ALLOCATION: The requested allocation is not valid\.(\n|\r\n|\r)+" { target openacc_radeon_accel_selected } } */ +/* { dg-output "libgomp: error in freeing device memory in acc_free(\n|\r\n|\r)+$" } */ /* { dg-shouldfail "" } */ diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-13.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-13.c index aca4c25..90b137f 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-13.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-13.c @@ -1,6 +1,6 @@ /* Check acc_is_present and acc_delete. */ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdlib.h> #include <openacc.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-14.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-14.c index de6d38b..892f97c 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-14.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-14.c @@ -1,6 +1,6 @@ /* Check acc_is_present. */ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdlib.h> #include <openacc.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-15.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-15.c index 50c1701..335b26f 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-15.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-15.c @@ -1,6 +1,6 @@ /* Check acc_is_present and acc_copyout. */ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdlib.h> #include <openacc.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-20.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-20.c index 10d3cbc..f1d9a21 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-20.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-20.c @@ -1,6 +1,6 @@ -/* Exercise acc_copyin and acc_copyout on nvidia targets. */ +/* Exercise acc_copyin and acc_copyout. */ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-23.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-23.c index b1f3e71..d39f31e 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-23.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-23.c @@ -1,6 +1,6 @@ -/* Exercise acc_copyin and acc_copyout on nvidia targets. */ +/* Exercise acc_copyin and acc_copyout. */ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-24.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-24.c index 09e2817..96e3129 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-24.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-24.c @@ -1,6 +1,6 @@ /* Exercise acc_create, acc_is_present and acc_delete. */ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdlib.h> #include <openacc.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-34.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-34.c index a24916d..8ddd897 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-34.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-34.c @@ -1,6 +1,6 @@ -/* Exercise an invalid acc_present_or_create on nvidia targets. */ +/* Exercise an invalid acc_present_or_create. */ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-42.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-42.c index 30b90d4..adab109 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-42.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-42.c @@ -1,6 +1,6 @@ -/* Exercise acc_update_device on unmapped data on nvidia targets. */ +/* Exercise acc_update_device on unmapped data. */ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-44.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-44.c index 8bbf016..f02fe21 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-44.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-44.c @@ -1,6 +1,6 @@ -/* Exercise acc_update_device with size zero data on nvidia targets. */ +/* Exercise acc_update_device with size zero data. */ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-48.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-48.c index afa137f..9975c9e 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-48.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-48.c @@ -1,6 +1,6 @@ -/* Exercise acc_update_self with a size zero data mapping on nvidia targets. */ +/* Exercise acc_update_self with a size zero data mapping. */ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdio.h> #include <string.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-5.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-5.c index 961a62c..1e0ab9c 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-5.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-5.c @@ -35,6 +35,24 @@ main (int argc, char **argv) acc_shutdown (acc_device_nvidia); } - return 0; + if (acc_get_num_devices (acc_device_radeon) != 0) + { + acc_init (acc_device_radeon); + + if (acc_get_device_type () != acc_device_radeon) + abort (); + + acc_shutdown (acc_device_radeon); + + acc_init (acc_device_default); + acc_set_device_type (acc_device_radeon); + + if (acc_get_device_type () != acc_device_radeon) + abort (); + + acc_shutdown (acc_device_radeon); + } + + return 0; } diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-52.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-52.c index 25c70c2..9a562b3 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-52.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-52.c @@ -1,6 +1,4 @@ -/* Exercise acc_map_data with a NULL data mapping on nvidia targets. */ - -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* Exercise acc_map_data with a NULL data mapping. */ #include <stdio.h> #include <stdlib.h> @@ -30,6 +28,6 @@ main (int argc, char **argv) } /* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */ -/* { dg-output "\\\[\[^\n\r]*,\\\+256\]->\[\[0-9a-fA-FxX\]+,\\\+256\\\] is a bad map" { target openacc_nvidia_accel_selected } } */ +/* { dg-output "\\\[\[^\n\r]*,\\\+256\]->\[\[0-9a-fA-FxX\]+,\\\+256\\\] is a bad map" { target { ! openacc_host_selected } } } */ /* { dg-output "cannot map data on shared-memory system" { target openacc_host_selected } } */ /* { dg-shouldfail "" } */ diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-53.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-53.c index a8ee7df..d452a69 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-53.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-53.c @@ -1,6 +1,4 @@ -/* Exercise acc_map_data with a NULL data mapping on nvidia targets. */ - -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* Exercise acc_map_data with a NULL data mapping. */ #include <stdio.h> #include <stdlib.h> @@ -30,6 +28,6 @@ main (int argc, char **argv) } /* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */ -/* { dg-output "\\\[\[0-9a-fA-FxX\]+,\\\+256\]->\\\[\[^\n\r]*,\\\+256\\\] is a bad map" { target openacc_nvidia_accel_selected } } */ +/* { dg-output "\\\[\[0-9a-fA-FxX\]+,\\\+256\]->\\\[\[^\n\r]*,\\\+256\\\] is a bad map" { target { ! openacc_host_selected } } } */ /* { dg-output "cannot map data on shared-memory system" { target openacc_host_selected } } */ /* { dg-shouldfail "" } */ diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-54.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-54.c index fc221f4..1922754 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-54.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-54.c @@ -1,6 +1,4 @@ -/* Exercise acc_map_data with data size of zero on nvidia targets. */ - -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* Exercise acc_map_data with data size of zero. */ #include <stdio.h> #include <stdlib.h> @@ -30,6 +28,6 @@ main (int argc, char **argv) } /* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */ -/* { dg-output "\\\[\[0-9a-fA-FxX\]+,\\\+0\\\]->\\\[\[0-9a-fA-FxX\]+,\\\+0\\\] is a bad map" { target openacc_nvidia_accel_selected } } */ +/* { dg-output "\\\[\[0-9a-fA-FxX\]+,\\\+0\\\]->\\\[\[0-9a-fA-FxX\]+,\\\+0\\\] is a bad map" { target { ! openacc_host_selected } } } */ /* { dg-output "cannot map data on shared-memory system" { target openacc_host_selected } } */ /* { dg-shouldfail "" } */ diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-57.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-57.c index 971a014..81653c6 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-57.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-57.c @@ -33,6 +33,6 @@ main (int argc, char **argv) } /* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */ -/* { dg-output "\[0-9a-fA-FxX\]+ is not a mapped block" { target openacc_nvidia_accel_selected } } */ +/* { dg-output "\[0-9a-fA-FxX\]+ is not a mapped block" { target { ! openacc_host_selected } } } */ /* { dg-output "cannot map data on shared-memory system" { target openacc_host_selected } } */ /* { dg-shouldfail "" } */ diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-58.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-58.c index fedda77..c6bc261 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-58.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-58.c @@ -33,6 +33,6 @@ main (int argc, char **argv) } /* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */ -/* { dg-output "\[^\n\r]* is not a mapped block" { target openacc_nvidia_accel_selected } } */ +/* { dg-output "\[^\n\r]* is not a mapped block" { target { ! openacc_host_selected } } } */ /* { dg-output "cannot map data on shared-memory system" { target openacc_host_selected } } */ /* { dg-shouldfail "" } */ diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-6.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-6.c index afdd480..a3affc0 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-6.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-6.c @@ -11,26 +11,47 @@ main (int argc, char **argv) if (acc_get_device_type () == acc_device_default) abort (); - if (acc_get_num_devices (acc_device_nvidia) == 0) - return 0; + if (acc_get_num_devices (acc_device_nvidia)) + { + acc_set_device_type (acc_device_nvidia); - acc_set_device_type (acc_device_nvidia); + if (acc_get_device_type () != acc_device_nvidia) + abort (); - if (acc_get_device_type () != acc_device_nvidia) - abort (); + acc_shutdown (acc_device_nvidia); - acc_shutdown (acc_device_nvidia); + acc_set_device_type (acc_device_nvidia); - acc_set_device_type (acc_device_nvidia); + if (acc_get_device_type () != acc_device_nvidia) + abort (); - if (acc_get_device_type () != acc_device_nvidia) - abort (); + devnum = acc_get_num_devices (acc_device_host); + if (devnum != 1) + abort (); - devnum = acc_get_num_devices (acc_device_host); - if (devnum != 1) - abort (); + acc_shutdown (acc_device_nvidia); + } + + if (acc_get_num_devices (acc_device_radeon)) + { + acc_set_device_type (acc_device_radeon); + + if (acc_get_device_type () != acc_device_radeon) + abort (); + + acc_shutdown (acc_device_radeon); + + acc_set_device_type (acc_device_radeon); + + if (acc_get_device_type () != acc_device_radeon) + abort (); + + devnum = acc_get_num_devices (acc_device_host); + if (devnum != 1) + abort (); - acc_shutdown (acc_device_nvidia); + acc_shutdown (acc_device_radeon); + } if (acc_get_device_type () == acc_device_default) abort (); diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-62.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-62.c index ace4b05..2e7184a 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-62.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-62.c @@ -1,4 +1,5 @@ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* Not all implement this checking. + { dg-skip-if "" { openacc_radeon_accel_selected || openacc_host_selected } } */ #include <stdio.h> #include <string.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-63.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-63.c index a3fa728..84bbccb 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-63.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-63.c @@ -1,4 +1,5 @@ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* Not all implement this checking. + { dg-skip-if "" { openacc_radeon_accel_selected || openacc_host_selected } } */ #include <stdio.h> #include <string.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-64.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-64.c index b57f67a..e26681a 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-64.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-64.c @@ -1,4 +1,5 @@ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* Not all implement this checking. + { dg-skip-if "" { openacc_radeon_accel_selected || openacc_host_selected } } */ #include <stdio.h> #include <string.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-65.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-65.c index 0fca821..69add3f 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-65.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-65.c @@ -1,4 +1,5 @@ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* Not all implement this checking. + { dg-skip-if "" { openacc_radeon_accel_selected || openacc_host_selected } } */ #include <stdio.h> #include <string.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-67.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-67.c index ec3c2a5..c13333b 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-67.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-67.c @@ -1,4 +1,5 @@ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* Not all implement this checking. + { dg-skip-if "" { openacc_radeon_accel_selected || openacc_host_selected } } */ #include <stdio.h> #include <string.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-68.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-68.c index f109034..7fffd0b 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-68.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-68.c @@ -1,4 +1,5 @@ -/* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* Not all implement this checking. + { dg-skip-if "" { openacc_radeon_accel_selected || openacc_host_selected } } */ #include <stdio.h> #include <string.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-86.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-86.c index b8a8ee9..7e8a7e2 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-86.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-86.c @@ -7,9 +7,6 @@ int main (int argc, char **argv) { - if (acc_get_num_devices (acc_device_nvidia) == 0) - return 0; - if (acc_get_current_cuda_device () != 0) abort (); @@ -20,18 +17,28 @@ main (int argc, char **argv) acc_shutdown (acc_device_host); - if (acc_get_num_devices (acc_device_nvidia) == 0) - return 0; - if (acc_get_current_cuda_device () != 0) abort (); - acc_init (acc_device_nvidia); + if (acc_get_num_devices (acc_device_nvidia)) + { + acc_init (acc_device_nvidia); - if (acc_get_current_cuda_device () == 0) - abort (); + if (acc_get_current_cuda_device () == 0) + abort (); + + acc_shutdown (acc_device_nvidia); + } + + if (acc_get_num_devices (acc_device_radeon)) + { + acc_init (acc_device_radeon); + + if (acc_get_current_cuda_device () != 0) + abort (); - acc_shutdown (acc_device_nvidia); + acc_shutdown (acc_device_radeon); + } if (acc_get_current_cuda_device () != 0) abort (); diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-87.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-87.c index 147d443..cdc87ed 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-87.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-87.c @@ -7,9 +7,6 @@ int main (int argc, char **argv) { - if (acc_get_num_devices (acc_device_nvidia) == 0) - return 0; - if (acc_get_current_cuda_context () != 0) abort (); @@ -20,18 +17,28 @@ main (int argc, char **argv) acc_shutdown (acc_device_host); - if (acc_get_num_devices (acc_device_nvidia) == 0) - return 0; - if (acc_get_current_cuda_context () != 0) abort (); - acc_init (acc_device_nvidia); + if (acc_get_num_devices (acc_device_nvidia)) + { + acc_init (acc_device_nvidia); - if (acc_get_current_cuda_context () == 0) - abort (); + if (acc_get_current_cuda_context () == 0) + abort (); + + acc_shutdown (acc_device_nvidia); + } + + if (acc_get_num_devices (acc_device_radeon)) + { + acc_init (acc_device_radeon); + + if (acc_get_current_cuda_context () != 0) + abort (); - acc_shutdown (acc_device_nvidia); + acc_shutdown (acc_device_radeon); + } if (acc_get_current_cuda_context () != 0) abort (); diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-88.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-88.c index 10f4ad8..c1cccd9 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-88.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-88.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdio.h> #include <pthread.h> @@ -47,10 +47,7 @@ main (int argc, char **argv) pthread_attr_t attr; pthread_t *tid; - if (acc_get_num_devices (acc_device_nvidia) == 0) - return 0; - - acc_init (acc_device_nvidia); + acc_init (acc_device_default); x = (unsigned char *) malloc (N); @@ -103,8 +100,6 @@ main (int argc, char **argv) if (acc_is_present (x, N) != 0) abort (); - acc_shutdown (acc_device_nvidia); - return 0; } diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-89.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-89.c index 061c409..6b4e3ac 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-89.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-89.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <stdio.h> #include <pthread.h> @@ -23,11 +23,16 @@ test (void *arg) tid = (int) (long) arg; - devnum = acc_get_device_num (acc_device_nvidia); - acc_set_device_num (devnum, acc_device_nvidia); + devnum = acc_get_device_num (acc_device_default); + acc_set_device_num (devnum, acc_device_default); +#if ACC_DEVICE_TYPE_nvidia if (acc_get_current_cuda_context () == NULL) abort (); +#else + if (acc_get_current_cuda_context () != NULL) + abort (); +#endif p = (unsigned char *) malloc (N); @@ -50,10 +55,7 @@ main (int argc, char **argv) pthread_attr_t attr; pthread_t *tid; - if (acc_get_num_devices (acc_device_nvidia) == 0) - return 0; - - acc_init (acc_device_nvidia); + acc_init (acc_device_default); x = (unsigned char **) malloc (NTHREADS * N); d_x = (void **) malloc (NTHREADS * N); @@ -110,8 +112,6 @@ main (int argc, char **argv) abort (); } - acc_shutdown (acc_device_nvidia); - return 0; } diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-92.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-92.c index 18193e0..0043fb3 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-92.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-92.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ #include <pthread.h> #include <stdio.h> @@ -22,11 +22,16 @@ test (void *arg) tid = (int) (long) arg; - devnum = acc_get_device_num (acc_device_nvidia); - acc_set_device_num (devnum, acc_device_nvidia); + devnum = acc_get_device_num (acc_device_default); + acc_set_device_num (devnum, acc_device_default); +#if ACC_DEVICE_TYPE_nvidia if (acc_get_current_cuda_context () == NULL) abort (); +#else + if (acc_get_current_cuda_context () != NULL) + abort (); +#endif acc_copyout (x[tid], N); @@ -49,10 +54,7 @@ main (int argc, char **argv) pthread_t *tid; unsigned char *p; - if (acc_get_num_devices (acc_device_nvidia) == 0) - return 0; - - acc_init (acc_device_nvidia); + acc_init (acc_device_default); x = (unsigned char **) malloc (NTHREADS * N); d_x = (void **) malloc (NTHREADS * N); @@ -104,8 +106,6 @@ main (int argc, char **argv) abort (); } - acc_shutdown (acc_device_nvidia); - return 0; } diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/parallel-dims.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/parallel-dims.c index ef4917a..fe0dacd 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/parallel-dims.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/parallel-dims.c @@ -10,42 +10,22 @@ #include <openacc.h> #include <gomp-constants.h> -/* TODO: "(int) acc_device_*" casts because of the C++ acc_on_device wrapper - not behaving as expected for -O0. */ #pragma acc routine seq -static unsigned int __attribute__ ((optimize ("O2"))) acc_gang () +static int acc_gang () { - if (acc_on_device ((int) acc_device_host)) - return 0; - else if (acc_on_device ((int) acc_device_nvidia) - || acc_on_device ((int) acc_device_radeon)) - return __builtin_goacc_parlevel_id (GOMP_DIM_GANG); - else - __builtin_abort (); + return __builtin_goacc_parlevel_id (GOMP_DIM_GANG); } #pragma acc routine seq -static unsigned int __attribute__ ((optimize ("O2"))) acc_worker () +static int acc_worker () { - if (acc_on_device ((int) acc_device_host)) - return 0; - else if (acc_on_device ((int) acc_device_nvidia) - || acc_on_device ((int) acc_device_radeon)) - return __builtin_goacc_parlevel_id (GOMP_DIM_WORKER); - else - __builtin_abort (); + return __builtin_goacc_parlevel_id (GOMP_DIM_WORKER); } #pragma acc routine seq -static unsigned int __attribute__ ((optimize ("O2"))) acc_vector () +static int acc_vector () { - if (acc_on_device ((int) acc_device_host)) - return 0; - else if (acc_on_device ((int) acc_device_nvidia) - || acc_on_device ((int) acc_device_radeon)) - return __builtin_goacc_parlevel_id (GOMP_DIM_VECTOR); - else - __builtin_abort (); + return __builtin_goacc_parlevel_id (GOMP_DIM_VECTOR); } @@ -72,22 +52,9 @@ int main () gangs_actual = 1; for (int i = 100 * gangs_actual; i > -100 * gangs_actual; --i) { - /* <https://gcc.gnu.org/PR80547>. */ -#if 0 gangs_min = gangs_max = acc_gang (); workers_min = workers_max = acc_worker (); vectors_min = vectors_max = acc_vector (); -#else - int gangs = acc_gang (); - gangs_min = (gangs_min < gangs) ? gangs_min : gangs; - gangs_max = (gangs_max > gangs) ? gangs_max : gangs; - int workers = acc_worker (); - workers_min = (workers_min < workers) ? workers_min : workers; - workers_max = (workers_max > workers) ? workers_max : workers; - int vectors = acc_vector (); - vectors_min = (vectors_min < vectors) ? vectors_min : vectors; - vectors_max = (vectors_max > vectors) ? vectors_max : vectors; -#endif } } if (gangs_actual != 1) @@ -346,8 +313,9 @@ int main () } else if (acc_on_device (acc_device_radeon)) { - /* The GCC GCN back end is limited to num_workers (16). */ - workers_actual = 16; + /* The GCC GCN back end is limited to num_workers (16). + Temporarily set this to 1 until multiple workers are permitted. */ + workers_actual = 1; // 16; } else __builtin_abort (); @@ -385,7 +353,7 @@ int main () } else if (acc_on_device (acc_device_nvidia)) { - /* The GCC nvptx back end enforces vector_length (32). */ + /* The GCC nvptx back end reduces to vector_length (1024). */ vectors_actual = 1024; } else if (acc_on_device (acc_device_radeon)) diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-wv-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-wv-2.c index a03a2c2..624ec24 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-wv-2.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-wv-2.c @@ -6,7 +6,8 @@ #include <gomp-constants.h> #ifdef ACC_DEVICE_TYPE_radeon -#define NUM_WORKERS 16 +/* Temporarily set this to 1 until multiple workers are permitted. */ +#define NUM_WORKERS 1 #define NUM_VECTORS 1 #else #define NUM_WORKERS 16 diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90 index ace9358..cd599e5 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90 +++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90 @@ -21,6 +21,7 @@ if (.not. acc_on_device (acc_device_none)) STOP 1 if (.not. acc_on_device (acc_device_host)) STOP 2 if (acc_on_device (acc_device_not_host)) STOP 3 if (acc_on_device (acc_device_nvidia)) STOP 4 +if (acc_on_device (acc_device_radeon)) STOP 4 ! Host via offloading fallback mode. @@ -32,6 +33,7 @@ if (.not. acc_on_device (acc_device_none)) STOP 5 if (.not. acc_on_device (acc_device_host)) STOP 6 if (acc_on_device (acc_device_not_host)) STOP 7 if (acc_on_device (acc_device_nvidia)) STOP 8 +if (acc_on_device (acc_device_radeon)) STOP 8 !$acc end parallel @@ -49,6 +51,11 @@ if (.not. acc_on_device (acc_device_nvidia)) STOP 12 #else if (acc_on_device (acc_device_nvidia)) STOP 13 #endif +#if ACC_DEVICE_TYPE_radeon +if (.not. acc_on_device (acc_device_radeon)) STOP 14 +#else +if (acc_on_device (acc_device_radeon)) STOP 15 +#endif !$acc end parallel #endif diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f index 56270b1..eb3daba 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f +++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f @@ -21,6 +21,7 @@ IF (.NOT. ACC_ON_DEVICE (ACC_DEVICE_HOST)) STOP 2 IF (ACC_ON_DEVICE (ACC_DEVICE_NOT_HOST)) STOP 3 IF (ACC_ON_DEVICE (ACC_DEVICE_NVIDIA)) STOP 4 + IF (ACC_ON_DEVICE (ACC_DEVICE_RADEON)) STOP 4 !Host via offloading fallback mode. @@ -32,6 +33,7 @@ IF (.NOT. ACC_ON_DEVICE (ACC_DEVICE_HOST)) STOP 6 IF (ACC_ON_DEVICE (ACC_DEVICE_NOT_HOST)) STOP 7 IF (ACC_ON_DEVICE (ACC_DEVICE_NVIDIA)) STOP 8 + IF (ACC_ON_DEVICE (ACC_DEVICE_RADEON)) STOP 8 !$ACC END PARALLEL @@ -49,6 +51,11 @@ #else IF (ACC_ON_DEVICE (ACC_DEVICE_NVIDIA)) STOP 13 #endif +#if ACC_DEVICE_TYPE_radeon + IF (.NOT. ACC_ON_DEVICE (ACC_DEVICE_RADEON)) STOP 14 +#else + IF (ACC_ON_DEVICE (ACC_DEVICE_RADEON)) STOP 15 +#endif !$ACC END PARALLEL #endif diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f index a8b9cdd..5f500c1 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f +++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f @@ -21,6 +21,7 @@ IF (.NOT. ACC_ON_DEVICE (ACC_DEVICE_HOST)) STOP 2 IF (ACC_ON_DEVICE (ACC_DEVICE_NOT_HOST)) STOP 3 IF (ACC_ON_DEVICE (ACC_DEVICE_NVIDIA)) STOP 4 + IF (ACC_ON_DEVICE (ACC_DEVICE_RADEON)) STOP 4 !Host via offloading fallback mode. @@ -32,6 +33,7 @@ IF (.NOT. ACC_ON_DEVICE (ACC_DEVICE_HOST)) STOP 6 IF (ACC_ON_DEVICE (ACC_DEVICE_NOT_HOST)) STOP 7 IF (ACC_ON_DEVICE (ACC_DEVICE_NVIDIA)) STOP 8 + IF (ACC_ON_DEVICE (ACC_DEVICE_RADEON)) STOP 8 !$ACC END PARALLEL @@ -49,6 +51,11 @@ #else IF (ACC_ON_DEVICE (ACC_DEVICE_NVIDIA)) STOP 13 #endif +#if ACC_DEVICE_TYPE_radeon + IF (.NOT. ACC_ON_DEVICE (ACC_DEVICE_RADEON)) STOP 14 +#else + IF (ACC_ON_DEVICE (ACC_DEVICE_RADEON)) STOP 15 +#endif !$ACC END PARALLEL #endif diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-10.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-10.f90 index 2875f16..2b2f8fe 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/lib-10.f90 +++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-10.f90 @@ -15,9 +15,7 @@ program main integer, parameter :: c_size = sizeof (c) integer, parameter :: r_size = sizeof (r) - if (acc_get_num_devices (acc_device_nvidia) .eq. 0) call exit - - call acc_init (acc_device_nvidia) + call acc_init (acc_device_default) call set3d (.FALSE., a_3d_i, a_3d_c, a_3d_r) @@ -39,8 +37,6 @@ program main end do end do - call acc_shutdown (acc_device_nvidia) - contains subroutine set3d (clear, a_i, a_c, a_r) diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-14.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-14.f90 index bf35631..90c2868 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/lib-14.f90 +++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-14.f90 @@ -1,7 +1,8 @@ ! Exercise the data movement runtime library functions on non-shared memory ! targets. -! { dg-do run { target openacc_nvidia_accel_selected } } +! { dg-do run } +! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } program main use openacc diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-5.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-5.f90 index 505b2c6..08808a4 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/lib-5.f90 +++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-5.f90 @@ -6,26 +6,52 @@ program main integer n - if (acc_get_num_devices (acc_device_nvidia) .eq. 0) call exit + if (acc_get_num_devices (acc_device_nvidia) .ne. 0) then - call acc_init (acc_device_nvidia) + call acc_init (acc_device_nvidia) - n = 0 + n = 0 - call acc_set_device_num (n, acc_device_nvidia) + call acc_set_device_num (n, acc_device_nvidia) - if (acc_get_device_num (acc_device_nvidia) .ne. 0) STOP 1 + if (acc_get_device_num (acc_device_nvidia) .ne. 0) stop 11 - if (acc_get_num_devices (acc_device_nvidia) .gt. 1) then + if (acc_get_num_devices (acc_device_nvidia) .gt. 1) then - n = 1 + n = 1 - call acc_set_device_num (n, acc_device_nvidia) + call acc_set_device_num (n, acc_device_nvidia) - if (acc_get_device_num (acc_device_nvidia) .ne. 1) STOP 2 + if (acc_get_device_num (acc_device_nvidia) .ne. 1) stop 12 + + end if + + call acc_shutdown (acc_device_nvidia) end if - call acc_shutdown (acc_device_nvidia) + if (acc_get_num_devices (acc_device_radeon) .ne. 0) then + + call acc_init (acc_device_radeon) + + n = 0 + + call acc_set_device_num (n, acc_device_radeon) + + if (acc_get_device_num (acc_device_radeon) .ne. 0) stop 21 + + if (acc_get_num_devices (acc_device_radeon) .gt. 1) then + + n = 1 + + call acc_set_device_num (n, acc_device_radeon) + + if (acc_get_device_num (acc_device_radeon) .ne. 1) stop 22 + + end if + + call acc_shutdown (acc_device_radeon) + + end if end program diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-7.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-7.f90 index 2ce93c3..fa610b1 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/lib-7.f90 +++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-7.f90 @@ -6,26 +6,52 @@ program main integer n - if (acc_get_num_devices (acc_device_nvidia) .eq. 0) call exit + if (acc_get_num_devices (acc_device_nvidia) .ne. 0) then - call acc_init (acc_device_nvidia) + call acc_init (acc_device_nvidia) - n = 0 + n = 0 - call acc_set_device_num (n, acc_device_nvidia) + call acc_set_device_num (n, acc_device_nvidia) - if (acc_get_device_num (acc_device_nvidia) .ne. 0) STOP 1 + if (acc_get_device_num (acc_device_nvidia) .ne. 0) STOP 1 - if (acc_get_num_devices (acc_device_nvidia) .gt. 1) then + if (acc_get_num_devices (acc_device_nvidia) .gt. 1) then - n = 1 + n = 1 - call acc_set_device_num (n, acc_device_nvidia) + call acc_set_device_num (n, acc_device_nvidia) - if (acc_get_device_num (acc_device_nvidia) .ne. 1) STOP 2 + if (acc_get_device_num (acc_device_nvidia) .ne. 1) STOP 2 + + end if + + call acc_shutdown (acc_device_nvidia) end if - call acc_shutdown (acc_device_nvidia) + if (acc_get_num_devices (acc_device_radeon) .ne. 0) then + + call acc_init (acc_device_radeon) + + n = 0 + + call acc_set_device_num (n, acc_device_radeon) + + if (acc_get_device_num (acc_device_radeon) .ne. 0) STOP 1 + + if (acc_get_num_devices (acc_device_radeon) .gt. 1) then + + n = 1 + + call acc_set_device_num (n, acc_device_radeon) + + if (acc_get_device_num (acc_device_radeon) .ne. 1) STOP 2 + + end if + + call acc_shutdown (acc_device_radeon) + + end if end program diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-8.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-8.f90 index 263cedb..2b36b40 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/lib-8.f90 +++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-8.f90 @@ -16,9 +16,7 @@ program main integer, parameter :: c_size = sizeof (c) integer, parameter :: r_size = sizeof (r) - if (acc_get_num_devices (acc_device_nvidia) .eq. 0) call exit - - call acc_init (acc_device_nvidia) + call acc_init (acc_device_default) call set3d (.FALSE., a_3d_i, a_3d_c, a_3d_r) @@ -40,8 +38,6 @@ program main end do end do - call acc_shutdown (acc_device_nvidia) - contains subroutine set3d (clear, a_i, a_c, a_r) diff --git a/libgomp/testsuite/libgomp.oacc-fortran/parallel-dims-aux.c b/libgomp/testsuite/libgomp.oacc-fortran/parallel-dims-aux.c index b5986f4..cdece32 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/parallel-dims-aux.c +++ b/libgomp/testsuite/libgomp.oacc-fortran/parallel-dims-aux.c @@ -5,41 +5,22 @@ /* Used by 'parallel-dims.f90'. */ -#include <limits.h> -#include <openacc.h> #include <gomp-constants.h> -/* TODO: "(int) acc_device_*" casts because of the C++ acc_on_device wrapper - not behaving as expected for -O0. */ #pragma acc routine seq -/* static */ unsigned int __attribute__ ((optimize ("O2"))) acc_gang () +/* static */ int acc_gang () { - if (acc_on_device ((int) acc_device_host)) - return 0; - else if (acc_on_device ((int) acc_device_nvidia)) - return __builtin_goacc_parlevel_id (GOMP_DIM_GANG); - else - __builtin_abort (); + return __builtin_goacc_parlevel_id (GOMP_DIM_GANG); } #pragma acc routine seq -/* static */ unsigned int __attribute__ ((optimize ("O2"))) acc_worker () +/* static */ int acc_worker () { - if (acc_on_device ((int) acc_device_host)) - return 0; - else if (acc_on_device ((int) acc_device_nvidia)) - return __builtin_goacc_parlevel_id (GOMP_DIM_WORKER); - else - __builtin_abort (); + return __builtin_goacc_parlevel_id (GOMP_DIM_WORKER); } #pragma acc routine seq -/* static */ unsigned int __attribute__ ((optimize ("O2"))) acc_vector () +/* static */ int acc_vector () { - if (acc_on_device ((int) acc_device_host)) - return 0; - else if (acc_on_device ((int) acc_device_nvidia)) - return __builtin_goacc_parlevel_id (GOMP_DIM_VECTOR); - else - __builtin_abort (); + return __builtin_goacc_parlevel_id (GOMP_DIM_VECTOR); } diff --git a/libquadmath/ChangeLog b/libquadmath/ChangeLog index aa611b7..86caab8 100644 --- a/libquadmath/ChangeLog +++ b/libquadmath/ChangeLog @@ -1,3 +1,7 @@ +2021-06-08 Martin Liska <mliska@suse.cz> + + * libquadmath.texi: Fix typo. + 2021-01-05 Samuel Thibault <samuel.thibault@ens-lyon.org> * configure: Re-generate. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 06aabc5..f5febd3 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,21 @@ +2021-06-08 Thomas Rodgers <rodgert@appliantology.com> + + PR libstdc++/100889 + * include/bits/atomic_base.h (atomic_ref<_Tp*>::wait): + Change parameter type from _Tp to _Tp*. + * testsuite/29_atomics/atomic_ref/wait_notify.cc: Extend + coverage of types tested. + +2021-06-08 Thomas Rodgers <rodgert@appliantology.com> + + * include/std/barrier (__tree_barrier::_M_arrive): Remove + unnecessary hasher instantiation. + +2021-06-08 Jonathan Wakely <jwakely@redhat.com> + + * include/experimental/propagate_const (swap): Constrain. + * testsuite/experimental/propagate_const/swap/lwg3413.cc: New test. + 2021-06-07 Avi Kivity <avi@scylladb.com> PR libstdc++/100900 diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h index 73d5d7a..396872f 100644 --- a/libstdc++-v3/include/bits/allocator.h +++ b/libstdc++-v3/include/bits/allocator.h @@ -89,9 +89,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment - typedef true_type propagate_on_container_move_assignment; + using propagate_on_container_move_assignment = true_type; - typedef true_type is_always_equal; + using is_always_equal + _GLIBCXX20_DEPRECATED_SUGGEST("allocator_traits::is_always_equal") + = true_type; #if __cplusplus >= 202002L allocator() = default; @@ -157,9 +159,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment - typedef true_type propagate_on_container_move_assignment; + using propagate_on_container_move_assignment = true_type; - typedef true_type is_always_equal; + using is_always_equal + _GLIBCXX20_DEPRECATED_SUGGEST("allocator_traits::is_always_equal") + = true_type; #endif // _GLIBCXX_RESOLVE_LIB_DEFECTS diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h index 029b8ad..20cf134 100644 --- a/libstdc++-v3/include/bits/atomic_base.h +++ b/libstdc++-v3/include/bits/atomic_base.h @@ -1870,7 +1870,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cpp_lib_atomic_wait _GLIBCXX_ALWAYS_INLINE void - wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept + wait(_Tp* __old, memory_order __m = memory_order_seq_cst) const noexcept { __atomic_impl::wait(_M_ptr, __old, __m); } // TODO add const volatile overload diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index f4e94a6..8723f35 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -264,8 +264,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : __detail::__cond_value_type<typename _Tp::value_type> { }; - // LWG 3446 doesn't add this, but it's needed for the case where - // value_type and element_type are both present, but not the same type. + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3541. indirectly_readable_traits should be SFINAE-friendly for all types template<__detail::__has_member_value_type _Tp> requires __detail::__has_member_element_type<_Tp> struct indirectly_readable_traits<_Tp> diff --git a/libstdc++-v3/include/experimental/propagate_const b/libstdc++-v3/include/experimental/propagate_const index 0d03c13..162b478 100644 --- a/libstdc++-v3/include/experimental/propagate_const +++ b/libstdc++-v3/include/experimental/propagate_const @@ -113,6 +113,7 @@ inline namespace fundamentals_v2 constexpr propagate_const() = default; propagate_const(const propagate_const& __p) = delete; constexpr propagate_const(propagate_const&& __p) = default; + template <typename _Up, typename enable_if<__and_<is_constructible<_Tp, _Up&&>, is_convertible<_Up&&, _Tp>>::value, bool @@ -120,6 +121,7 @@ inline namespace fundamentals_v2 constexpr propagate_const(propagate_const<_Up>&& __pu) : _M_t(std::move(get_underlying(__pu))) {} + template <typename _Up, typename enable_if<__and_<is_constructible<_Tp, _Up&&>, __not_<is_convertible<_Up&&, _Tp>>>::value, @@ -127,6 +129,7 @@ inline namespace fundamentals_v2 constexpr explicit propagate_const(propagate_const<_Up>&& __pu) : _M_t(std::move(get_underlying(__pu))) {} + template <typename _Up, typename enable_if<__and_<is_constructible<_Tp, _Up&&>, is_convertible<_Up&&, _Tp>, @@ -136,6 +139,7 @@ inline namespace fundamentals_v2 constexpr propagate_const(_Up&& __u) : _M_t(std::forward<_Up>(__u)) {} + template <typename _Up, typename enable_if<__and_<is_constructible<_Tp, _Up&&>, __not_<is_convertible<_Up&&, _Tp>>, @@ -399,8 +403,10 @@ inline namespace fundamentals_v2 } // [propagate_const.algorithms], specialized algorithms + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3413. propagate_const's swap [...] needs to be constrained and use a trait template <typename _Tp> - constexpr void + constexpr enable_if_t<__is_swappable<_Tp>::value, void> swap(propagate_const<_Tp>& __pt, propagate_const<_Tp>& __pt2) noexcept(__is_nothrow_swappable<_Tp>::value) { diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier index fd61fb4..4210e30 100644 --- a/libstdc++-v3/include/std/barrier +++ b/libstdc++-v3/include/std/barrier @@ -103,7 +103,6 @@ It looks different from literature pseudocode for two main reasons: static_cast<__barrier_phase_t>(__old_phase_val + 2); size_t __current_expected = _M_expected; - std::hash<std::thread::id> __hasher; __current %= ((_M_expected + 1) >> 1); for (int __round = 0; ; ++__round) diff --git a/libstdc++-v3/include/std/memory_resource b/libstdc++-v3/include/std/memory_resource index d330da9..df4e806 100644 --- a/libstdc++-v3/include/std/memory_resource +++ b/libstdc++-v3/include/std/memory_resource @@ -322,6 +322,7 @@ namespace pmr #endif template<typename _Up> + _GLIBCXX20_DEPRECATED_SUGGEST("allocator_traits::destroy") __attribute__((__nonnull__)) void destroy(_Up* __p) diff --git a/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs.cc index ca4714d..4f1f46a 100644 --- a/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs.cc @@ -53,5 +53,27 @@ static_assert( is_same<allocator<int>::propagate_on_container_move_assignment, std::true_type>::value, "propagate_on_container_move_assignment" ); -static_assert( is_same<allocator<int>::is_always_equal, std::true_type>::value, - "is_always_equal" ); +using IAE = allocator<int>::is_always_equal; // { dg-warning "deprecated" "" { target c++20 } } +static_assert( is_same<IAE, std::true_type>::value, "is_always_equal" ); + + +// Test required typedefs for allocator<void> specialization. +static_assert( is_same<allocator<void>::value_type, void>::value, + "void value_type" ); +#if __cplusplus <= 201703L +static_assert( is_same<allocator<void>::pointer, void*>::value, + "void pointer" ); +static_assert( is_same<allocator<void>::const_pointer, const void*>::value, + "void const_pointer" ); +static_assert( is_same<allocator<void>::rebind<char>::other, + allocator<char>>::value, + "void rebind::other" ); +#else +// Since C++20 allocator<void> uses the primary template, so has the same types. +static_assert( is_same<allocator<void>::propagate_on_container_move_assignment, + std::true_type>::value, + "propagate_on_container_move_assignment" ); + +using VIAE = allocator<void>::is_always_equal; // { dg-warning "deprecated" "" { target c++20 } } +static_assert( is_same<VIAE, std::true_type>::value, "is_always_equal" ); +#endif diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc index 2fd3130..003b86c 100644 --- a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc +++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc @@ -26,22 +26,34 @@ #include <testsuite_hooks.h> +template<typename S> + void + test (S va, S vb) + { + S aa{ va }; + S bb{ vb }; + std::atomic_ref<S> a{ aa }; + a.wait(bb); + std::thread t([&] + { + a.store(bb); + a.notify_one(); + }); + a.wait(aa); + t.join(); + } + int main () { + test<int>(0, 42); + test<long>(0, 42); + test<unsigned>(0u, 42u); + test<float>(0.0f, 42.0f); + test<double>(0.0, 42.0); + test<void*>(nullptr, reinterpret_cast<void*>(42)); + struct S{ int i; }; - S aa{ 0 }; - S bb{ 42 }; - - std::atomic_ref<S> a{ aa }; - VERIFY( a.load().i == aa.i ); - a.wait(bb); - std::thread t([&] - { - a.store(bb); - a.notify_one(); - }); - a.wait(aa); - t.join(); + test<S>(S{ 0 }, S{ 42 }); return 0; } diff --git a/libstdc++-v3/testsuite/experimental/propagate_const/swap/lwg3413.cc b/libstdc++-v3/testsuite/experimental/propagate_const/swap/lwg3413.cc new file mode 100644 index 0000000..8dc13cf --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/propagate_const/swap/lwg3413.cc @@ -0,0 +1,41 @@ +// { dg-do compile { target c++14 } } + +// LWG 3413 +// propagate_const's swap's noexcept specification needs to be constrained +// and use a trait + +#include <experimental/propagate_const> + +using std::experimental::propagate_const; + +propagate_const<int*> i; +static_assert( noexcept(i.swap(i)), "member swap is noexcept" ); +static_assert( noexcept(swap(i, i)), "non-member swap is noexcept" ); + +struct P +{ + int i = 0; + int& operator*() const; +}; + +void swap(P&, P&) noexcept(false); + +propagate_const<P> p; +static_assert( ! noexcept(p.swap(p)), "member swap is conditionally noexcept" ); +static_assert( ! noexcept(swap(p, p)), "non-member swap is conditionally noexcept" ); + +// std::is_swappable not available for -std=c++14 +#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) +struct Q +{ + int i = 0; + int& operator*() const; + + Q& operator=(Q&&) = delete; +}; + +static_assert( ! std::is_swappable<Q>::value, "" ); + +static_assert( ! std::is_swappable<propagate_const<Q>>::value, + "non-member swap is constrained" ); +#endif |