aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-06-09 13:40:10 +0200
committerMartin Liska <mliska@suse.cz>2021-06-09 13:40:10 +0200
commit739448cd8af3b3f38e91e53e9971c9ba9dd82313 (patch)
tree18f107dde85c9da8dd70a25ec52836432a51911d
parentc7768f068398b267756b767f7d2f4d06d1292a8e (diff)
parentec748dc7dd2d8ca39dc503b2a6dfbe172127cd13 (diff)
downloadgcc-739448cd8af3b3f38e91e53e9971c9ba9dd82313.zip
gcc-739448cd8af3b3f38e91e53e9971c9ba9dd82313.tar.gz
gcc-739448cd8af3b3f38e91e53e9971c9ba9dd82313.tar.bz2
Merge branch 'master' into devel/sphinx
-rw-r--r--gcc/ChangeLog140
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/analyzer/ChangeLog46
-rw-r--r--gcc/analyzer/analyzer.h2
-rw-r--r--gcc/analyzer/region-model-manager.cc46
-rw-r--r--gcc/analyzer/region-model.cc65
-rw-r--r--gcc/analyzer/region-model.h4
-rw-r--r--gcc/analyzer/region.cc33
-rw-r--r--gcc/analyzer/store.cc224
-rw-r--r--gcc/analyzer/store.h79
-rw-r--r--gcc/analyzer/svalue.h2
-rw-r--r--gcc/c-family/c-warn.c12
-rw-r--r--gcc/config/arc/arc-protos.h1
-rw-r--r--gcc/config/arc/arc.c44
-rw-r--r--gcc/config/arc/arc.md203
-rw-r--r--gcc/config/arc/simdext.md38
-rw-r--r--gcc/config/h8300/logical.md41
-rw-r--r--gcc/config/i386/i386.c6
-rw-r--r--gcc/config/rs6000/power10.md25
-rw-r--r--gcc/config/rs6000/rs6000-p8swap.c35
-rw-r--r--gcc/cp/ChangeLog40
-rw-r--r--gcc/cp/call.c3
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/cp/parser.c4
-rw-r--r--gcc/fortran/ChangeLog16
-rw-r--r--gcc/fortran/intrinsic.texi144
-rw-r--r--gcc/fortran/trans-openmp.c190
-rw-r--r--gcc/gimple-range-gori.cc2
-rw-r--r--gcc/gimple-range.cc314
-rw-r--r--gcc/gimple-range.h101
-rw-r--r--gcc/gimple-ssa-evrp.c354
-rw-r--r--gcc/objc/ChangeLog7
-rw-r--r--gcc/objc/Make-lang.in3
-rw-r--r--gcc/objcp/ChangeLog7
-rw-r--r--gcc/objcp/Make-lang.in3
-rw-r--r--gcc/testsuite/ChangeLog96
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist124.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr60209-neg.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp23/mixed-concat1.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp23/narrowing-bool1.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp23/whitespace-splice1.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/explicit18.C23
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/enum3.C9
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C6
-rw-r--r--gcc/testsuite/g++.dg/ext/utf-badconcat.C12
-rw-r--r--gcc/testsuite/g++.dg/ext/utf-badconcat2.C12
-rw-r--r--gcc/testsuite/g++.dg/gomp/doacross-2.C16
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/bitfields-1.c144
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-1.c30
-rw-r--r--gcc/testsuite/gcc.dg/pr100887.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr100923.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100936.c34
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100951.c15
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-call.c4
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr100085.c23
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/loop-1.f907
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f902
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr100965.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr99928-1.f904
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr99928-2.f904
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr99928-3.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr99928-8.f9048
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/scan-5.f902
-rw-r--r--gcc/tree-inline.c3
-rw-r--r--gcc/tree-ssa-phiopt.c164
-rw-r--r--gcc/tree-ssa-sccvn.c76
-rw-r--r--gcc/tree-vect-generic.c34
-rw-r--r--gcc/tree-vect-slp.c152
-rw-r--r--gcc/tree-vect-stmts.c12
-rw-r--r--gcc/tree-vectorizer.h10
-rw-r--r--libgfortran/ChangeLog5
-rw-r--r--libgomp/ChangeLog101
-rw-r--r--libgomp/plugin/plugin-gcn.c5
-rw-r--r--libgomp/testsuite/lib/libgomp.exp7
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/declare-1.C2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c11
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c3
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/async_queue-1.c7
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/declare-3.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/firstprivate-1.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-11.c10
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-13.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-14.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-15.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-20.c4
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-23.c4
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-24.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-34.c4
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-42.c4
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-44.c4
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-48.c4
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-5.c20
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-52.c6
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-53.c6
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-54.c6
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-57.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-58.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-6.c47
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-62.c3
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-63.c3
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-64.c3
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-65.c3
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-67.c3
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-68.c3
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-86.c27
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-87.c27
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-88.c9
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-89.c18
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-92.c18
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/parallel-dims.c52
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/routine-wv-2.c3
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f907
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f7
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f7
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-10.f906
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-14.f903
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-5.f9046
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-7.f9046
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-8.f906
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/parallel-dims-aux.c31
-rw-r--r--libquadmath/ChangeLog4
-rw-r--r--libstdc++-v3/ChangeLog18
-rw-r--r--libstdc++-v3/include/bits/allocator.h12
-rw-r--r--libstdc++-v3/include/bits/atomic_base.h2
-rw-r--r--libstdc++-v3/include/bits/iterator_concepts.h4
-rw-r--r--libstdc++-v3/include/experimental/propagate_const8
-rw-r--r--libstdc++-v3/include/std/barrier1
-rw-r--r--libstdc++-v3/include/std/memory_resource1
-rw-r--r--libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs.cc26
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc38
-rw-r--r--libstdc++-v3/testsuite/experimental/propagate_const/swap/lwg3413.cc41
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