diff options
author | Martin Liska <mliska@suse.cz> | 2021-05-17 15:53:06 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-05-17 15:53:06 +0200 |
commit | 6ec928c2ae25f84be1ca022be60dadea5140c155 (patch) | |
tree | e59b3c930c84acb9b96fc18cd13883411af91e27 /gcc | |
parent | 9c217a1395dad1fa1cf9c3e3ac6e3a330cb003ae (diff) | |
parent | e0a5daf81f2c79a0275eccd7c1a25349990a7a4d (diff) | |
download | gcc-6ec928c2ae25f84be1ca022be60dadea5140c155.zip gcc-6ec928c2ae25f84be1ca022be60dadea5140c155.tar.gz gcc-6ec928c2ae25f84be1ca022be60dadea5140c155.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc')
189 files changed, 8033 insertions, 1246 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 02e66c8..eeb293a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,506 @@ +2021-05-16 Christophe Lyon <christophe.lyon@linaro.org> + + * config/arm/arm.h (CPP_SPEC): Remove error message about + -mlittle-endian/-mbig-endian conflict. + +2021-05-15 Bill Schmidt <wschmidt@linux.ibm.com> + + * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Define + __ROP_PROTECT__ if -mrop-protect is selected. + +2021-05-15 Bill Schmidt <wschmidt@linux.ibm.com> + + * config/rs6000/rs6000-internal.h (rs6000_stack): Add + rop_hash_save_offset and rop_hash_size. + * config/rs6000/rs6000-logue.c (rs6000_stack_info): Compute + rop_hash_size and rop_hash_save_offset. + (debug_stack_info): Dump rop_hash_save_offset and rop_hash_size. + (rs6000_emit_prologue): Emit hashst[p] in prologue. + (rs6000_emit_epilogue): Emit hashchk[p] in epilogue. + * config/rs6000/rs6000.md (unspec): Add UNSPEC_HASHST and + UNSPEC_HASHCHK. + (hashst): New define_insn. + (hashchk): Likewise. + +2021-05-15 Bill Schmidt <wschmidt@linux.ibm.com> + + * config/rs6000/rs6000.c (rs6000_option_override_internal): + Disable shrink wrap when inserting ROP-protect instructions. + * config/rs6000/rs6000.opt (mrop-protect): New option. + (mprivileged): Likewise. + * doc/invoke.texi: Document mrop-protect and mprivileged. + +2021-05-15 Hans-Peter Nilsson <hp@axis.com> + + * reorg.c (fill_slots_from_thread): Reinstate code typoed out in + "Remove CC0". + +2021-05-15 Martin Jambor <mjambor@suse.cz> + + Revert: + 2021-05-13 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/100453 + * tree-sra.c (sra_modify_assign): All const base accesses do not + need refreshing, not just those from decl_pool. + (sra_modify_assign): Do not refresh into a const base decl. + +2021-05-15 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/100342 + * regcprop.c (copy_value): When copying a source reg in a wider + mode than it has recorded for the value, adjust recorded destination + mode too or punt if !REG_CAN_CHANGE_MODE_P. + +2021-05-14 Jason Merrill <jason@redhat.com> + + * intl.h: Add comments. + +2021-05-14 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * config/aarch64/aarch64-simd.md + (aarch64_sqdml<SBINQOPS:as>l2_lane<mode>_internal): Split into... + (aarch64_sqdmlsl2_lane<mode>_internal): ... This... + (aarch64_sqdmlal2_lane<mode>_internal): ... And this. + (aarch64_sqdml<SBINQOPS:as>l2_laneq<mode>_internal): Split into ... + (aarch64_sqdmlsl2_laneq<mode>_internal): ... This... + (aarch64_sqdmlal2_laneq<mode>_internal): ... And this. + (aarch64_sqdml<SBINQOPS:as>l2_n<mode>_internal): Split into... + (aarch64_sqdmlsl2_n<mode>_internal): ... This... + (aarch64_sqdmlal2_n<mode>_internal): ... And this. + +2021-05-14 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> + + PR target/66791 + * config/arm/arm_neon.h (vtst_s8): Replace call to vtst builtin with it's + boolean logic equivalent. + (vtst_s16): Likewise. + (vtst_s32): Likewise. + (vtst_u8): Likewise. + (vtst_u16): Likewise. + (vtst_u32): Likewise. + (vtst_p8): Likewise. + (vtst_p16): Likewise. + (vtstq_s8): Likewise. + (vtstq_s16): Likewise. + (vtstq_s32): Likewise. + (vtstq_u8): Likewise. + (vtstq_u16): Likewise. + (vtstq_u32): Likewise. + (vtstq_p8): Likewise. + (vtstq_p16): Likewise. + * config/arm/arm_neon_builtins.def: Remove entry for vtst. + * config/arm/neon.md (neon_vtst<mode>): Remove pattern. + +2021-05-14 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * config/aarch64/aarch64-simd.md (aarch64_sqdmlal2<mode>): Merge into... + (aarch64_sqdml<SBINQOPS:as>l2<mode>): ... This. + (aarch64_sqdmlsl2<mode>): Delete. + (aarch64_sqdmlal2_lane<mode>): Merge this... + (aarch64_sqdmlsl2_lane<mode>): ... And this... + (aarch64_sqdml<SBINQOPS:as>l2_lane<mode>): ... Into this. + (aarch64_sqdmlal2_laneq<mode>): Merge this... + (aarch64_sqdmlsl2_laneq<mode>): ... And this... + (aarch64_sqdml<SBINQOPS:as>l2_laneq<mode>): ... Into this. + (aarch64_sqdmlal2_n<mode>): Merge this... + (aarch64_sqdmlsl2_n<mode>): ... And this... + (aarch64_sqdml<SBINQOPS:as>l2_n<mode>): ... Into this. + +2021-05-13 Martin Sebor <msebor@redhat.com> + + PR middle-end/100574 + * builtins.c (access_ref::get_ref): Improve detection of PHIs with + all null arguments. + +2021-05-13 Martin Sebor <msebor@redhat.com> + + PR tree-optimization/93100 + PR middle-end/98583 + * tree-ssa-uninit.c (check_defs): Exclude intrinsic functions that + don't modify referenced objects. + +2021-05-13 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/100453 + * tree-sra.c (sra_modify_assign): All const base accesses do not + need refreshing, not just those from decl_pool. + (sra_modify_assign): Do not refresh into a const base decl. + +2021-05-13 Martin Liska <mliska@suse.cz> + + * tree-ssa-dom.c: Remove m_simplifier. + +2021-05-13 Richard Earnshaw <rearnsha@arm.com> + + PR target/100563 + * config/arm/arm.c (arm_canonicalize_comparison): Correctly + canonicalize DImode inequality comparisons against the + maximum integral value. + +2021-05-13 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/98856 + * config/i386/i386.c (ix86_shift_rotate_cost): Add CODE argument. + Expect V2DI and V4DI arithmetic right shifts to be emulated. + (ix86_rtx_costs, ix86_add_stmt_cost): Adjust ix86_shift_rotate_cost + caller. + * config/i386/i386-expand.c (expand_vec_perm_2perm_interleave, + expand_vec_perm_2perm_pblendv): New functions. + (ix86_expand_vec_perm_const_1): Use them. + * config/i386/sse.md (ashr<mode>3<mask_name>): Rename to ... + (<mask_codefor>ashr<mode>3<mask_name>): ... this. + (ashr<mode>3): New define_expand with VI248_AVX512BW iterator. + (ashrv4di3): New define_expand. + (ashrv2di3): Change condition to TARGET_SSE2, handle !TARGET_XOP + and !TARGET_AVX512VL expansion. + +2021-05-13 Uroš Bizjak <ubizjak@gmail.com> + + PR target/100581 + * config/i386/i386-expand.c (ix86_expand_sse_movcc): Force mode + sizes < 16 to a register when constructing vpcmov pattern. + * config/i386/mmx.md (*xop_pcmov_<mode>): Use MMXMODE124 mode. + +2021-05-13 Martin Liska <mliska@suse.cz> + + * gcov-io.c (gcov_write_block): Remove. + (gcov_write_words): Likewise. + (gcov_read_words): Re-implement using gcov_read_bytes. + (gcov_allocate): Remove. + (GCOV_BLOCK_SIZE): Likewise. + (struct gcov_var): Remove most of the fields. + (gcov_position): Implement with ftell. + (gcov_rewrite): Remove setting of start and offset fields. + (from_file): Re-format. + (gcov_open): Remove setbuf call. It should not be needed. + (gcov_close): Remove internal buffer handling. + (gcov_magic): Use __builtin_bswap32. + (gcov_write_counter): Use directly gcov_write_unsigned. + (gcov_write_string): Use direct fwrite and do not round + to 4 bytes. + (gcov_seek): Use directly fseek. + (gcov_write_tag): Use gcov_write_unsigned directly. + (gcov_write_length): Likewise. + (gcov_write_tag_length): Likewise. + (gcov_read_bytes): Use directly fread. + (gcov_read_unsigned): Use gcov_read_words. + (gcov_read_counter): Likewise. + (gcov_read_string): Use gcov_read_bytes. + * gcov-io.h (GCOV_WORD_SIZE): Adjust to reflect + that size is not in bytes, but words (4B). + (GCOV_TAG_FUNCTION_LENGTH): Likewise. + (GCOV_TAG_ARCS_LENGTH): Likewise. + (GCOV_TAG_ARCS_NUM): Likewise. + (GCOV_TAG_COUNTER_LENGTH): Likewise. + (GCOV_TAG_COUNTER_NUM): Likewise. + (GCOV_TAG_SUMMARY_LENGTH): Likewise. + +2021-05-13 liuhongt <hongtao.liu@intel.com> + + PR target/94680 + * config/i386/sse.md (ssedoublevecmode): Add attribute for + V64QI/V32HI/V16SI/V4DI. + (ssehalfvecmode): Add attribute for V2DI/V2DF. + (*vec_concatv4si_0): Extend to VI124_128. + (*vec_concat<mode>_0): New pre-reload splitter. + * config/i386/predicates.md (movq_parallel): New predicate. + +2021-05-13 Alexandre Oliva <oliva@adacore.com> + + * targhooks.c (default_zero_call_used_regs): Retry using + successfully-zeroed registers as sources. + +2021-05-12 Tobias Burnus <tobias@codesourcery.com> + + * omp-low.c (finish_taskreg_scan): Use the proper detach decl. + +2021-05-12 Aldy Hernandez <aldyh@redhat.com> + + PR c/100521 + * gimple-range.cc (range_of_builtin_call): Skip out on + processing __builtin_clz when varying. + +2021-05-12 Tom de Vries <tdevries@suse.de> + + PR target/96005 + * config/nvptx/nvptx-opts.h (enum ptx_version): New enum. + * config/nvptx/nvptx.c (nvptx_file_start): Print .version according + to ptx_version_option. + * config/nvptx/nvptx.h (TARGET_PTX_6_3): Define. + * config/nvptx/nvptx.md (define_insn "nvptx_shuffle<mode>") + (define_insn "nvptx_vote_ballot"): Use sync variant for + TARGET_PTX_6_3. + * config/nvptx/nvptx.opt (ptx_version): Add enum. + (mptx): Add option. + * doc/invoke.texi (Nvidia PTX Options): Add mptx item. + +2021-05-12 Richard Biener <rguenther@suse.de> + + PR tree-optimization/100566 + * tree-ssa-sccvn.c (dominated_by_p_w_unex): Properly handle + allow_back for all edge queries. + +2021-05-12 liuhongt <hongtao.liu@intel.com> + + PR target/99908 + * config/i386/sse.md (<sse4_1_avx2>_pblendvb): Add + splitters for pblendvb of NOT mask register. + +2021-05-12 Richard Biener <rguenther@suse.de> + + PR tree-optimization/100519 + * tree-ssa-reassoc.c (can_associate_p): Split into... + (can_associate_op_p): ... this + (can_associate_type_p): ... and this. + (is_reassociable_op): Call can_associate_op_p. + (break_up_subtract_bb): Call the appropriate predicates. + (reassociate_bb): Likewise. + +2021-05-12 Martin Liska <mliska@suse.cz> + + * lto-wrapper.c (merge_and_complain): Merge -flto=arg options. + (run_gcc): Use -flto argument detection for merged + fdecoded_options. + +2021-05-12 Martin Liska <mliska@suse.cz> + + * lto-wrapper.c (print_lto_docs_link): New function. + (run_gcc): Print warning about missing job server detection + after we know NR of partitions. Do the same for -flto{,=1}. + * opts.c (get_option_html_page): Support -flto option. + +2021-05-12 Martin Liska <mliska@suse.cz> + + * lto-wrapper.c (get_options_from_collect_gcc_options): Change + return type. + (append_option): Remove. + (find_option): Rework to use the vector type. + (remove_option): Remove. + (merge_and_complain): Use vectors for cl_decoded_option data + type arguments. + (append_compiler_options): Likewise. + (append_diag_options): Likewise. + (append_linker_options): Likewise. + (append_offload_options): Likewise. + (compile_offload_image): Likewise. + (compile_images_for_offload_targets): Likewise. + (find_and_merge_options): Likewise. + (run_gcc): Likewise. + +2021-05-12 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR debug/100515 + * dwarf2out.c (dwarf2out_finish): Set + have_multiple_function_sections with multi-range text_section. + +2021-05-12 Martin Liska <mliska@suse.cz> + + PR bootstrap/100560 + * Makefile.in: Remove version.h from linker command line. + +2021-05-12 Richard Biener <rguenther@suse.de> + + PR middle-end/100547 + * rtl.h (rtvec_alloc): Make argument size_t. + * rtl.c (rtvec_alloc): Verify the count is less than INT_MAX. + +2021-05-12 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/100508 + * cfgexpand.c (expand_debug_expr): For DEBUG_EXPR_DECL with vector + type, don't reuse DECL_RTL if it has different mode, instead force + creation of a new DEBUG_EXPR. + +2021-05-12 Jakub Jelinek <jakub@redhat.com> + Marc Glisse <marc.glisse@inria.fr> + + PR tree-optimization/94589 + * match.pd ((X & Y) == X -> (X & ~Y) == 0, + (X | Y) == Y -> (X & ~Y) == 0): New GIMPLE simplifications. + +2021-05-12 Uroš Bizjak <ubizjak@gmail.com> + + PR target/98218 + * config/i386/i386-expand.c (ix86_expand_sse_movcc): Handle V2SF mode. + * config/i386/mmx.md (MMXMODE124): New mode iterator. + (V2FI): Ditto. + (mmxintvecmode): New mode attribute. + (mmxintvecmodelower): Ditto. + (*mmx_maskcmpv2sf3_comm): New insn pattern. + (*mmx_maskcmpv2sf3): Ditto. + (vec_cmpv2sfv2si): New expander. + (vcond<V2FI:mode>v2si): Ditto. + (mmx_vlendvps): New insn pattern. + (vcond<MMXMODE124:mode><MMXMODEI:mode>): Also handle V2SFmode. + (vcondu<MMXMODE124:mode><MMXMODEI:mode>): Ditto. + (vcond_mask_<mode><mmxintvecmodelower>): Ditto. + +2021-05-11 Martin Sebor <msebor@redhat.com> + + PR middle-end/21433 + * expr.c (expand_expr_real_1): Replace unreachable code with an assert. + +2021-05-11 Richard Biener <rguenther@suse.de> + + * gimple-fold.c (gimple_fold_call): Do not call + maybe_fold_reference on call arguments or the static chain. + (fold_stmt_1): Do not call maybe_fold_reference on GIMPLE_ASM + inputs. + +2021-05-11 Martin Liska <mliska@suse.cz> + + * builtins.def (DEF_HSAIL_BUILTIN): Remove. + (DEF_HSAIL_ATOMIC_BUILTIN): Likewise. + (DEF_HSAIL_SAT_BUILTIN): Likewise. + (DEF_HSAIL_INTR_BUILTIN): Likewise. + (DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN): Likewise. + * doc/frontends.texi: Remove BRIG. + * doc/install.texi: Likewise. + * doc/invoke.texi: Likewise. + * doc/standards.texi: Likewise. + * brig-builtins.def: Removed. + * brig/ChangeLog: Removed. + * brig/Make-lang.in: Removed. + * brig/brig-builtins.h: Removed. + * brig/brig-c.h: Removed. + * brig/brig-lang.c: Removed. + * brig/brigfrontend/brig-arg-block-handler.cc: Removed. + * brig/brigfrontend/brig-atomic-inst-handler.cc: Removed. + * brig/brigfrontend/brig-basic-inst-handler.cc: Removed. + * brig/brigfrontend/brig-branch-inst-handler.cc: Removed. + * brig/brigfrontend/brig-cmp-inst-handler.cc: Removed. + * brig/brigfrontend/brig-code-entry-handler.cc: Removed. + * brig/brigfrontend/brig-code-entry-handler.h: Removed. + * brig/brigfrontend/brig-comment-handler.cc: Removed. + * brig/brigfrontend/brig-control-handler.cc: Removed. + * brig/brigfrontend/brig-copy-move-inst-handler.cc: Removed. + * brig/brigfrontend/brig-cvt-inst-handler.cc: Removed. + * brig/brigfrontend/brig-fbarrier-handler.cc: Removed. + * brig/brigfrontend/brig-function-handler.cc: Removed. + * brig/brigfrontend/brig-function.cc: Removed. + * brig/brigfrontend/brig-function.h: Removed. + * brig/brigfrontend/brig-inst-mod-handler.cc: Removed. + * brig/brigfrontend/brig-label-handler.cc: Removed. + * brig/brigfrontend/brig-lane-inst-handler.cc: Removed. + * brig/brigfrontend/brig-machine.c: Removed. + * brig/brigfrontend/brig-machine.h: Removed. + * brig/brigfrontend/brig-mem-inst-handler.cc: Removed. + * brig/brigfrontend/brig-module-handler.cc: Removed. + * brig/brigfrontend/brig-queue-inst-handler.cc: Removed. + * brig/brigfrontend/brig-seg-inst-handler.cc: Removed. + * brig/brigfrontend/brig-signal-inst-handler.cc: Removed. + * brig/brigfrontend/brig-to-generic.cc: Removed. + * brig/brigfrontend/brig-to-generic.h: Removed. + * brig/brigfrontend/brig-util.cc: Removed. + * brig/brigfrontend/brig-util.h: Removed. + * brig/brigfrontend/brig-variable-handler.cc: Removed. + * brig/brigfrontend/hsa-brig-format.h: Removed. + * brig/brigfrontend/phsa.h: Removed. + * brig/brigspec.c: Removed. + * brig/config-lang.in: Removed. + * brig/gccbrig.texi: Removed. + * brig/lang-specs.h: Removed. + * brig/lang.opt: Removed. + +2021-05-11 Richard Biener <rguenther@suse.de> + + PR ipa/100513 + * ipa-param-manipulation.c + (ipa_param_body_adjustments::modify_call_stmt): Avoid + altering SSA_NAME_DEF_STMT by adjusting the calls LHS + via gimple_call_lhs_ptr. + +2021-05-11 Alex Coplan <alex.coplan@arm.com> + + PR target/99725 + * config/arm/arm.c (cmse_nonsecure_call_inline_register_clear): + Avoid emitting CFA adjusts on the sp if we have the fp. + +2021-05-11 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/iterators.md (VMUL_CHANGE_NLANES): Delete. + (VMULD): New iterator. + (VCOND): Handle V4HF and V8HF. + (VCONQ): Fix entry for V2SF. + * config/aarch64/aarch64-simd.md (mul_lane<mode>3): Use VMULD + instead of VMUL. Use a 64-bit vector mode for the indexed operand. + (*aarch64_mul3_elt_<vswap_width_name><mode>): Merge with... + (mul_laneq<mode>3): ...this define_insn. Use VMUL instead of VDQSF. + Use a 128-bit vector mode for the indexed operand. Use stype for + the scheduling type. + +2021-05-11 Richard Biener <rguenther@suse.de> + + * gimple-fold.c (maybe_fold_reference): Only return + is_gimple_min_invariant values. + +2021-05-11 Richard Biener <rguenther@suse.de> + + PR middle-end/100509 + * gimple-fold.c (fold_gimple_assign): Only call + get_symbol_constant_value on register type symbols. + +2021-05-11 Srinath Parvathaneni <srinath.parvathaneni@arm.com> + Joe Ramsay <joe.ramsay@arm.com> + + PR target/100419 + * config/arm/arm_mve.h (__arm_vstrwq_scatter_offset): Fix wrong arguments. + (__arm_vcmpneq): Remove duplicate definition. + (__arm_vstrwq_scatter_offset_p): Likewise. + (__arm_vmaxq_x): Likewise. + (__arm_vmlsdavaq): Likewise. + (__arm_vmlsdavaxq): Likewise. + (__arm_vmlsdavq_p): Likewise. + (__arm_vmlsdavxq_p): Likewise. + (__arm_vrmlaldavhaq): Likewise. + (__arm_vstrbq_p): Likewise. + (__arm_vstrbq_scatter_offset): Likewise. + (__arm_vstrbq_scatter_offset_p): Likewise. + (__arm_vstrdq_scatter_offset): Likewise. + (__arm_vstrdq_scatter_offset_p): Likewise. + (__arm_vstrdq_scatter_shifted_offset): Likewise. + (__arm_vstrdq_scatter_shifted_offset_p): Likewise. + +2021-05-11 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/100471 + * omp-low.c (lower_omp_task_reductions): For OMP_TASKLOOP, if data + is 0, bypass the reduction loop including + GOMP_taskgroup_reduction_unregister call. + +2021-05-11 Kewen Lin <linkw@linux.ibm.com> + + * config/rs6000/rs6000.c (struct rs6000_cost_data): New member + costing_for_scalar. + (rs6000_density_test): Early return if costing_for_scalar is true. + (rs6000_init_cost): Init costing_for_scalar of rs6000_cost_data. + +2021-05-11 Kewen Lin <linkw@linux.ibm.com> + + * doc/tm.texi: Regenerated. + * target.def (init_cost): Add new parameter costing_for_scalar. + * targhooks.c (default_init_cost): Adjust for new parameter. + * targhooks.h (default_init_cost): Likewise. + * tree-vect-loop.c (_loop_vec_info::_loop_vec_info): Likewise. + (vect_compute_single_scalar_iteration_cost): Likewise. + (vect_analyze_loop_2): Likewise. + * tree-vect-slp.c (_bb_vec_info::_bb_vec_info): Likewise. + (vect_bb_vectorization_profitable_p): Likewise. + * tree-vectorizer.h (init_cost): Likewise. + * config/aarch64/aarch64.c (aarch64_init_cost): Likewise. + * config/i386/i386.c (ix86_init_cost): Likewise. + * config/rs6000/rs6000.c (rs6000_init_cost): Likewise. + +2021-05-11 Kewen Lin <linkw@linux.ibm.com> + + * config/rs6000/rs6000.c (rs6000_vect_nonmem): Renamed to + vect_nonmem and moved into... + (struct rs6000_cost_data): ...here. + (rs6000_init_cost): Use vect_nonmem of cost_data instead. + (rs6000_add_stmt_cost): Likewise. + (rs6000_finish_cost): Likewise. + 2021-05-10 Eric Botcazou <ebotcazou@adacore.com> * range-op.cc (get_bool_state): Adjust head comment. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index abf046d..915a0b2 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210511 +20210517 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 487db22..1b5d3f4 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2942,10 +2942,10 @@ build/genmatch$(build_exeext) : $(BUILD_CPPLIB) \ # These programs are not linked with the MD reader. build/gengtype$(build_exeext) : build/gengtype-lex.o build/gengtype-parse.o \ - build/gengtype-state.o version.h build/errors.o + build/gengtype-state.o build/errors.o gengtype$(exeext) : gengtype.o gengtype-lex.o gengtype-parse.o \ - gengtype-state.o version.h errors.o $(LIBDEPS) + gengtype-state.o errors.o $(LIBDEPS) +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \ $(filter-out ($LIBDEPS), $^) $(LIBS) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b956fea..5146820 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,11 +1,48 @@ +2021-05-14 Martin Liska <mliska@suse.cz> + + * doc/Makefile: Add gnat-style target. + * doc/share/conf.py: Likewise. + * doc/gnat-style.rst: New file. + +2021-05-12 Bob Duff <duff@adacore.com> + + PR ada/100564 + * atree.adb (Change_Node): Do not call Zero_Slots on a Node_Id + when the Nkind has not yet been set; call the other Zero_Slots + that takes a range of slot offsets. Call the new Mutate_Kind + that takes an Old_Size, for the same reason -- the size cannot + be computed without the Nkind. + (Mutate_Nkind): New function that allows specifying the Old_Size. + (Size_In_Slots): Assert that the Nkind has proper (nonzero) value. + * atree.ads: Minor reformatting. + +2021-05-12 Martin Liska <mliska@suse.cz> + + * doc/share/conf.py: Do not use binary mode. + Do not use u' literals as Python3 uses unicode by default. + +2021-05-11 Martin Liska <mliska@suse.cz> + + * gcc-interface/ada-tree.h (BUILT_IN_LIKELY): Use builtins + from COROUTINES. + (BUILT_IN_UNLIKELY): Likewise. + +2021-05-11 Eric Botcazou <ebotcazou@adacore.com> + + * gnatvsn.adb (Version_String): Rename to... + (C_Version_String): ...this. + (Gnat_Version_String): Adjust to above renaming. + * version.c : Fix formatting glitches. + 2021-05-10 Martin Liska <mliska@suse.cz> PR bootstrap/100506 * Make-generated.in: Replace version.c with ada/version.c. - * gcc-interface/Make-lang.in: Add version.o to GNAT1_C_OBJS. - Add version.o to GNAT_ADA_OBJS and GNATBIND_OBJS. - * gcc-interface/Makefile.in: Add version.o to TOOLS_LIBS. - * gnatvsn.adb: Start using a new C symbol gnat_version_string. + * gcc-interface/Make-lang.in: Add version.o to GNAT1_C_OBJS and + GNATBIND_OBJS. + * gcc-interface/Makefile.in: Replace version.c with ada/version.c. + Add version.o to TOOLS_LIBS. + * gnatvsn.adb: Replace version_string with gnat_version_string. * version.c: New file. 2021-05-10 Eric Botcazou <ebotcazou@adacore.com> diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb index 4d4dc43..608819b 100644 --- a/gcc/ada/atree.adb +++ b/gcc/ada/atree.adb @@ -216,6 +216,13 @@ package body Atree is -- cannot be used to modify an already-initialized Nkind field. See also -- Mutate_Nkind. + procedure Mutate_Nkind + (N : Node_Id; Val : Node_Kind; Old_Size : Field_Offset); + -- Called by the other Mutate_Nkind to do all the work. This is needed + -- because the call in Change_Node, which calls this one directly, happens + -- after zeroing N's slots, which destroys its Nkind, which prevents us + -- from properly computing Old_Size. + package Field_Checking is function Field_Present (Kind : Node_Kind; Field : Node_Field) return Boolean; @@ -868,9 +875,8 @@ package body Atree is end Init_Nkind; procedure Mutate_Nkind - (N : Node_Id; Val : Node_Kind) + (N : Node_Id; Val : Node_Kind; Old_Size : Field_Offset) is - Old_Size : constant Field_Offset := Size_In_Slots (N); New_Size : constant Field_Offset := Size_In_Slots_To_Alloc (Val); All_Node_Offsets : Node_Offsets.Table_Type renames @@ -905,6 +911,11 @@ package body Atree is pragma Debug (Validate_Node_Write (N)); end Mutate_Nkind; + procedure Mutate_Nkind (N : Node_Id; Val : Node_Kind) is + begin + Mutate_Nkind (N, Val, Old_Size => Size_In_Slots (N)); + end Mutate_Nkind; + Ekind_Offset : constant Field_Offset := Entity_Field_Descriptors (Ekind).Offset; @@ -998,13 +1009,19 @@ package body Atree is end if; if New_Size > Old_Size then - pragma Debug (Zero_Slots (N)); - Node_Offsets.Table (N) := Alloc_Slots (New_Size); - end if; + declare + New_Offset : constant Field_Offset := Alloc_Slots (New_Size); + begin + pragma Debug (Zero_Slots (N)); + Node_Offsets.Table (N) := New_Offset; + Zero_Slots (New_Offset, New_Offset + New_Size - 1); + end; - Zero_Slots (N); + else + Zero_Slots (N); + end if; - Mutate_Nkind (N, New_Kind); + Mutate_Nkind (N, New_Kind, Old_Size); Set_Sloc (N, Save_Sloc); Set_In_List (N, Save_In_List); @@ -2125,6 +2142,7 @@ package body Atree is function Size_In_Slots (N : Node_Or_Entity_Id) return Field_Offset is begin + pragma Assert (Nkind (N) /= N_Unused_At_Start); return (if Nkind (N) in N_Entity then Einfo.Entities.Max_Entity_Size else Sinfo.Nodes.Size (Nkind (N))); diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads index efb8ca2..e2d3492 100644 --- a/gcc/ada/atree.ads +++ b/gcc/ada/atree.ads @@ -571,8 +571,7 @@ package Atree is (N : Entity_Id; Field : Entity_Field) return Boolean; -- True if the field value is the initial zero value - procedure Mutate_Nkind - (N : Node_Id; Val : Node_Kind) with Inline; + procedure Mutate_Nkind (N : Node_Id; Val : Node_Kind) with Inline; -- There is no Set_Nkind in Sinfo.Nodes. We use this instead. This is here, -- and has a different name, because it does some extra checking. Nkind is -- like a discriminant, in that it controls which fields exist, and that diff --git a/gcc/ada/doc/Makefile b/gcc/ada/doc/Makefile index 9a435eb..4adfd36 100644 --- a/gcc/ada/doc/Makefile +++ b/gcc/ada/doc/Makefile @@ -14,7 +14,7 @@ ALLSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) \ -c $(SOURCEDIR)/share \ -d $(BUILDDIR)/$*/doctrees \ $(SOURCEDIR) -DOC_LIST=gnat_rm gnat_ugn +DOC_LIST=gnat_rm gnat_ugn gnat-style FMT_LIST=html pdf txt info .PHONY: help clean diff --git a/gcc/ada/doc/gnat-style.rst b/gcc/ada/doc/gnat-style.rst new file mode 100644 index 0000000..527e7ba --- /dev/null +++ b/gcc/ada/doc/gnat-style.rst @@ -0,0 +1,691 @@ +GNAT Coding Style: A Guide for GNAT Developers +============================================== + +General +------- + +Most of GNAT is written in Ada using a consistent style to ensure +readability of the code. This document has been written to help +maintain this consistent style, while having a large group of developers +work on the compiler. + +For the coding style in the C parts of the compiler and run time, +see the GNU Coding Guidelines. + +This document is structured after the Ada Reference Manual. +Those familiar with that document should be able to quickly +lookup style rules for particular constructs. + +Lexical Elements +---------------- + +Character Set and Separators +**************************** + +.. index:: Character set +.. index:: ASCII +.. index:: Separators +.. index:: End-of-line +.. index:: Line length +.. index:: Indentation + +* The character set used should be plain 7-bit ASCII. + The only separators allowed are space and the end-of-line sequence. + No other control character or format effector (such as ``HT``, + ``VT``, ``FF`` ) + should be used. + The normal end-of-line sequence is used, which may be + ``LF``, ``CR/LF`` or ``CR``, + depending on the host system. An optional ``SUB`` + ( ``16#1A#`` ) may be present as the + last character in the file on hosts using that character as file terminator. + +* Files that are checked in or distributed should be in host format. + +* A line should never be longer than 79 characters, not counting the line + separator. + +* Lines must not have trailing blanks. + +* Indentation is 3 characters per level for ``if`` statements, loops, and + ``case`` statements. + For exact information on required spacing between lexical + elements, see file style.adb. + + .. index:: style.adb file + +Identifiers +*********** + +* Identifiers will start with an upper case letter, and each letter following + an underscore will be upper case. + + .. index:: Casing (for identifiers) + + Short acronyms may be all upper case. + All other letters are lower case. + An exception is for identifiers matching a foreign language. In particular, + we use all lower case where appropriate for C. + +* Use underscores to separate words in an identifier. + + .. index:: Underscores + +* Try to limit your use of abbreviations in identifiers. + It is ok to make a few abbreviations, explain what they mean, and then + use them frequently, but don't use lots of obscure abbreviations. An + example is the ``ALI`` word which stands for Ada Library + Information and is by convention always written in upper-case when + used in entity names. + + .. code-block:: ada + + procedure Find_ALI_Files; + +* Don't use the variable name ``I``, use ``J`` instead; ``I`` is too + easily confused with ``1`` in some fonts. Similarly don't use the + variable ``O``, which is too easily mistaken for the number ``0``. + +Numeric Literals +**************** + +* Numeric literals should include underscores where helpful for + readability. + + .. index:: Underscores + + .. code-block:: ada + + 1_000_000 + 16#8000_0000# + 3.14159_26535_89793_23846 + +Reserved Words +************** + +* Reserved words use all lower case. + + .. index:: Casing (for reserved words) + + .. code-block:: ada + + return else + +* The words ``Access``, ``Delta`` and ``Digits`` are + capitalized when used as attribute_designator. + +Comments +******** + +* A comment starts with ``--`` followed by two spaces. + The only exception to this rule (i.e. one space is tolerated) is when the + comment ends with a single space followed by ``--``. + It is also acceptable to have only one space between ``--`` and the start + of the comment when the comment is at the end of a line, + after some Ada code. + +* Every sentence in a comment should start with an upper-case letter (including + the first letter of the comment). + + .. index:: Casing (in comments) + +* When declarations are commented with 'hanging' comments, i.e. + comments after the declaration, there is no blank line before the + comment, and if it is absolutely necessary to have blank lines within + the comments, e.g. to make paragraph separations within a single comment, + these blank lines *do* have a ``--`` (unlike the + normal rule, which is to use entirely blank lines for separating + comment paragraphs). The comment starts at same level of indentation + as code it is commenting. + + .. index:: Blank lines (in comments) + .. index:: Indentation + + .. code-block:: ada + + z : Integer; + -- Integer value for storing value of z + -- + -- The previous line was a blank line. + +* Comments that are dubious or incomplete, or that comment on possibly + wrong or incomplete code, should be preceded or followed by ``???``. + +* Comments in a subprogram body must generally be surrounded by blank lines. + An exception is a comment that follows a line containing a single keyword + ( ``begin``, ``else``, ``loop`` ): + + .. code-block:: ada + + begin + -- Comment for the next statement + + A := 5; + + -- Comment for the B statement + + B := 6; + end; + +* In sequences of statements, comments at the end of the lines should be + aligned. + + .. index:: Alignment (in comments) + + .. code-block:: ada + + My_Identifier := 5; -- First comment + Other_Id := 6; -- Second comment + +* Short comments that fit on a single line are *not* ended with a + period. Comments taking more than a line are punctuated in the normal + manner. + +* Comments should focus on *why* instead of *what*. + Descriptions of what subprograms do go with the specification. + +* Comments describing a subprogram spec should specifically mention the + formal argument names. General rule: write a comment that does not + depend on the names of things. The names are supplementary, not + sufficient, as comments. + +* *Do not* put two spaces after periods in comments. + +Declarations and Types +---------------------- + +* In entity declarations, colons must be surrounded by spaces. Colons + should be aligned. + + .. index:: Alignment (in declarations) + + .. code-block:: ada + + Entity1 : Integer; + My_Entity : Integer; + +* Declarations should be grouped in a logical order. + Related groups of declarations may be preceded by a header comment. + +* All local subprograms in a subprogram or package body should be declared + before the first local subprogram body. + +* Do not declare local entities that hide global entities. + + .. index:: Hiding of outer entities + +* Do not declare multiple variables in one declaration that spans lines. + Start a new declaration on each line, instead. + +* The defining_identifiers of global declarations serve as + comments of a sort. So don't choose terse names, but look for names + that give useful information instead. + +* Local names can be shorter, because they are used only within + one context, where comments explain their purpose. + +* When starting an initialization or default expression on the line that follows + the declaration line, use 2 characters for indentation. + + .. code-block:: ada + + Entity1 : Integer := + Function_Name (Parameters, For_Call); + +* If an initialization or default expression needs to be continued on subsequent + lines, the continuations should be indented from the start of the expression. + + .. code-block:: ada + + Entity1 : Integer := Long_Function_Name + (parameters for call); + +Expressions and Names +--------------------- + +* Every operator must be surrounded by spaces. An exception is that + this rule does not apply to the exponentiation operator, for which + there are no specific layout rules. The reason for this exception + is that sometimes it makes clearer reading to leave out the spaces + around exponentiation. + + .. index:: Operators + + .. code-block:: ada + + E := A * B**2 + 3 * (C - D); + +* Use parentheses where they clarify the intended association of operands + with operators: + + .. index:: Parenthesization of expressions + + .. code-block:: ada + + (A / B) * C + +Statements +---------- + +Simple and Compound Statements +****************************** + +* Use only one statement or label per line. + +* A longer sequence_of_statements may be divided in logical + groups or separated from surrounding code using a blank line. + + +If Statements +************* + +* When the ``if``, ``elsif`` or ``else`` keywords fit on the + same line with the condition and the ``then`` keyword, then the + statement is formatted as follows: + + .. index:: Alignment (in an if statement) + + .. code-block:: ada + + if condition then + ... + elsif condition then + ... + else + ... + end if; + + When the above layout is not possible, ``then`` should be aligned + with ``if``, and conditions should preferably be split before an + ``and`` or ``or`` keyword a follows: + + .. code-block:: ada + + if long_condition_that_has_to_be_split + and then continued_on_the_next_line + then + ... + end if; + + The ``elsif``, ``else`` and ``end if`` always line up with + the ``if`` keyword. The preferred location for splitting the line + is before ``and`` or ``or``. The continuation of a condition is + indented with two spaces or as many as needed to make nesting clear. + As an exception, if conditions are closely related either of the + following is allowed: + + .. code-block:: ada + + if x = lakdsjfhlkashfdlkflkdsalkhfsalkdhflkjdsahf + or else + x = asldkjhalkdsjfhhfd + or else + x = asdfadsfadsf + then + ... + end if; + + if x = lakdsjfhlkashfdlkflkdsalkhfsalkdhflkjdsahf or else + x = asldkjhalkdsjfhhfd or else + x = asdfadsfadsf + then + ... + end if; + +* Conditions should use short-circuit forms ( ``and then``, + ``or else`` ), except when the operands are boolean variables + or boolean constants. + + .. index:: Short-circuit forms + +* Complex conditions in ``if`` statements are indented two characters: + + .. index:: Indentation (in if statements) + + .. code-block:: ada + + if this_complex_condition + and then that_other_one + and then one_last_one + then + ... + end if; + + There are some cases where complex conditionals can be laid out + in manners that do not follow these rules to preserve better + parallelism between branches, e.g. + + .. code-block:: ada + + if xyz.abc (gef) = 'c' + or else + xyz.abc (gef) = 'x' + then + ... + end if; + +* Every ``if`` block is preceded and followed by a blank line, except + where it begins or ends a sequence_of_statements. + + .. index:: Blank lines (in an if statement) + + .. code-block:: ada + + A := 5; + + if A = 5 then + null; + end if; + + A := 6; + +Case Statements +*************** + +* Layout is as below. For long ``case`` statements, the extra indentation + can be saved by aligning the ``when`` clauses with the opening ``case``. + + .. code-block:: ada + + case expression is + when condition => + ... + when condition => + ... + end case; + +Loop Statements +*************** + +* When possible, have ``for`` or ``while`` on one line with the + condition and the ``loop`` keyword. + + .. code-block:: ada + + for J in S'Range loop + ... + end loop; + + If the condition is too long, split the condition (see 'If + statements' above) and align ``loop`` with the ``for`` or + ``while`` keyword. + + .. index:: Alignment (in a loop statement) + + .. code-block:: ada + + while long_condition_that_has_to_be_split + and then continued_on_the_next_line + loop + ... + end loop; + + If the loop_statement has an identifier, it is laid out as follows: + + .. code-block:: ada + + Outer : while not condition loop + ... + end Outer; + +Block Statements +**************** + +* The ``declare`` (optional), ``begin`` and ``end`` words + are aligned, except when the block_statement is named. There + is a blank line before the ``begin`` keyword: + + .. index:: Alignment (in a block statement) + + .. code-block:: ada + + Some_Block : declare + ... + + begin + ... + end Some_Block; + +Subprograms +----------- + +Subprogram Declarations +*********************** + +* Do not write the ``in`` for parameters. + + .. code-block:: ada + + function Length (S : String) return Integer; + +* When the declaration line for a procedure or a function is too long to fit + the entire declaration (including the keyword procedure or function) on a + single line, then fold it, putting a single parameter on a line, aligning + the colons, as in: + + .. code-block:: ada + + procedure Set_Heading + (Source : String; + Count : Natural; + Pad : Character := Space; + Fill : Boolean := True); + + In the case of a function, if the entire spec does not fit on one line, then + the return may appear after the last parameter, as in: + + .. code-block:: ada + + function Head + (Source : String; + Count : Natural; + Pad : Character := Space) return String; + + Or it may appear on its own as a separate line. This form is preferred when + putting the return on the same line as the last parameter would result in + an overlong line. The return type may optionally be aligned with the types + of the parameters (usually we do this aligning if it results only in a small + number of extra spaces, and otherwise we don't attempt to align). So two + alternative forms for the above spec are: + + .. code-block:: ada + + function Head + (Source : String; + Count : Natural; + Pad : Character := Space) + return String; + + function Head + (Source : String; + Count : Natural; + Pad : Character := Space) + return String; + +Subprogram Bodies +***************** + +* Function and procedure bodies should usually be sorted alphabetically. Do + not attempt to sort them in some logical order by functionality. For a + sequence of subprogram specs, a general alphabetical sorting is also + usually appropriate, but occasionally it makes sense to group by major + function, with appropriate headers. + +* All subprograms have a header giving the function name, with the following + format: + + .. code-block:: ada + + ----------------- + -- My_Function -- + ----------------- + + procedure My_Function is + begin + ... + end My_Function; + + Note that the name in the header is preceded by a single space, + not two spaces as for other comments. These headers are used on + nested subprograms as well as outer level subprograms. They may + also be used as headers for sections of comments, or collections + of declarations that are related. + +* Every subprogram body must have a preceding subprogram_declaration, + which includes proper client documentation so that you do not need to + read the subprogram body in order to understand what the subprogram does and + how to call it. All subprograms should be documented, without exceptions. + + .. index:: Blank lines (in subprogram bodies) + +* A sequence of declarations may optionally be separated from the following + begin by a blank line. Just as we optionally allow blank lines in general + between declarations, this blank line should be present only if it improves + readability. Generally we avoid this blank line if the declarative part is + small (one or two lines) and the body has no blank lines, and we include it + if the declarative part is long or if the body has blank lines. + +* If the declarations in a subprogram contain at least one nested + subprogram body, then just before the ``begin`` of the enclosing + subprogram, there is a comment line and a blank line: + + .. code-block:: ada + + -- Start of processing for Enclosing_Subprogram + + begin + ... + end Enclosing_Subprogram; + +* When nested subprograms are present, variables that are referenced by any + nested subprogram should precede the nested subprogram specs. For variables + that are not referenced by nested procedures, the declarations can either also + be before any of the nested subprogram specs (this is the old style, more + generally used). Or then can come just before the begin, with a header. The + following example shows the two possible styles: + + .. code-block:: ada + + procedure Style1 is + Var_Referenced_In_Nested : Integer; + Var_Referenced_Only_In_Style1 : Integer; + + proc Nested; + -- Comments ... + + ------------ + -- Nested -- + ------------ + + procedure Nested is + begin + ... + end Nested; + + -- Start of processing for Style1 + + begin + ... + end Style1; + + procedure Style2 is + Var_Referenced_In_Nested : Integer; + + proc Nested; + -- Comments ... + + ------------ + -- Nested -- + ------------ + + procedure Nested is + begin + ... + end Nested; + + -- Local variables + + Var_Referenced_Only_In_Style2 : Integer; + + -- Start of processing for Style2 + + begin + ... + end Style2; + + For new code, we generally prefer Style2, but we do not insist on + modifying all legacy occurrences of Style1, which is still much + more common in the sources. + +Packages and Visibility Rules +----------------------------- + +* All program units and subprograms have their name at the end: + + .. code-block:: ada + + package P is + ... + end P; + +* We will use the style of ``use`` -ing ``with`` -ed packages, with + the context clauses looking like: + + .. index:: use clauses + + .. code-block:: ada + + with A; use A; + with B; use B; + +* Names declared in the visible part of packages should be + unique, to prevent name clashes when the packages are ``use`` d. + + .. index:: Name clash avoidance + + .. code-block:: ada + + package Entity is + type Entity_Kind is ...; + ... + end Entity; + +* After the file header comment, the context clause and unit specification + should be the first thing in a program_unit. + +* Preelaborate, Pure and Elaborate_Body pragmas should be added right after the + package name, indented an extra level and using the parameterless form: + + .. code-block:: ada + + package Preelaborate_Package is + pragma Preelaborate; + ... + end Preelaborate_Package; + +Program Structure and Compilation Issues +---------------------------------------- + +* Every GNAT source file must be compiled with the ``-gnatg`` + switch to check the coding style. + (Note that you should look at + style.adb to see the lexical rules enforced by ``-gnatg`` ). + + .. index:: -gnatg option (to gcc) + .. index:: style.adb file + +* Each source file should contain only one compilation unit. + +* Filenames should be 8 or fewer characters, followed by the ``.adb`` + extension for a body or ``.ads`` for a spec. + + .. index:: File name length + +* Unit names should be distinct when 'krunch'ed to 8 characters + (see krunch.ads) and the filenames should match the unit name, + except that they are all lower case. + + .. index:: krunch.ads file + +.. toctree:: + share/gnu_free_documentation_license diff --git a/gcc/ada/doc/share/conf.py b/gcc/ada/doc/share/conf.py index debd716..755c3a6 100644 --- a/gcc/ada/doc/share/conf.py +++ b/gcc/ada/doc/share/conf.py @@ -18,9 +18,11 @@ import latex_elements DOCS = { 'gnat_rm': { - 'title': u'GNAT Reference Manual'}, + 'title': 'GNAT Reference Manual'}, 'gnat_ugn': { - 'title': u'GNAT User\'s Guide for Native Platforms'}} + 'title': 'GNAT User\'s Guide for Native Platforms'}, + 'gnat-style': { + 'title': 'GNAT Coding Style: A Guide for GNAT Developers'}} # Then retrieve the source directory root_source_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -28,17 +30,17 @@ gnatvsn_spec = os.path.join(root_source_dir, '..', 'gnatvsn.ads') basever = os.path.join(root_source_dir, '..', '..', 'BASE-VER') texi_fsf = True # Set to False when FSF doc is switched to sphinx by default -with open(gnatvsn_spec, 'rb') as fd: +with open(gnatvsn_spec, 'r') as fd: gnatvsn_content = fd.read() def get_copyright(): - return u'2008-%s, Free Software Foundation' % time.strftime('%Y') + return '2008-%s, Free Software Foundation' % time.strftime('%Y') def get_gnat_version(): - m = re.search(br'Gnat_Static_Version_String : ' + - br'constant String := "([^\(\)]+)\(.*\)?";', + m = re.search(r'Gnat_Static_Version_String : ' + + r'constant String := "([^\(\)]+)\(.*\)?";', gnatvsn_content) if m: return m.group(1).strip().decode() @@ -57,12 +59,12 @@ def get_gnat_version(): def get_gnat_build_type(): - m = re.search(br'Build_Type : constant Gnat_Build_Type := (.+);', + m = re.search(r'Build_Type : constant Gnat_Build_Type := (.+);', gnatvsn_content) if m: - return {b'Gnatpro': 'PRO', - b'FSF': 'FSF', - b'GPL': 'GPL'}[m.group(1).strip()] + return {'Gnatpro': 'PRO', + 'FSF': 'FSF', + 'GPL': 'GPL'}[m.group(1).strip()] else: print('cannot compute GNAT build type') sys.exit(1) @@ -119,8 +121,8 @@ copyright_macros = { 'date': time.strftime("%b %d, %Y"), 'edition': 'GNAT %s Edition' % 'Pro' if get_gnat_build_type() == 'PRO' else 'GPL', - 'name': u'GNU Ada', - 'tool': u'GNAT', + 'name': 'GNU Ada', + 'tool': 'GNAT', 'version': version} latex_elements = { @@ -134,11 +136,11 @@ latex_elements = { 'tableofcontents': latex_elements.TOC % copyright_macros} latex_documents = [ - (master_doc, '%s.tex' % doc_name, project, u'AdaCore', 'manual')] + (master_doc, '%s.tex' % doc_name, project, 'AdaCore', 'manual')] texinfo_documents = [ (master_doc, doc_name, project, - u'AdaCore', doc_name, doc_name, '')] + 'AdaCore', doc_name, doc_name, '')] def setup(app): diff --git a/gcc/builtins.c b/gcc/builtins.c index 2f0efae..e1b2848 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -362,15 +362,6 @@ access_ref::get_ref (vec<access_ref> *all_refs, same_ref.offrng[1] = phi_arg_ref.offrng[1]; } - if (phi_ref.sizrng[0] < 0) - { - /* Fail if none of the PHI's arguments resulted in updating PHI_REF - (perhaps because they have all been already visited by prior - recursive calls). */ - psnlim->leave_phi (ref); - return NULL_TREE; - } - if (!same_ref.ref && same_ref.offrng[0] != 0) /* Clear BASE0 if not all the arguments refer to the same object and if not all their offsets are zero-based. This allows the final @@ -390,6 +381,15 @@ access_ref::get_ref (vec<access_ref> *all_refs, phi_ref.parmarray = parmarray; } + if (phi_ref.sizrng[0] < 0) + { + /* Fail if none of the PHI's arguments resulted in updating PHI_REF + (perhaps because they have all been already visited by prior + recursive calls). */ + psnlim->leave_phi (ref); + return NULL_TREE; + } + /* Avoid changing *THIS. */ if (pref && pref != this) *pref = phi_ref; diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index e73c3ee..7fc64a5 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,17 @@ +2021-05-14 Martin Liska <mliska@suse.cz> + + * c.opt: Add Warning keyword for 2 options. + +2021-05-13 Martin Liska <mliska@suse.cz> + + PR middle-end/100504 + * c-attribs.c (handle_target_clones_attribute): Expect a string + argument to target_clone argument. + +2021-05-11 Joseph Myers <joseph@codesourcery.com> + + * c-lex.c (interpret_float): Handle digit separators for C2X. + 2021-05-10 Martin Liska <mliska@suse.cz> * c-ada-spec.c (print_destructor): Use startswith diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index c1f652d..f54388e 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -5288,7 +5288,12 @@ handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args), /* Ensure we have a function type. */ if (TREE_CODE (*node) == FUNCTION_DECL) { - if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node))) + if (TREE_CODE (TREE_VALUE (args)) != STRING_CST) + { + error ("%qE attribute argument not a string constant", name); + *no_add_attrs = true; + } + else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node))) { warning (OPT_Wattributes, "%qE attribute ignored due to conflict " "with %qs attribute", name, "always_inline"); diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 7bd799d..b7daa2e 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -9059,6 +9059,12 @@ braced_list_to_string (tree type, tree ctor, bool member) if (!member && !tree_fits_uhwi_p (typesize)) return ctor; + /* If the target char size differes from the host char size, we'd risk + loosing data and getting object sizes wrong by converting to + host chars. */ + if (TYPE_PRECISION (char_type_node) != CHAR_BIT) + return ctor; + /* If the array has an explicit bound, use it to constrain the size of the string. If it doesn't, be sure to create a string that's as long as implied by the index of the last zero specified via diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index f1b4c3f..5fcf961 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -592,7 +592,7 @@ C ObjC RejectNegative Warning Alias(Werror=, implicit-function-declaration) This switch is deprecated; use -Werror=implicit-function-declaration instead. Wexceptions -C++ ObjC++ Var(warn_exceptions) Init(1) +C++ ObjC++ Var(warn_exceptions) Init(1) Warning Warn when an exception handler is shadowed by another handler. Wextra @@ -1741,7 +1741,7 @@ C++ ObjC Var(flag_module_version_ignore) Integer ; undocumented, Very dangerous, but occasionally useful Winvalid-imported-macros -C++ ObjC++ Var(warn_imported_macros) +C++ ObjC++ Var(warn_imported_macros) Warning Warn about macros that have conflicting header units definitions. flang-info-include-translate diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index d003883..a75832b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,13 @@ +2021-05-13 Martin Sebor <msebor@redhat.com> + + PR c/100550 + * c-decl.c (get_parm_array_spec): Avoid erroneous VLA bounds. + +2021-05-12 Marcel Vollweiler <marcel@codesourcery.com> + + * c-parser.c (c_parser_omp_clause_map): Support map-type-modifier + 'close'. + 2021-05-10 Martin Liska <mliska@suse.cz> * c-aux-info.c (affix_data_type): Use startswith diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 3ea4708..53b2b5b 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -5856,6 +5856,9 @@ get_parm_array_spec (const struct c_parm *parm, tree attrs) spec += buf; break; } + else if (!INTEGRAL_TYPE_P (TREE_TYPE (nelts))) + /* Avoid invalid NELTS. */ + return attrs; /* Each variable VLA bound is represented by a dollar sign. */ spec += "$"; diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 5cdeb21..f79b839 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -15643,54 +15643,83 @@ c_parser_omp_clause_depend (c_parser *parser, tree list) map-kind: alloc | to | from | tofrom | release | delete - map ( always [,] map-kind: variable-list ) */ + map ( always [,] map-kind: variable-list ) + + OpenMP 5.0: + map ( [map-type-modifier[,] ...] map-kind: variable-list ) + + map-type-modifier: + always | close */ static tree c_parser_omp_clause_map (c_parser *parser, tree list) { location_t clause_loc = c_parser_peek_token (parser)->location; enum gomp_map_kind kind = GOMP_MAP_TOFROM; - int always = 0; - enum c_id_kind always_id_kind = C_ID_NONE; - location_t always_loc = UNKNOWN_LOCATION; - tree always_id = NULL_TREE; tree nl, c; matching_parens parens; if (!parens.require_open (parser)) return list; - if (c_parser_next_token_is (parser, CPP_NAME)) + int pos = 1; + int map_kind_pos = 0; + while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME) + { + if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON) + { + map_kind_pos = pos; + break; + } + + if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA) + pos++; + pos++; + } + + int always_modifier = 0; + int close_modifier = 0; + for (int pos = 1; pos < map_kind_pos; ++pos) { c_token *tok = c_parser_peek_token (parser); + + if (tok->type == CPP_COMMA) + { + c_parser_consume_token (parser); + continue; + } + const char *p = IDENTIFIER_POINTER (tok->value); - always_id_kind = tok->id_kind; - always_loc = tok->location; - always_id = tok->value; if (strcmp ("always", p) == 0) { - c_token *sectok = c_parser_peek_2nd_token (parser); - if (sectok->type == CPP_COMMA) + if (always_modifier) { - c_parser_consume_token (parser); - c_parser_consume_token (parser); - always = 2; + c_parser_error (parser, "too many %<always%> modifiers"); + parens.skip_until_found_close (parser); + return list; } - else if (sectok->type == CPP_NAME) + always_modifier++; + } + else if (strcmp ("close", p) == 0) + { + if (close_modifier) { - p = IDENTIFIER_POINTER (sectok->value); - if (strcmp ("alloc", p) == 0 - || strcmp ("to", p) == 0 - || strcmp ("from", p) == 0 - || strcmp ("tofrom", p) == 0 - || strcmp ("release", p) == 0 - || strcmp ("delete", p) == 0) - { - c_parser_consume_token (parser); - always = 1; - } + c_parser_error (parser, "too many %<close%> modifiers"); + parens.skip_until_found_close (parser); + return list; } + close_modifier++; } + else + { + c_parser_error (parser, "%<#pragma omp target%> with " + "modifier other than %<always%> or %<close%>" + "on %<map%> clause"); + parens.skip_until_found_close (parser); + return list; + } + + c_parser_consume_token (parser); } if (c_parser_next_token_is (parser, CPP_NAME) @@ -15700,11 +15729,11 @@ c_parser_omp_clause_map (c_parser *parser, tree list) if (strcmp ("alloc", p) == 0) kind = GOMP_MAP_ALLOC; else if (strcmp ("to", p) == 0) - kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO; + kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO; else if (strcmp ("from", p) == 0) - kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM; + kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM; else if (strcmp ("tofrom", p) == 0) - kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM; + kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM; else if (strcmp ("release", p) == 0) kind = GOMP_MAP_RELEASE; else if (strcmp ("delete", p) == 0) @@ -15719,35 +15748,6 @@ c_parser_omp_clause_map (c_parser *parser, tree list) c_parser_consume_token (parser); c_parser_consume_token (parser); } - else if (always) - { - if (always_id_kind != C_ID_ID) - { - c_parser_error (parser, "expected identifier"); - parens.skip_until_found_close (parser); - return list; - } - - tree t = lookup_name (always_id); - if (t == NULL_TREE) - { - undeclared_variable (always_loc, always_id); - t = error_mark_node; - } - if (t != error_mark_node) - { - tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP); - OMP_CLAUSE_DECL (u) = t; - OMP_CLAUSE_CHAIN (u) = list; - OMP_CLAUSE_SET_MAP_KIND (u, kind); - list = u; - } - if (always == 1) - { - parens.skip_until_found_close (parser); - return list; - } - } nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list); diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 747ca3e..e3814ee 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -4512,7 +4512,12 @@ expand_debug_expr (tree exp) op0 = DECL_RTL_IF_SET (exp); if (op0) - return op0; + { + if (GET_MODE (op0) != mode) + gcc_assert (VECTOR_TYPE_P (TREE_TYPE (exp))); + else + return op0; + } op0 = gen_rtx_DEBUG_EXPR (mode); DEBUG_EXPR_TREE_DECL (op0) = exp; diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 9962089..e59bc7b 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -5356,37 +5356,27 @@ [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")] ) -(define_expand "aarch64_sqdmlal2<mode>" +(define_expand "aarch64_sqdml<SBINQOPS:as>l2<mode>" [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:<VWIDE> 1 "register_operand") - (match_operand:VQ_HSI 2 "register_operand") - (match_operand:VQ_HSI 3 "register_operand")] - "TARGET_SIMD" -{ - rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true); - emit_insn (gen_aarch64_sqdmlal2<mode>_internal (operands[0], operands[1], - operands[2], operands[3], p)); - DONE; -}) - -(define_expand "aarch64_sqdmlsl2<mode>" - [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:<VWIDE> 1 "register_operand") + (SBINQOPS:<VWIDE> + (match_operand:<VWIDE> 1 "register_operand") + (match_dup 1)) (match_operand:VQ_HSI 2 "register_operand") (match_operand:VQ_HSI 3 "register_operand")] "TARGET_SIMD" { rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true); - emit_insn (gen_aarch64_sqdmlsl2<mode>_internal (operands[0], operands[1], - operands[2], operands[3], p)); + emit_insn (gen_aarch64_sqdml<SBINQOPS:as>l2<mode>_internal (operands[0], + operands[1], operands[2], + operands[3], p)); DONE; }) ;; vqdml[sa]l2_lane -(define_insn "aarch64_sqdml<SBINQOPS:as>l2_lane<mode>_internal" +(define_insn "aarch64_sqdmlsl2_lane<mode>_internal" [(set (match_operand:<VWIDE> 0 "register_operand" "=w") - (SBINQOPS:<VWIDE> + (ss_minus:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "0") (ss_ashift:<VWIDE> (mult:<VWIDE> @@ -5405,14 +5395,40 @@ { operands[4] = aarch64_endian_lane_rtx (<VCOND>mode, INTVAL (operands[4])); return - "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"; + "sqdmlsl2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"; } [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")] ) -(define_insn "aarch64_sqdml<SBINQOPS:as>l2_laneq<mode>_internal" +(define_insn "aarch64_sqdmlal2_lane<mode>_internal" [(set (match_operand:<VWIDE> 0 "register_operand" "=w") - (SBINQOPS:<VWIDE> + (ss_plus:<VWIDE> + (ss_ashift:<VWIDE> + (mult:<VWIDE> + (sign_extend:<VWIDE> + (vec_select:<VHALF> + (match_operand:VQ_HSI 2 "register_operand" "w") + (match_operand:VQ_HSI 5 "vect_par_cnst_hi_half" ""))) + (sign_extend:<VWIDE> + (vec_duplicate:<VHALF> + (vec_select:<VEL> + (match_operand:<VCOND> 3 "register_operand" "<vwx>") + (parallel [(match_operand:SI 4 "immediate_operand" "i")]) + )))) + (const_int 1)) + (match_operand:<VWIDE> 1 "register_operand" "0")))] + "TARGET_SIMD" + { + operands[4] = aarch64_endian_lane_rtx (<VCOND>mode, INTVAL (operands[4])); + return + "sqdmlal2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"; + } + [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")] +) + +(define_insn "aarch64_sqdmlsl2_laneq<mode>_internal" + [(set (match_operand:<VWIDE> 0 "register_operand" "=w") + (ss_minus:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "0") (ss_ashift:<VWIDE> (mult:<VWIDE> @@ -5431,74 +5447,74 @@ { operands[4] = aarch64_endian_lane_rtx (<VCONQ>mode, INTVAL (operands[4])); return - "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"; + "sqdmlsl2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"; } [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")] ) -(define_expand "aarch64_sqdmlal2_lane<mode>" - [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:<VWIDE> 1 "register_operand") - (match_operand:VQ_HSI 2 "register_operand") - (match_operand:<VCOND> 3 "register_operand") - (match_operand:SI 4 "immediate_operand")] - "TARGET_SIMD" -{ - rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true); - emit_insn (gen_aarch64_sqdmlal2_lane<mode>_internal (operands[0], operands[1], - operands[2], operands[3], - operands[4], p)); - DONE; -}) - -(define_expand "aarch64_sqdmlal2_laneq<mode>" - [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:<VWIDE> 1 "register_operand") - (match_operand:VQ_HSI 2 "register_operand") - (match_operand:<VCONQ> 3 "register_operand") - (match_operand:SI 4 "immediate_operand")] +(define_insn "aarch64_sqdmlal2_laneq<mode>_internal" + [(set (match_operand:<VWIDE> 0 "register_operand" "=w") + (ss_plus:<VWIDE> + (ss_ashift:<VWIDE> + (mult:<VWIDE> + (sign_extend:<VWIDE> + (vec_select:<VHALF> + (match_operand:VQ_HSI 2 "register_operand" "w") + (match_operand:VQ_HSI 5 "vect_par_cnst_hi_half" ""))) + (sign_extend:<VWIDE> + (vec_duplicate:<VHALF> + (vec_select:<VEL> + (match_operand:<VCONQ> 3 "register_operand" "<vwx>") + (parallel [(match_operand:SI 4 "immediate_operand" "i")]) + )))) + (const_int 1)) + (match_operand:<VWIDE> 1 "register_operand" "0")))] "TARGET_SIMD" -{ - rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true); - emit_insn (gen_aarch64_sqdmlal2_laneq<mode>_internal (operands[0], operands[1], - operands[2], operands[3], - operands[4], p)); - DONE; -}) + { + operands[4] = aarch64_endian_lane_rtx (<VCONQ>mode, INTVAL (operands[4])); + return + "sqdmlal2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"; + } + [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")] +) -(define_expand "aarch64_sqdmlsl2_lane<mode>" +(define_expand "aarch64_sqdml<SBINQOPS:as>l2_lane<mode>" [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:<VWIDE> 1 "register_operand") + (SBINQOPS:<VWIDE> + (match_operand:<VWIDE> 1 "register_operand") + (match_dup 1)) (match_operand:VQ_HSI 2 "register_operand") (match_operand:<VCOND> 3 "register_operand") (match_operand:SI 4 "immediate_operand")] "TARGET_SIMD" { rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true); - emit_insn (gen_aarch64_sqdmlsl2_lane<mode>_internal (operands[0], operands[1], - operands[2], operands[3], - operands[4], p)); + emit_insn (gen_aarch64_sqdml<SBINQOPS:as>l2_lane<mode>_internal (operands[0], + operands[1], operands[2], + operands[3], operands[4], p)); DONE; }) -(define_expand "aarch64_sqdmlsl2_laneq<mode>" +(define_expand "aarch64_sqdml<SBINQOPS:as>l2_laneq<mode>" [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:<VWIDE> 1 "register_operand") + (SBINQOPS:<VWIDE> + (match_operand:<VWIDE> 1 "register_operand") + (match_dup 1)) (match_operand:VQ_HSI 2 "register_operand") (match_operand:<VCONQ> 3 "register_operand") (match_operand:SI 4 "immediate_operand")] "TARGET_SIMD" { rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true); - emit_insn (gen_aarch64_sqdmlsl2_laneq<mode>_internal (operands[0], operands[1], - operands[2], operands[3], - operands[4], p)); + emit_insn (gen_aarch64_sqdml<SBINQOPS:as>l2_laneq<mode>_internal (operands[0], + operands[1], operands[2], + operands[3], operands[4], p)); DONE; }) -(define_insn "aarch64_sqdml<SBINQOPS:as>l2_n<mode>_internal" +(define_insn "aarch64_sqdmlsl2_n<mode>_internal" [(set (match_operand:<VWIDE> 0 "register_operand" "=w") - (SBINQOPS:<VWIDE> + (ss_minus:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "0") (ss_ashift:<VWIDE> (mult:<VWIDE> @@ -5511,35 +5527,42 @@ (match_operand:<VEL> 3 "register_operand" "<vwx>")))) (const_int 1))))] "TARGET_SIMD" - "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]" + "sqdmlsl2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]" [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")] ) -(define_expand "aarch64_sqdmlal2_n<mode>" - [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:<VWIDE> 1 "register_operand") - (match_operand:VQ_HSI 2 "register_operand") - (match_operand:<VEL> 3 "register_operand")] +(define_insn "aarch64_sqdmlal2_n<mode>_internal" + [(set (match_operand:<VWIDE> 0 "register_operand" "=w") + (ss_plus:<VWIDE> + (ss_ashift:<VWIDE> + (mult:<VWIDE> + (sign_extend:<VWIDE> + (vec_select:<VHALF> + (match_operand:VQ_HSI 2 "register_operand" "w") + (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" ""))) + (sign_extend:<VWIDE> + (vec_duplicate:<VHALF> + (match_operand:<VEL> 3 "register_operand" "<vwx>")))) + (const_int 1)) + (match_operand:<VWIDE> 1 "register_operand" "0")))] "TARGET_SIMD" -{ - rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true); - emit_insn (gen_aarch64_sqdmlal2_n<mode>_internal (operands[0], operands[1], - operands[2], operands[3], - p)); - DONE; -}) + "sqdmlal2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]" + [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")] +) -(define_expand "aarch64_sqdmlsl2_n<mode>" +(define_expand "aarch64_sqdml<SBINQOPS:as>l2_n<mode>" [(match_operand:<VWIDE> 0 "register_operand") - (match_operand:<VWIDE> 1 "register_operand") + (SBINQOPS:<VWIDE> + (match_operand:<VWIDE> 1 "register_operand") + (match_dup 1)) (match_operand:VQ_HSI 2 "register_operand") (match_operand:<VEL> 3 "register_operand")] "TARGET_SIMD" { rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true); - emit_insn (gen_aarch64_sqdmlsl2_n<mode>_internal (operands[0], operands[1], - operands[2], operands[3], - p)); + emit_insn (gen_aarch64_sqdml<SBINQOPS:as>l2_n<mode>_internal (operands[0], + operands[1], operands[2], + operands[3], p)); DONE; }) diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 2521541..ffccaa7 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -373,7 +373,7 @@ extern void arm_emit_coreregs_64bit_shift (enum rtx_code, rtx, rtx, rtx, rtx, extern bool arm_fusion_enabled_p (tune_params::fuse_ops); extern bool arm_valid_symbolic_address_p (rtx); extern bool arm_validize_comparison (rtx *, rtx *, rtx *); -extern bool arm_expand_vector_compare (rtx, rtx_code, rtx, rtx, bool); +extern bool arm_expand_vector_compare (rtx, rtx_code, rtx, rtx, bool, bool); #endif /* RTX_CODE */ extern bool arm_gen_setmem (rtx *); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 2962071..eee3671 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -5563,9 +5563,20 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, return; *op1 = GEN_INT (i + 1); *code = *code == GT ? GE : LT; - return; } - break; + else + { + /* GT maxval is always false, LE maxval is always true. + We can't fold that away here as we must make a + comparison, but we can fold them to comparisons + with the same result that can be handled: + op0 GT maxval -> op0 LT minval + op0 LE maxval -> op0 GE minval + where minval = (-maxval - 1). */ + *op1 = GEN_INT (-maxval - 1); + *code = *code == GT ? LT : GE; + } + return; case GTU: case LEU: @@ -5578,9 +5589,19 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, return; *op1 = GEN_INT (i + 1); *code = *code == GTU ? GEU : LTU; - return; } - break; + else + { + /* GTU ~0 is always false, LEU ~0 is always true. + We can't fold that away here as we must make a + comparison, but we can fold them to comparisons + with the same result that can be handled: + op0 GTU ~0 -> op0 LTU 0 + op0 LEU ~0 -> op0 GEU 0. */ + *op1 = const0_rtx; + *code = *code == GTU ? LTU : GEU; + } + return; default: gcc_unreachable (); @@ -30938,66 +30959,113 @@ arm_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem, and return true if TARGET contains the inverse. If !CAN_INVERT, always store the result in TARGET, never its inverse. + If VCOND_MVE, do not emit the vpsel instruction here, let arm_expand_vcond do + it with the right destination type to avoid emiting two vpsel, one here and + one in arm_expand_vcond. + Note that the handling of floating-point comparisons is not IEEE compliant. */ bool arm_expand_vector_compare (rtx target, rtx_code code, rtx op0, rtx op1, - bool can_invert) + bool can_invert, bool vcond_mve) { machine_mode cmp_result_mode = GET_MODE (target); machine_mode cmp_mode = GET_MODE (op0); bool inverted; - switch (code) - { - /* For these we need to compute the inverse of the requested - comparison. */ - case UNORDERED: - case UNLT: - case UNLE: - case UNGT: - case UNGE: - case UNEQ: - case NE: - code = reverse_condition_maybe_unordered (code); - if (!can_invert) - { - /* Recursively emit the inverted comparison into a temporary - and then store its inverse in TARGET. This avoids reusing - TARGET (which for integer NE could be one of the inputs). */ - rtx tmp = gen_reg_rtx (cmp_result_mode); - if (arm_expand_vector_compare (tmp, code, op0, op1, true)) - gcc_unreachable (); - emit_insn (gen_rtx_SET (target, gen_rtx_NOT (cmp_result_mode, tmp))); - return false; - } - inverted = true; - break; - default: + /* MVE supports more comparisons than Neon. */ + if (TARGET_HAVE_MVE) inverted = false; - break; - } + else + switch (code) + { + /* For these we need to compute the inverse of the requested + comparison. */ + case UNORDERED: + case UNLT: + case UNLE: + case UNGT: + case UNGE: + case UNEQ: + case NE: + code = reverse_condition_maybe_unordered (code); + if (!can_invert) + { + /* Recursively emit the inverted comparison into a temporary + and then store its inverse in TARGET. This avoids reusing + TARGET (which for integer NE could be one of the inputs). */ + rtx tmp = gen_reg_rtx (cmp_result_mode); + if (arm_expand_vector_compare (tmp, code, op0, op1, true, vcond_mve)) + gcc_unreachable (); + emit_insn (gen_rtx_SET (target, gen_rtx_NOT (cmp_result_mode, tmp))); + return false; + } + inverted = true; + break; + + default: + inverted = false; + break; + } switch (code) { - /* These are natively supported for zero comparisons, but otherwise - require the operands to be swapped. */ + /* These are natively supported by Neon for zero comparisons, but otherwise + require the operands to be swapped. For MVE, we can only compare + registers. */ case LE: case LT: - if (op1 != CONST0_RTX (cmp_mode)) - { - code = swap_condition (code); - std::swap (op0, op1); - } + if (!TARGET_HAVE_MVE) + if (op1 != CONST0_RTX (cmp_mode)) + { + code = swap_condition (code); + std::swap (op0, op1); + } /* Fall through. */ - /* These are natively supported for both register and zero operands. */ + /* These are natively supported by Neon for both register and zero + operands. MVE supports registers only. */ case EQ: case GE: case GT: - emit_insn (gen_neon_vc (code, cmp_mode, target, op0, op1)); + case NE: + if (TARGET_HAVE_MVE) + { + rtx vpr_p0; + if (vcond_mve) + vpr_p0 = target; + else + vpr_p0 = gen_reg_rtx (HImode); + + switch (GET_MODE_CLASS (cmp_mode)) + { + case MODE_VECTOR_INT: + emit_insn (gen_mve_vcmpq (code, cmp_mode, vpr_p0, op0, force_reg (cmp_mode, op1))); + break; + case MODE_VECTOR_FLOAT: + if (TARGET_HAVE_MVE_FLOAT) + emit_insn (gen_mve_vcmpq_f (code, cmp_mode, vpr_p0, op0, force_reg (cmp_mode, op1))); + else + gcc_unreachable (); + break; + default: + gcc_unreachable (); + } + + /* If we are not expanding a vcond, build the result here. */ + if (!vcond_mve) + { + rtx zero = gen_reg_rtx (cmp_result_mode); + rtx one = gen_reg_rtx (cmp_result_mode); + emit_move_insn (zero, CONST0_RTX (cmp_result_mode)); + emit_move_insn (one, CONST1_RTX (cmp_result_mode)); + emit_insn (gen_mve_vpselq (VPSELQ_S, cmp_result_mode, target, one, zero, vpr_p0)); + } + } + else + emit_insn (gen_neon_vc (code, cmp_mode, target, op0, op1)); return inverted; /* These are natively supported for register operands only. @@ -31005,16 +31073,54 @@ arm_expand_vector_compare (rtx target, rtx_code code, rtx op0, rtx op1, or canonicalized by target-independent code. */ case GEU: case GTU: - emit_insn (gen_neon_vc (code, cmp_mode, target, - op0, force_reg (cmp_mode, op1))); + if (TARGET_HAVE_MVE) + { + rtx vpr_p0; + if (vcond_mve) + vpr_p0 = target; + else + vpr_p0 = gen_reg_rtx (HImode); + + emit_insn (gen_mve_vcmpq (code, cmp_mode, vpr_p0, op0, force_reg (cmp_mode, op1))); + if (!vcond_mve) + { + rtx zero = gen_reg_rtx (cmp_result_mode); + rtx one = gen_reg_rtx (cmp_result_mode); + emit_move_insn (zero, CONST0_RTX (cmp_result_mode)); + emit_move_insn (one, CONST1_RTX (cmp_result_mode)); + emit_insn (gen_mve_vpselq (VPSELQ_S, cmp_result_mode, target, one, zero, vpr_p0)); + } + } + else + emit_insn (gen_neon_vc (code, cmp_mode, target, + op0, force_reg (cmp_mode, op1))); return inverted; /* These require the operands to be swapped and likewise do not support comparisons with zero. */ case LEU: case LTU: - emit_insn (gen_neon_vc (swap_condition (code), cmp_mode, - target, force_reg (cmp_mode, op1), op0)); + if (TARGET_HAVE_MVE) + { + rtx vpr_p0; + if (vcond_mve) + vpr_p0 = target; + else + vpr_p0 = gen_reg_rtx (HImode); + + emit_insn (gen_mve_vcmpq (swap_condition (code), cmp_mode, vpr_p0, force_reg (cmp_mode, op1), op0)); + if (!vcond_mve) + { + rtx zero = gen_reg_rtx (cmp_result_mode); + rtx one = gen_reg_rtx (cmp_result_mode); + emit_move_insn (zero, CONST0_RTX (cmp_result_mode)); + emit_move_insn (one, CONST1_RTX (cmp_result_mode)); + emit_insn (gen_mve_vpselq (VPSELQ_S, cmp_result_mode, target, one, zero, vpr_p0)); + } + } + else + emit_insn (gen_neon_vc (swap_condition (code), cmp_mode, + target, force_reg (cmp_mode, op1), op0)); return inverted; /* These need a combination of two comparisons. */ @@ -31026,8 +31132,8 @@ arm_expand_vector_compare (rtx target, rtx_code code, rtx op0, rtx op1, rtx gt_res = gen_reg_rtx (cmp_result_mode); rtx alt_res = gen_reg_rtx (cmp_result_mode); rtx_code alt_code = (code == LTGT ? LT : LE); - if (arm_expand_vector_compare (gt_res, GT, op0, op1, true) - || arm_expand_vector_compare (alt_res, alt_code, op0, op1, true)) + if (arm_expand_vector_compare (gt_res, GT, op0, op1, true, vcond_mve) + || arm_expand_vector_compare (alt_res, alt_code, op0, op1, true, vcond_mve)) gcc_unreachable (); emit_insn (gen_rtx_SET (target, gen_rtx_IOR (cmp_result_mode, gt_res, alt_res))); @@ -31045,13 +31151,47 @@ arm_expand_vector_compare (rtx target, rtx_code code, rtx op0, rtx op1, void arm_expand_vcond (rtx *operands, machine_mode cmp_result_mode) { - rtx mask = gen_reg_rtx (cmp_result_mode); + /* When expanding for MVE, we do not want to emit a (useless) vpsel in + arm_expand_vector_compare, and another one here. */ + bool vcond_mve=false; + rtx mask; + + if (TARGET_HAVE_MVE) + { + vcond_mve=true; + mask = gen_reg_rtx (HImode); + } + else + mask = gen_reg_rtx (cmp_result_mode); + bool inverted = arm_expand_vector_compare (mask, GET_CODE (operands[3]), - operands[4], operands[5], true); + operands[4], operands[5], true, vcond_mve); if (inverted) std::swap (operands[1], operands[2]); + if (TARGET_NEON) emit_insn (gen_neon_vbsl (GET_MODE (operands[0]), operands[0], mask, operands[1], operands[2])); + else + { + machine_mode cmp_mode = GET_MODE (operands[4]); + rtx vpr_p0 = mask; + rtx zero = gen_reg_rtx (cmp_mode); + rtx one = gen_reg_rtx (cmp_mode); + emit_move_insn (zero, CONST0_RTX (cmp_mode)); + emit_move_insn (one, CONST1_RTX (cmp_mode)); + switch (GET_MODE_CLASS (cmp_mode)) + { + case MODE_VECTOR_INT: + emit_insn (gen_mve_vpselq (VPSELQ_S, cmp_result_mode, operands[0], one, zero, vpr_p0)); + break; + case MODE_VECTOR_FLOAT: + if (TARGET_HAVE_MVE_FLOAT) + emit_insn (gen_mve_vpselq_f (cmp_mode, operands[0], one, zero, vpr_p0)); + break; + default: + gcc_unreachable (); + } + } } #define MAX_VECT_LEN 16 diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index e430e4d..8e5bd57 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -89,9 +89,7 @@ extern tree arm_bf16_ptr_type_node; #undef CPP_SPEC -#define CPP_SPEC "%(subtarget_cpp_spec) \ -%{mbig-endian:%{mlittle-endian: \ - %e-mbig-endian and -mlittle-endian may not be used together}}" +#define CPP_SPEC "%(subtarget_cpp_spec)" #ifndef CC1_SPEC #define CC1_SPEC "" diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h index dc28b92..dcd533f 100644 --- a/gcc/config/arm/arm_neon.h +++ b/gcc/config/arm/arm_neon.h @@ -2919,112 +2919,112 @@ __extension__ extern __inline uint8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtst_s8 (int8x8_t __a, int8x8_t __b) { - return (uint8x8_t)__builtin_neon_vtstv8qi (__a, __b); + return (uint8x8_t) ((__a & __b) != 0); } __extension__ extern __inline uint16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtst_s16 (int16x4_t __a, int16x4_t __b) { - return (uint16x4_t)__builtin_neon_vtstv4hi (__a, __b); + return (uint16x4_t) ((__a & __b) != 0); } __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtst_s32 (int32x2_t __a, int32x2_t __b) { - return (uint32x2_t)__builtin_neon_vtstv2si (__a, __b); + return (uint32x2_t) ((__a & __b) != 0); } __extension__ extern __inline uint8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtst_u8 (uint8x8_t __a, uint8x8_t __b) { - return (uint8x8_t)__builtin_neon_vtstv8qi ((int8x8_t) __a, (int8x8_t) __b); + return (uint8x8_t) ((__a & __b) != 0); } __extension__ extern __inline uint16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtst_u16 (uint16x4_t __a, uint16x4_t __b) { - return (uint16x4_t)__builtin_neon_vtstv4hi ((int16x4_t) __a, (int16x4_t) __b); + return (uint16x4_t) ((__a & __b) != 0); } __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtst_u32 (uint32x2_t __a, uint32x2_t __b) { - return (uint32x2_t)__builtin_neon_vtstv2si ((int32x2_t) __a, (int32x2_t) __b); + return (uint32x2_t) ((__a & __b) != 0); } __extension__ extern __inline uint8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtst_p8 (poly8x8_t __a, poly8x8_t __b) { - return (uint8x8_t)__builtin_neon_vtstv8qi ((int8x8_t) __a, (int8x8_t) __b); + return (uint8x8_t) ((__a & __b) != 0); } __extension__ extern __inline uint16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtst_p16 (poly16x4_t __a, poly16x4_t __b) { - return (uint16x4_t)__builtin_neon_vtstv4hi ((int16x4_t) __a, (int16x4_t) __b); + return (uint16x4_t) ((__a & __b) != 0); } __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtstq_s8 (int8x16_t __a, int8x16_t __b) { - return (uint8x16_t)__builtin_neon_vtstv16qi (__a, __b); + return (uint8x16_t) ((__a & __b) != 0); } __extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtstq_s16 (int16x8_t __a, int16x8_t __b) { - return (uint16x8_t)__builtin_neon_vtstv8hi (__a, __b); + return (uint16x8_t) ((__a & __b) != 0); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtstq_s32 (int32x4_t __a, int32x4_t __b) { - return (uint32x4_t)__builtin_neon_vtstv4si (__a, __b); + return (uint32x4_t) ((__a & __b) != 0); } __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtstq_u8 (uint8x16_t __a, uint8x16_t __b) { - return (uint8x16_t)__builtin_neon_vtstv16qi ((int8x16_t) __a, (int8x16_t) __b); + return (uint8x16_t) ((__a & __b) != 0); } __extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtstq_u16 (uint16x8_t __a, uint16x8_t __b) { - return (uint16x8_t)__builtin_neon_vtstv8hi ((int16x8_t) __a, (int16x8_t) __b); + return (uint16x8_t) ((__a & __b) != 0); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtstq_u32 (uint32x4_t __a, uint32x4_t __b) { - return (uint32x4_t)__builtin_neon_vtstv4si ((int32x4_t) __a, (int32x4_t) __b); + return (uint32x4_t) ((__a & __b) != 0); } __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtstq_p8 (poly8x16_t __a, poly8x16_t __b) { - return (uint8x16_t)__builtin_neon_vtstv16qi ((int8x16_t) __a, (int8x16_t) __b); + return (uint8x16_t) ((__a & __b) != 0); } __extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vtstq_p16 (poly16x8_t __a, poly16x8_t __b) { - return (uint16x8_t)__builtin_neon_vtstv8hi ((int16x8_t) __a, (int16x8_t) __b); + return (uint16x8_t) ((__a & __b) != 0); } __extension__ extern __inline int8x8_t diff --git a/gcc/config/arm/arm_neon_builtins.def b/gcc/config/arm/arm_neon_builtins.def index 97e4f9c..70438ac 100644 --- a/gcc/config/arm/arm_neon_builtins.def +++ b/gcc/config/arm/arm_neon_builtins.def @@ -142,7 +142,6 @@ VAR2 (UNOP, vcgez, v4hf, v8hf) VAR2 (UNOP, vcgtz, v4hf, v8hf) VAR2 (UNOP, vclez, v4hf, v8hf) VAR2 (UNOP, vcltz, v4hf, v8hf) -VAR6 (BINOP, vtst, v8qi, v4hi, v2si, v16qi, v8hi, v4si) VAR6 (BINOP, vabds, v8qi, v4hi, v2si, v16qi, v8hi, v4si) VAR6 (BINOP, vabdu, v8qi, v4hi, v2si, v16qi, v8hi, v4si) VAR2 (BINOP, vabdf, v2sf, v4sf) diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 95df8bd..3042baf 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -231,6 +231,9 @@ ;; Vector modes for 16-bit floating-point support. (define_mode_iterator VH [V8HF V4HF]) +;; Modes with 16-bit elements only. +(define_mode_iterator V16 [V4HI V4HF V8HI V8HF]) + ;; 16-bit floating-point vector modes suitable for moving (includes BFmode). (define_mode_iterator VHFBF [V8HF V4HF V4BF V8BF]) @@ -571,6 +574,8 @@ ;; (Opposite) mode to convert to/from for vector-half mode conversions. (define_mode_attr VH_CVTTO [(V4HI "V4HF") (V4HF "V4HI") (V8HI "V8HF") (V8HF "V8HI")]) +(define_mode_attr VH_cvtto [(V4HI "v4hf") (V4HF "v4hi") + (V8HI "v8hf") (V8HF "v8hi")]) ;; Define element mode for each vector mode. (define_mode_attr V_elem [(V8QI "QI") (V16QI "QI") @@ -720,6 +725,7 @@ (define_mode_attr v_cmp_result [(V8QI "v8qi") (V16QI "v16qi") (V4HI "v4hi") (V8HI "v8hi") (V2SI "v2si") (V4SI "v4si") + (V4HF "v4hi") (V8HF "v8hi") (DI "di") (V2DI "v2di") (V2SF "v2si") (V4SF "v4si")]) @@ -1288,12 +1294,11 @@ (VCREATEQ_U "u") (VCREATEQ_S "s") (VSHRQ_N_S "s") (VSHRQ_N_U "u") (VCVTQ_N_FROM_F_S "s") (VSHLQ_U "u") (VCVTQ_N_FROM_F_U "u") (VADDLVQ_P_S "s") (VSHLQ_S "s") - (VADDLVQ_P_U "u") (VCMPNEQ_S "s") + (VADDLVQ_P_U "u") (VABDQ_M_S "s") (VABDQ_M_U "u") (VABDQ_S "s") (VABDQ_U "u") (VADDQ_N_S "s") (VADDQ_N_U "u") (VADDVQ_P_S "s") (VADDVQ_P_U "u") (VBRSRQ_N_S "s") - (VBRSRQ_N_U "u") (VCMPEQQ_S "s") - (VCMPEQQ_N_S "s") (VCMPNEQ_N_S "s") + (VBRSRQ_N_U "u") (VHADDQ_N_S "s") (VHADDQ_N_U "u") (VHADDQ_S "s") (VHADDQ_U "u") (VHSUBQ_N_S "s") (VHSUBQ_N_U "u") (VHSUBQ_S "s") (VMAXQ_S "s") (VMAXQ_U "u") (VHSUBQ_U "u") @@ -1549,16 +1554,12 @@ (define_int_iterator VSHRQ_N [VSHRQ_N_S VSHRQ_N_U]) (define_int_iterator VCVTQ_N_FROM_F [VCVTQ_N_FROM_F_S VCVTQ_N_FROM_F_U]) (define_int_iterator VADDLVQ_P [VADDLVQ_P_S VADDLVQ_P_U]) -(define_int_iterator VCMPNEQ [VCMPNEQ_S]) (define_int_iterator VSHLQ [VSHLQ_S VSHLQ_U]) (define_int_iterator VABDQ [VABDQ_S VABDQ_U]) (define_int_iterator VADDQ_N [VADDQ_N_S VADDQ_N_U]) (define_int_iterator VADDVAQ [VADDVAQ_S VADDVAQ_U]) (define_int_iterator VADDVQ_P [VADDVQ_P_U VADDVQ_P_S]) (define_int_iterator VBRSRQ_N [VBRSRQ_N_U VBRSRQ_N_S]) -(define_int_iterator VCMPEQQ [VCMPEQQ_S]) -(define_int_iterator VCMPEQQ_N [VCMPEQQ_N_S]) -(define_int_iterator VCMPNEQ_N [VCMPNEQ_N_S]) (define_int_iterator VHADDQ [VHADDQ_S VHADDQ_U]) (define_int_iterator VHADDQ_N [VHADDQ_N_U VHADDQ_N_S]) (define_int_iterator VHSUBQ [VHSUBQ_S VHSUBQ_U]) diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index 45df211..133ebe9 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -813,7 +813,7 @@ ;; ;; [vcmpneq_, vcmpcsq_, vcmpeqq_, vcmpgeq_, vcmpgtq_, vcmphiq_, vcmpleq_, vcmpltq_]) ;; -(define_insn "mve_vcmp<mve_cmp_op>q_<mode>" +(define_insn "@mve_vcmp<mve_cmp_op>q_<mode>" [ (set (match_operand:HI 0 "vpr_register_operand" "=Up") (MVE_COMPARISONS:HI (match_operand:MVE_2 1 "s_register_operand" "w") @@ -1903,7 +1903,7 @@ ;; ;; [vcmpeqq_f, vcmpgeq_f, vcmpgtq_f, vcmpleq_f, vcmpltq_f, vcmpneq_f]) ;; -(define_insn "mve_vcmp<mve_cmp_op>q_f<mode>" +(define_insn "@mve_vcmp<mve_cmp_op>q_f<mode>" [ (set (match_operand:HI 0 "vpr_register_operand" "=Up") (MVE_FP_COMPARISONS:HI (match_operand:MVE_0 1 "s_register_operand" "w") @@ -1917,7 +1917,7 @@ ;; ;; [vcmpeqq_n_f, vcmpgeq_n_f, vcmpgtq_n_f, vcmpleq_n_f, vcmpltq_n_f, vcmpneq_n_f]) ;; -(define_insn "mve_vcmp<mve_cmp_op>q_n_f<mode>" +(define_insn "@mve_vcmp<mve_cmp_op>q_n_f<mode>" [ (set (match_operand:HI 0 "vpr_register_operand" "=Up") (MVE_FP_COMPARISONS:HI (match_operand:MVE_0 1 "s_register_operand" "w") @@ -3282,7 +3282,7 @@ ;; ;; [vpselq_u, vpselq_s]) ;; -(define_insn "mve_vpselq_<supf><mode>" +(define_insn "@mve_vpselq_<supf><mode>" [ (set (match_operand:MVE_1 0 "s_register_operand" "=w") (unspec:MVE_1 [(match_operand:MVE_1 1 "s_register_operand" "w") @@ -4377,7 +4377,7 @@ ;; ;; [vpselq_f]) ;; -(define_insn "mve_vpselq_f<mode>" +(define_insn "@mve_vpselq_f<mode>" [ (set (match_operand:MVE_0 0 "s_register_operand" "=w") (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "w") diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 2a1e304..cc82d06 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -1416,93 +1416,6 @@ [(set_attr "type" "neon_qsub<q>")] ) -(define_expand "vec_cmp<mode><v_cmp_result>" - [(set (match_operand:<V_cmp_result> 0 "s_register_operand") - (match_operator:<V_cmp_result> 1 "comparison_operator" - [(match_operand:VDQW 2 "s_register_operand") - (match_operand:VDQW 3 "reg_or_zero_operand")]))] - "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" -{ - arm_expand_vector_compare (operands[0], GET_CODE (operands[1]), - operands[2], operands[3], false); - DONE; -}) - -(define_expand "vec_cmpu<mode><mode>" - [(set (match_operand:VDQIW 0 "s_register_operand") - (match_operator:VDQIW 1 "comparison_operator" - [(match_operand:VDQIW 2 "s_register_operand") - (match_operand:VDQIW 3 "reg_or_zero_operand")]))] - "TARGET_NEON" -{ - arm_expand_vector_compare (operands[0], GET_CODE (operands[1]), - operands[2], operands[3], false); - DONE; -}) - -;; Conditional instructions. These are comparisons with conditional moves for -;; vectors. They perform the assignment: -;; -;; Vop0 = (Vop4 <op3> Vop5) ? Vop1 : Vop2; -;; -;; where op3 is <, <=, ==, !=, >= or >. Operations are performed -;; element-wise. - -(define_expand "vcond<mode><mode>" - [(set (match_operand:VDQW 0 "s_register_operand") - (if_then_else:VDQW - (match_operator 3 "comparison_operator" - [(match_operand:VDQW 4 "s_register_operand") - (match_operand:VDQW 5 "reg_or_zero_operand")]) - (match_operand:VDQW 1 "s_register_operand") - (match_operand:VDQW 2 "s_register_operand")))] - "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" -{ - arm_expand_vcond (operands, <V_cmp_result>mode); - DONE; -}) - -(define_expand "vcond<V_cvtto><mode>" - [(set (match_operand:<V_CVTTO> 0 "s_register_operand") - (if_then_else:<V_CVTTO> - (match_operator 3 "comparison_operator" - [(match_operand:V32 4 "s_register_operand") - (match_operand:V32 5 "reg_or_zero_operand")]) - (match_operand:<V_CVTTO> 1 "s_register_operand") - (match_operand:<V_CVTTO> 2 "s_register_operand")))] - "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" -{ - arm_expand_vcond (operands, <V_cmp_result>mode); - DONE; -}) - -(define_expand "vcondu<mode><v_cmp_result>" - [(set (match_operand:VDQW 0 "s_register_operand") - (if_then_else:VDQW - (match_operator 3 "arm_comparison_operator" - [(match_operand:<V_cmp_result> 4 "s_register_operand") - (match_operand:<V_cmp_result> 5 "reg_or_zero_operand")]) - (match_operand:VDQW 1 "s_register_operand") - (match_operand:VDQW 2 "s_register_operand")))] - "TARGET_NEON" -{ - arm_expand_vcond (operands, <V_cmp_result>mode); - DONE; -}) - -(define_expand "vcond_mask_<mode><v_cmp_result>" - [(set (match_operand:VDQW 0 "s_register_operand") - (if_then_else:VDQW - (match_operand:<V_cmp_result> 3 "s_register_operand") - (match_operand:VDQW 1 "s_register_operand") - (match_operand:VDQW 2 "s_register_operand")))] - "TARGET_NEON" -{ - emit_insn (gen_neon_vbsl<mode> (operands[0], operands[3], operands[1], - operands[2])); - DONE; -}) - ;; Patterns for builtins. ; good for plain vadd, vaddq. @@ -2578,16 +2491,6 @@ DONE; }) -(define_insn "neon_vtst<mode>" - [(set (match_operand:VDQIW 0 "s_register_operand" "=w") - (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:VDQIW 2 "s_register_operand" "w")] - UNSPEC_VTST))] - "TARGET_NEON" - "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "type" "neon_tst<q>")] -) - (define_insn "neon_vtst_combine<mode>" [(set (match_operand:VDQIW 0 "s_register_operand" "=w") (plus:VDQIW diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md index 07ca53b..0778db1 100644 --- a/gcc/config/arm/unspecs.md +++ b/gcc/config/arm/unspecs.md @@ -596,8 +596,6 @@ VCVTQ_N_FROM_F_U VADDLVQ_P_S VADDLVQ_P_U - VCMPNEQ_U - VCMPNEQ_S VSHLQ_S VSHLQ_U VABDQ_S @@ -605,9 +603,6 @@ VADDVAQ_S VADDVQ_P_S VBRSRQ_N_S - VCMPEQQ_S - VCMPEQQ_N_S - VCMPNEQ_N_S VHADDQ_S VHADDQ_N_S VHSUBQ_S @@ -645,9 +640,6 @@ VADDVAQ_U VADDVQ_P_U VBRSRQ_N_U - VCMPEQQ_U - VCMPEQQ_N_U - VCMPNEQ_N_U VHADDQ_U VHADDQ_N_U VHSUBQ_U @@ -680,14 +672,6 @@ VSHLQ_R_U VSUBQ_U VSUBQ_N_U - VCMPGEQ_N_S - VCMPGEQ_S - VCMPGTQ_N_S - VCMPGTQ_S - VCMPLEQ_N_S - VCMPLEQ_S - VCMPLTQ_N_S - VCMPLTQ_S VHCADDQ_ROT270_S VHCADDQ_ROT90_S VMAXAQ_S @@ -702,10 +686,6 @@ VQRDMULHQ_N_S VQRDMULHQ_S VQSHLUQ_N_S - VCMPCSQ_N_U - VCMPCSQ_U - VCMPHIQ_N_U - VCMPHIQ_U VABDQ_M_S VABDQ_M_U VABDQ_F diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md index 0b2b3b1..265fa40 100644 --- a/gcc/config/arm/vec-common.md +++ b/gcc/config/arm/vec-common.md @@ -362,3 +362,127 @@ DONE; } }) + +(define_expand "vec_cmp<mode><v_cmp_result>" + [(set (match_operand:<V_cmp_result> 0 "s_register_operand") + (match_operator:<V_cmp_result> 1 "comparison_operator" + [(match_operand:VDQWH 2 "s_register_operand") + (match_operand:VDQWH 3 "reg_or_zero_operand")]))] + "ARM_HAVE_<MODE>_ARITH + && !TARGET_REALLY_IWMMXT + && (!<Is_float_mode> || flag_unsafe_math_optimizations)" +{ + arm_expand_vector_compare (operands[0], GET_CODE (operands[1]), + operands[2], operands[3], false, false); + DONE; +}) + +(define_expand "vec_cmpu<mode><mode>" + [(set (match_operand:VDQIW 0 "s_register_operand") + (match_operator:VDQIW 1 "comparison_operator" + [(match_operand:VDQIW 2 "s_register_operand") + (match_operand:VDQIW 3 "reg_or_zero_operand")]))] + "ARM_HAVE_<MODE>_ARITH + && !TARGET_REALLY_IWMMXT" +{ + arm_expand_vector_compare (operands[0], GET_CODE (operands[1]), + operands[2], operands[3], false, false); + DONE; +}) + +;; Conditional instructions. These are comparisons with conditional moves for +;; vectors. They perform the assignment: +;; +;; Vop0 = (Vop4 <op3> Vop5) ? Vop1 : Vop2; +;; +;; where op3 is <, <=, ==, !=, >= or >. Operations are performed +;; element-wise. + +(define_expand "vcond<mode><mode>" + [(set (match_operand:VDQWH 0 "s_register_operand") + (if_then_else:VDQWH + (match_operator 3 "comparison_operator" + [(match_operand:VDQWH 4 "s_register_operand") + (match_operand:VDQWH 5 "reg_or_zero_operand")]) + (match_operand:VDQWH 1 "s_register_operand") + (match_operand:VDQWH 2 "s_register_operand")))] + "ARM_HAVE_<MODE>_ARITH + && !TARGET_REALLY_IWMMXT + && (!<Is_float_mode> || flag_unsafe_math_optimizations)" +{ + arm_expand_vcond (operands, <V_cmp_result>mode); + DONE; +}) + +(define_expand "vcond<V_cvtto><mode>" + [(set (match_operand:<V_CVTTO> 0 "s_register_operand") + (if_then_else:<V_CVTTO> + (match_operator 3 "comparison_operator" + [(match_operand:V32 4 "s_register_operand") + (match_operand:V32 5 "reg_or_zero_operand")]) + (match_operand:<V_CVTTO> 1 "s_register_operand") + (match_operand:<V_CVTTO> 2 "s_register_operand")))] + "ARM_HAVE_<MODE>_ARITH + && !TARGET_REALLY_IWMMXT + && (!<Is_float_mode> || flag_unsafe_math_optimizations)" +{ + arm_expand_vcond (operands, <V_cmp_result>mode); + DONE; +}) + +(define_expand "vcond<VH_cvtto><mode>" + [(set (match_operand:<VH_CVTTO> 0 "s_register_operand") + (if_then_else:<VH_CVTTO> + (match_operator 3 "comparison_operator" + [(match_operand:V16 4 "s_register_operand") + (match_operand:V16 5 "reg_or_zero_operand")]) + (match_operand:<VH_CVTTO> 1 "s_register_operand") + (match_operand:<VH_CVTTO> 2 "s_register_operand")))] + "ARM_HAVE_<MODE>_ARITH + && !TARGET_REALLY_IWMMXT + && (!<Is_float_mode> || flag_unsafe_math_optimizations)" +{ + arm_expand_vcond (operands, <V_cmp_result>mode); + DONE; +}) + +(define_expand "vcondu<mode><v_cmp_result>" + [(set (match_operand:VDQW 0 "s_register_operand") + (if_then_else:VDQW + (match_operator 3 "arm_comparison_operator" + [(match_operand:<V_cmp_result> 4 "s_register_operand") + (match_operand:<V_cmp_result> 5 "reg_or_zero_operand")]) + (match_operand:VDQW 1 "s_register_operand") + (match_operand:VDQW 2 "s_register_operand")))] + "ARM_HAVE_<MODE>_ARITH + && !TARGET_REALLY_IWMMXT" +{ + arm_expand_vcond (operands, <V_cmp_result>mode); + DONE; +}) + +(define_expand "vcond_mask_<mode><v_cmp_result>" + [(set (match_operand:VDQWH 0 "s_register_operand") + (if_then_else:VDQWH + (match_operand:<V_cmp_result> 3 "s_register_operand") + (match_operand:VDQWH 1 "s_register_operand") + (match_operand:VDQWH 2 "s_register_operand")))] + "ARM_HAVE_<MODE>_ARITH + && !TARGET_REALLY_IWMMXT + && (!<Is_float_mode> || flag_unsafe_math_optimizations)" +{ + if (TARGET_NEON) + { + emit_insn (gen_neon_vbsl (<MODE>mode, operands[0], operands[3], + operands[1], operands[2])); + } + else if (TARGET_HAVE_MVE) + { + emit_insn (gen_mve_vpselq (VPSELQ_S, <MODE>mode, operands[0], + operands[1], operands[2], operands[3])); + } + else + gcc_unreachable (); + + DONE; +}) diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index 5cfde5b..0fa8d45 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -3661,7 +3661,8 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false) { op_true = force_reg (mode, op_true); - if (!nonimmediate_operand (op_false, mode)) + if (GET_MODE_SIZE (mode) < 16 + || !nonimmediate_operand (op_false, mode)) op_false = force_reg (mode, op_false); emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cmp, @@ -3680,6 +3681,13 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false) switch (mode) { + case E_V2SFmode: + if (TARGET_SSE4_1) + { + gen = gen_mmx_blendvps; + op_true = force_reg (mode, op_true); + } + break; case E_V4SFmode: if (TARGET_SSE4_1) gen = gen_sse4_1_blendvps; @@ -18654,6 +18662,242 @@ expand_vec_perm_vperm2f128_vblend (struct expand_vec_perm_d *d) return true; } +/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement + a two vector permutation using two single vector permutations and + {,v}{,p}unpckl{ps,pd,bw,wd,dq}. If two_insn, succeed only if one + of dfirst or dsecond is identity permutation. */ + +static bool +expand_vec_perm_2perm_interleave (struct expand_vec_perm_d *d, bool two_insn) +{ + unsigned i, nelt = d->nelt, nelt2 = nelt / 2, lane = nelt; + struct expand_vec_perm_d dfirst, dsecond, dfinal; + bool ident1 = true, ident2 = true; + + if (d->one_operand_p) + return false; + + if (GET_MODE_SIZE (d->vmode) == 16) + { + if (!TARGET_SSE) + return false; + if (d->vmode != V4SFmode && d->vmode != V2DFmode && !TARGET_SSE2) + return false; + } + else if (GET_MODE_SIZE (d->vmode) == 32) + { + if (!TARGET_AVX) + return false; + if (d->vmode != V8SFmode && d->vmode != V4DFmode && !TARGET_AVX2) + return false; + lane = nelt2; + } + else + return false; + + for (i = 1; i < nelt; i++) + if ((d->perm[i] >= nelt) != ((d->perm[0] >= nelt) ^ (i & 1))) + return false; + + dfirst = *d; + dsecond = *d; + dfinal = *d; + dfirst.op1 = dfirst.op0; + dfirst.one_operand_p = true; + dsecond.op0 = dsecond.op1; + dsecond.one_operand_p = true; + + for (i = 0; i < nelt; i++) + if (d->perm[i] >= nelt) + { + dsecond.perm[i / 2 + (i >= lane ? lane / 2 : 0)] = d->perm[i] - nelt; + if (d->perm[i] - nelt != i / 2 + (i >= lane ? lane / 2 : 0)) + ident2 = false; + dsecond.perm[i / 2 + (i >= lane ? lane : lane / 2)] + = d->perm[i] - nelt; + } + else + { + dfirst.perm[i / 2 + (i >= lane ? lane / 2 : 0)] = d->perm[i]; + if (d->perm[i] != i / 2 + (i >= lane ? lane / 2 : 0)) + ident1 = false; + dfirst.perm[i / 2 + (i >= lane ? lane : lane / 2)] = d->perm[i]; + } + + if (two_insn && !ident1 && !ident2) + return false; + + if (!d->testing_p) + { + if (!ident1) + dfinal.op0 = dfirst.target = gen_reg_rtx (d->vmode); + if (!ident2) + dfinal.op1 = dsecond.target = gen_reg_rtx (d->vmode); + if (d->perm[0] >= nelt) + std::swap (dfinal.op0, dfinal.op1); + } + + bool ok; + rtx_insn *seq1 = NULL, *seq2 = NULL; + + if (!ident1) + { + start_sequence (); + ok = expand_vec_perm_1 (&dfirst); + seq1 = get_insns (); + end_sequence (); + + if (!ok) + return false; + } + + if (!ident2) + { + start_sequence (); + ok = expand_vec_perm_1 (&dsecond); + seq2 = get_insns (); + end_sequence (); + + if (!ok) + return false; + } + + if (d->testing_p) + return true; + + for (i = 0; i < nelt; i++) + { + dfinal.perm[i] = i / 2; + if (i >= lane) + dfinal.perm[i] += lane / 2; + if ((i & 1) != 0) + dfinal.perm[i] += nelt; + } + emit_insn (seq1); + emit_insn (seq2); + ok = expand_vselect_vconcat (dfinal.target, dfinal.op0, dfinal.op1, + dfinal.perm, dfinal.nelt, false); + gcc_assert (ok); + return true; +} + +/* A subroutine of ix86_expand_vec_perm_const_1. Try to simplify + the permutation using two single vector permutations and the SSE4_1 pblendv + instruction. If two_insn, succeed only if one of dfirst or dsecond is + identity permutation. */ + +static bool +expand_vec_perm_2perm_pblendv (struct expand_vec_perm_d *d, bool two_insn) +{ + unsigned i, nelt = d->nelt; + struct expand_vec_perm_d dfirst, dsecond, dfinal; + machine_mode vmode = d->vmode; + bool ident1 = true, ident2 = true; + + /* Use the same checks as in expand_vec_perm_blend. */ + if (d->one_operand_p) + return false; + if (TARGET_AVX2 && GET_MODE_SIZE (vmode) == 32) + ; + else if (TARGET_AVX && (vmode == V4DFmode || vmode == V8SFmode)) + ; + else if (TARGET_SSE4_1 && GET_MODE_SIZE (vmode) == 16) + ; + else + return false; + + dfirst = *d; + dsecond = *d; + dfinal = *d; + dfirst.op1 = dfirst.op0; + dfirst.one_operand_p = true; + dsecond.op0 = dsecond.op1; + dsecond.one_operand_p = true; + + for (i = 0; i < nelt; ++i) + if (d->perm[i] >= nelt) + { + dfirst.perm[i] = 0xff; + dsecond.perm[i] = d->perm[i] - nelt; + if (d->perm[i] != i + nelt) + ident2 = false; + } + else + { + dsecond.perm[i] = 0xff; + dfirst.perm[i] = d->perm[i]; + if (d->perm[i] != i) + ident1 = false; + } + + if (two_insn && !ident1 && !ident2) + return false; + + /* For now. Ideally treat 0xff as a wildcard. */ + for (i = 0; i < nelt; ++i) + if (dfirst.perm[i] == 0xff) + { + if (GET_MODE_SIZE (vmode) == 32 + && dfirst.perm[i ^ (nelt / 2)] != 0xff) + dfirst.perm[i] = dfirst.perm[i ^ (nelt / 2)] ^ (nelt / 2); + else + dfirst.perm[i] = i; + } + else + { + if (GET_MODE_SIZE (vmode) == 32 + && dsecond.perm[i ^ (nelt / 2)] != 0xff) + dsecond.perm[i] = dsecond.perm[i ^ (nelt / 2)] ^ (nelt / 2); + else + dsecond.perm[i] = i; + } + + if (!d->testing_p) + { + if (!ident1) + dfinal.op0 = dfirst.target = gen_reg_rtx (d->vmode); + if (!ident2) + dfinal.op1 = dsecond.target = gen_reg_rtx (d->vmode); + } + + bool ok; + rtx_insn *seq1 = NULL, *seq2 = NULL; + + if (!ident1) + { + start_sequence (); + ok = expand_vec_perm_1 (&dfirst); + seq1 = get_insns (); + end_sequence (); + + if (!ok) + return false; + } + + if (!ident2) + { + start_sequence (); + ok = expand_vec_perm_1 (&dsecond); + seq2 = get_insns (); + end_sequence (); + + if (!ok) + return false; + } + + if (d->testing_p) + return true; + + for (i = 0; i < nelt; ++i) + dfinal.perm[i] = (d->perm[i] >= nelt ? i + nelt : i); + + emit_insn (seq1); + emit_insn (seq2); + ok = expand_vec_perm_blend (&dfinal); + gcc_assert (ok); + return true; +} + /* A subroutine of ix86_expand_vec_perm_const_1. Implement a V4DF permutation using two vperm2f128, followed by a vshufpd insn blending the two vectors together. */ @@ -19765,6 +20009,12 @@ ix86_expand_vec_perm_const_1 (struct expand_vec_perm_d *d) if (expand_vec_perm_pblendv (d)) return true; + if (expand_vec_perm_2perm_interleave (d, true)) + return true; + + if (expand_vec_perm_2perm_pblendv (d, true)) + return true; + /* Try sequences of three instructions. */ if (expand_vec_perm_even_odd_pack (d)) @@ -19782,6 +20032,12 @@ ix86_expand_vec_perm_const_1 (struct expand_vec_perm_d *d) if (expand_vec_perm_vperm2f128_vblend (d)) return true; + if (expand_vec_perm_2perm_interleave (d, false)) + return true; + + if (expand_vec_perm_2perm_pblendv (d, false)) + return true; + /* Try sequences of four instructions. */ if (expand_vec_perm_even_odd_trunc (d)) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 915f89f..befe69e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -18000,8 +18000,8 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi) tree cmp_type = truth_type_for (type); gimple_seq stmts = NULL; tree cmp = gimple_build (&stmts, tcode, cmp_type, arg0, arg1); - gsi_insert_before (gsi, stmts, GSI_SAME_STMT); - gimple *g = gimple_build_assign (gimple_call_lhs (stmt), + gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + gimple* g = gimple_build_assign (gimple_call_lhs (stmt), VEC_COND_EXPR, cmp, minus_one_vec, zero_vec); gimple_set_location (g, loc); @@ -19732,6 +19732,7 @@ ix86_division_cost (const struct processor_costs *cost, static int ix86_shift_rotate_cost (const struct processor_costs *cost, + enum rtx_code code, enum machine_mode mode, bool constant_op1, HOST_WIDE_INT op1_val, bool speed, @@ -19770,6 +19771,19 @@ ix86_shift_rotate_cost (const struct processor_costs *cost, count = 7; return ix86_vec_cost (mode, cost->sse_op * count); } + /* V*DImode arithmetic right shift is emulated. */ + else if (code == ASHIFTRT + && (mode == V2DImode || mode == V4DImode) + && !TARGET_XOP + && !TARGET_AVX512VL) + { + int count = 4; + if (constant_op1 && op1_val == 63 && TARGET_SSE4_2) + count = 2; + else if (constant_op1) + count = 3; + return ix86_vec_cost (mode, cost->sse_op * count); + } else return ix86_vec_cost (mode, cost->sse_op); } @@ -19939,13 +19953,15 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno, case LSHIFTRT: case ROTATERT: bool skip_op0, skip_op1; - *total = ix86_shift_rotate_cost (cost, mode, CONSTANT_P (XEXP (x, 1)), + *total = ix86_shift_rotate_cost (cost, code, mode, + CONSTANT_P (XEXP (x, 1)), CONST_INT_P (XEXP (x, 1)) ? INTVAL (XEXP (x, 1)) : -1, speed, GET_CODE (XEXP (x, 1)) == AND, SUBREG_P (XEXP (x, 1)) - && GET_CODE (XEXP (XEXP (x, 1), 0)) == AND, + && GET_CODE (XEXP (XEXP (x, 1), + 0)) == AND, &skip_op0, &skip_op1); if (skip_op0 || skip_op1) { @@ -22383,11 +22399,16 @@ ix86_add_stmt_cost (class vec_info *vinfo, void *data, int count, case LROTATE_EXPR: case RROTATE_EXPR: { + tree op1 = gimple_assign_rhs1 (stmt_info->stmt); tree op2 = gimple_assign_rhs2 (stmt_info->stmt); stmt_cost = ix86_shift_rotate_cost - (ix86_cost, mode, + (ix86_cost, + (subcode == RSHIFT_EXPR + && !TYPE_UNSIGNED (TREE_TYPE (op1))) + ? ASHIFTRT : LSHIFTRT, mode, TREE_CODE (op2) == INTEGER_CST, - cst_and_fits_in_hwi (op2) ? int_cst_value (op2) : -1, + cst_and_fits_in_hwi (op2) + ? int_cst_value (op2) : -1, true, false, false, NULL, NULL); } break; diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index f085708..7fc2e5d 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -49,6 +49,7 @@ ;; All 8-byte vector modes handled by MMX (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF]) +(define_mode_iterator MMXMODE124 [V8QI V4HI V2SI V2SF]) ;; Mix-n-match (define_mode_iterator MMXMODE12 [V8QI V4HI]) @@ -56,12 +57,22 @@ (define_mode_iterator MMXMODE24 [V4HI V2SI]) (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI]) +;; All V2S* modes +(define_mode_iterator V2FI [V2SF V2SI]) + ;; Mapping from integer vector mode to mnemonic suffix (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")]) (define_mode_attr mmxdoublemode [(V8QI "V8HI") (V4HI "V4SI")]) +;; Mapping of vector float modes to an integer mode of the same size +(define_mode_attr mmxintvecmode + [(V2SF "V2SI") (V2SI "V2SI") (V4HI "V4HI") (V8QI "V8QI")]) + +(define_mode_attr mmxintvecmodelower + [(V2SF "v2si") (V2SI "v2si") (V4HI "v4hi") (V8QI "v8qi")]) + (define_mode_attr Yv_Yw [(V8QI "Yw") (V4HI "Yw") (V2SI "Yv") (V1DI "Yv") (V2SF "Yv")]) @@ -714,6 +725,85 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) +(define_insn "*mmx_maskcmpv2sf3_comm" + [(set (match_operand:V2SF 0 "register_operand" "=x,x") + (match_operator:V2SF 3 "sse_comparison_operator" + [(match_operand:V2SF 1 "register_operand" "%0,x") + (match_operand:V2SF 2 "register_operand" "x,x")]))] + "TARGET_MMX_WITH_SSE + && GET_RTX_CLASS (GET_CODE (operands[3])) == RTX_COMM_COMPARE" + "@ + cmp%D3ps\t{%2, %0|%0, %2} + vcmp%D3ps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "noavx,avx") + (set_attr "type" "ssecmp") + (set_attr "length_immediate" "1") + (set_attr "prefix" "orig,vex") + (set_attr "mode" "V4SF")]) + +(define_insn "*mmx_maskcmpv2sf3" + [(set (match_operand:V2SF 0 "register_operand" "=x,x") + (match_operator:V2SF 3 "sse_comparison_operator" + [(match_operand:V2SF 1 "register_operand" "0,x") + (match_operand:V2SF 2 "register_operand" "x,x")]))] + "TARGET_MMX_WITH_SSE" + "@ + cmp%D3ps\t{%2, %0|%0, %2} + vcmp%D3ps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "noavx,avx") + (set_attr "type" "ssecmp") + (set_attr "length_immediate" "1") + (set_attr "prefix" "orig,vex") + (set_attr "mode" "V4SF")]) + +(define_expand "vec_cmpv2sfv2si" + [(set (match_operand:V2SI 0 "register_operand") + (match_operator:V2SI 1 "" + [(match_operand:V2SF 2 "register_operand") + (match_operand:V2SF 3 "register_operand")]))] + "TARGET_MMX_WITH_SSE" +{ + bool ok = ix86_expand_fp_vec_cmp (operands); + gcc_assert (ok); + DONE; +}) + +(define_expand "vcond<mode>v2sf" + [(set (match_operand:V2FI 0 "register_operand") + (if_then_else:V2FI + (match_operator 3 "" + [(match_operand:V2SF 4 "register_operand") + (match_operand:V2SF 5 "register_operand")]) + (match_operand:V2FI 1) + (match_operand:V2FI 2)))] + "TARGET_MMX_WITH_SSE" +{ + bool ok = ix86_expand_fp_vcond (operands); + gcc_assert (ok); + DONE; +}) + +(define_insn "mmx_blendvps" + [(set (match_operand:V2SF 0 "register_operand" "=Yr,*x,x") + (unspec:V2SF + [(match_operand:V2SF 1 "register_operand" "0,0,x") + (match_operand:V2SF 2 "register_operand" "Yr,*x,x") + (match_operand:V2SF 3 "register_operand" "Yz,Yz,x")] + UNSPEC_BLENDV))] + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" + "@ + blendvps\t{%3, %2, %0|%0, %2, %3} + blendvps\t{%3, %2, %0|%0, %2, %3} + vblendvps\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "isa" "noavx,noavx,avx") + (set_attr "type" "ssemov") + (set_attr "length_immediate" "1") + (set_attr "prefix_data16" "1,1,*") + (set_attr "prefix_extra" "1") + (set_attr "prefix" "orig,orig,vex") + (set_attr "btver2_decode" "vector") + (set_attr "mode" "V4SF")]) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Parallel single-precision floating point logical operations @@ -1657,42 +1747,46 @@ DONE; }) -(define_expand "vcond<mode><mode>" - [(set (match_operand:MMXMODEI 0 "register_operand") - (if_then_else:MMXMODEI +(define_expand "vcond<MMXMODE124:mode><MMXMODEI:mode>" + [(set (match_operand:MMXMODE124 0 "register_operand") + (if_then_else:MMXMODE124 (match_operator 3 "" [(match_operand:MMXMODEI 4 "register_operand") (match_operand:MMXMODEI 5 "register_operand")]) - (match_operand:MMXMODEI 1) - (match_operand:MMXMODEI 2)))] - "TARGET_MMX_WITH_SSE" + (match_operand:MMXMODE124 1) + (match_operand:MMXMODE124 2)))] + "TARGET_MMX_WITH_SSE + && (GET_MODE_NUNITS (<MMXMODE124:MODE>mode) + == GET_MODE_NUNITS (<MMXMODEI:MODE>mode))" { bool ok = ix86_expand_int_vcond (operands); gcc_assert (ok); DONE; }) -(define_expand "vcondu<mode><mode>" - [(set (match_operand:MMXMODEI 0 "register_operand") - (if_then_else:MMXMODEI +(define_expand "vcondu<MMXMODE124:mode><MMXMODEI:mode>" + [(set (match_operand:MMXMODE124 0 "register_operand") + (if_then_else:MMXMODE124 (match_operator 3 "" [(match_operand:MMXMODEI 4 "register_operand") (match_operand:MMXMODEI 5 "register_operand")]) - (match_operand:MMXMODEI 1) - (match_operand:MMXMODEI 2)))] - "TARGET_MMX_WITH_SSE" + (match_operand:MMXMODE124 1) + (match_operand:MMXMODE124 2)))] + "TARGET_MMX_WITH_SSE + && (GET_MODE_NUNITS (<MMXMODE124:MODE>mode) + == GET_MODE_NUNITS (<MMXMODEI:MODE>mode))" { bool ok = ix86_expand_int_vcond (operands); gcc_assert (ok); DONE; }) -(define_expand "vcond_mask_<mode><mode>" - [(set (match_operand:MMXMODEI 0 "register_operand") - (vec_merge:MMXMODEI - (match_operand:MMXMODEI 1 "register_operand") - (match_operand:MMXMODEI 2 "register_operand") - (match_operand:MMXMODEI 3 "register_operand")))] +(define_expand "vcond_mask_<mode><mmxintvecmodelower>" + [(set (match_operand:MMXMODE124 0 "register_operand") + (vec_merge:MMXMODE124 + (match_operand:MMXMODE124 1 "register_operand") + (match_operand:MMXMODE124 2 "register_operand") + (match_operand:<mmxintvecmode> 3 "register_operand")))] "TARGET_MMX_WITH_SSE" { ix86_expand_sse_movcc (operands[0], operands[3], @@ -1722,11 +1816,11 @@ ;; XOP parallel XMM conditional moves (define_insn "*xop_pcmov_<mode>" - [(set (match_operand:MMXMODEI 0 "register_operand" "=x") - (if_then_else:MMXMODEI - (match_operand:MMXMODEI 3 "register_operand" "x") - (match_operand:MMXMODEI 1 "register_operand" "x") - (match_operand:MMXMODEI 2 "register_operand" "x")))] + [(set (match_operand:MMXMODE124 0 "register_operand" "=x") + (if_then_else:MMXMODE124 + (match_operand:MMXMODE124 3 "register_operand" "x") + (match_operand:MMXMODE124 1 "register_operand" "x") + (match_operand:MMXMODE124 2 "register_operand" "x")))] "TARGET_XOP && TARGET_MMX_WITH_SSE" "vpcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse4arg")]) diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 6dfbb08..abd307e 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1535,6 +1535,38 @@ (and (match_code "mem") (match_test "MEM_ALIGN (op) < GET_MODE_BITSIZE (mode)"))) +;; Return true if OP is a parallel for an mov{d,q,dqa,ps,pd} vec_select, +;; where one of the two operands of the vec_concat is const0_operand. +(define_predicate "movq_parallel" + (match_code "parallel") +{ + unsigned nelt = XVECLEN (op, 0); + unsigned nelt2 = nelt >> 1; + unsigned i; + + if (nelt < 2) + return false; + + /* Validate that all of the elements are constants, + lower halves of permute are lower halves of the first operand, + upper halves of permute come from any of the second operand. */ + for (i = 0; i < nelt; ++i) + { + rtx er = XVECEXP (op, 0, i); + unsigned HOST_WIDE_INT ei; + + if (!CONST_INT_P (er)) + return 0; + ei = INTVAL (er); + if (i < nelt2 && ei != i) + return 0; + if (i >= nelt2 && (ei < nelt || ei >= nelt << 1)) + return 0; + } + + return 1; +}) + ;; Return true if OP is a vzeroall operation, known to be a PARALLEL. (define_predicate "vzeroall_operation" (match_code "parallel") diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 244fb13..62f4e15f 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -811,19 +811,22 @@ ;; Mapping of vector modes to a vector mode of double size (define_mode_attr ssedoublevecmode - [(V32QI "V64QI") (V16HI "V32HI") (V8SI "V16SI") (V4DI "V8DI") + [(V64QI "V128QI") (V32HI "V64HI") (V16SI "V32SI") (V8DI "V16DI") + (V32QI "V64QI") (V16HI "V32HI") (V8SI "V16SI") (V4DI "V8DI") (V16QI "V32QI") (V8HI "V16HI") (V4SI "V8SI") (V2DI "V4DI") + (V16SF "V32SF") (V8DF "V16DF") (V8SF "V16SF") (V4DF "V8DF") (V4SF "V8SF") (V2DF "V4DF")]) ;; Mapping of vector modes to a vector mode of half size +;; instead of V1DI/V1DF, DI/DF are used for V2DI/V2DF although they are scalar. (define_mode_attr ssehalfvecmode [(V64QI "V32QI") (V32HI "V16HI") (V16SI "V8SI") (V8DI "V4DI") (V4TI "V2TI") (V32QI "V16QI") (V16HI "V8HI") (V8SI "V4SI") (V4DI "V2DI") - (V16QI "V8QI") (V8HI "V4HI") (V4SI "V2SI") + (V16QI "V8QI") (V8HI "V4HI") (V4SI "V2SI") (V2DI "DI") (V16SF "V8SF") (V8DF "V4DF") (V8SF "V4SF") (V4DF "V2DF") - (V4SF "V2SF")]) + (V4SF "V2SF") (V2DF "DF")]) (define_mode_attr ssehalfvecmodelower [(V64QI "v32qi") (V32HI "v16hi") (V16SI "v8si") (V8DI "v4di") (V4TI "v2ti") @@ -12465,7 +12468,7 @@ (set_attr "prefix" "orig,vex") (set_attr "mode" "<sseinsnmode>")]) -(define_insn "ashr<mode>3<mask_name>" +(define_insn "<mask_codefor>ashr<mode>3<mask_name>" [(set (match_operand:VI248_AVX512BW_AVX512VL 0 "register_operand" "=v,v") (ashiftrt:VI248_AVX512BW_AVX512VL (match_operand:VI248_AVX512BW_AVX512VL 1 "nonimmediate_operand" "v,vm") @@ -12479,6 +12482,126 @@ (const_string "0"))) (set_attr "mode" "<sseinsnmode>")]) +(define_expand "ashr<mode>3" + [(set (match_operand:VI248_AVX512BW 0 "register_operand") + (ashiftrt:VI248_AVX512BW + (match_operand:VI248_AVX512BW 1 "nonimmediate_operand") + (match_operand:DI 2 "nonmemory_operand")))] + "TARGET_AVX512F") + +(define_expand "ashrv4di3" + [(set (match_operand:V4DI 0 "register_operand") + (ashiftrt:V4DI + (match_operand:V4DI 1 "nonimmediate_operand") + (match_operand:DI 2 "nonmemory_operand")))] + "TARGET_AVX2" +{ + if (!TARGET_AVX512VL) + { + if (CONST_INT_P (operands[2]) && UINTVAL (operands[2]) >= 63) + { + rtx zero = force_reg (V4DImode, CONST0_RTX (V4DImode)); + emit_insn (gen_avx2_gtv4di3 (operands[0], zero, operands[1])); + DONE; + } + if (operands[2] == const0_rtx) + { + emit_move_insn (operands[0], operands[1]); + DONE; + } + operands[1] = force_reg (V4DImode, operands[1]); + if (CONST_INT_P (operands[2])) + { + vec_perm_builder sel (8, 8, 1); + sel.quick_grow (8); + rtx arg0, arg1; + rtx op1 = lowpart_subreg (V8SImode, operands[1], V4DImode); + rtx target = gen_reg_rtx (V8SImode); + if (INTVAL (operands[2]) > 32) + { + arg0 = gen_reg_rtx (V8SImode); + arg1 = gen_reg_rtx (V8SImode); + emit_insn (gen_ashrv8si3 (arg1, op1, GEN_INT (31))); + emit_insn (gen_ashrv8si3 (arg0, op1, + GEN_INT (INTVAL (operands[2]) - 32))); + sel[0] = 1; + sel[1] = 9; + sel[2] = 3; + sel[3] = 11; + sel[4] = 5; + sel[5] = 13; + sel[6] = 7; + sel[7] = 15; + } + else if (INTVAL (operands[2]) == 32) + { + arg0 = op1; + arg1 = gen_reg_rtx (V8SImode); + emit_insn (gen_ashrv8si3 (arg1, op1, GEN_INT (31))); + sel[0] = 1; + sel[1] = 9; + sel[2] = 3; + sel[3] = 11; + sel[4] = 5; + sel[5] = 13; + sel[6] = 7; + sel[7] = 15; + } + else + { + arg0 = gen_reg_rtx (V4DImode); + arg1 = gen_reg_rtx (V8SImode); + emit_insn (gen_lshrv4di3 (arg0, operands[1], operands[2])); + emit_insn (gen_ashrv8si3 (arg1, op1, operands[2])); + arg0 = lowpart_subreg (V8SImode, arg0, V4DImode); + sel[0] = 0; + sel[1] = 9; + sel[2] = 2; + sel[3] = 11; + sel[4] = 4; + sel[5] = 13; + sel[6] = 6; + sel[7] = 15; + } + vec_perm_indices indices (sel, 2, 8); + bool ok = targetm.vectorize.vec_perm_const (V8SImode, target, + arg0, arg1, indices); + gcc_assert (ok); + emit_move_insn (operands[0], + lowpart_subreg (V4DImode, target, V8SImode)); + DONE; + } + + rtx zero = force_reg (V4DImode, CONST0_RTX (V4DImode)); + rtx zero_or_all_ones = gen_reg_rtx (V4DImode); + emit_insn (gen_avx2_gtv4di3 (zero_or_all_ones, zero, operands[1])); + rtx lshr_res = gen_reg_rtx (V4DImode); + emit_insn (gen_lshrv4di3 (lshr_res, operands[1], operands[2])); + rtx ashl_res = gen_reg_rtx (V4DImode); + rtx amount; + if (TARGET_64BIT) + { + amount = gen_reg_rtx (DImode); + emit_insn (gen_subdi3 (amount, force_reg (DImode, GEN_INT (64)), + operands[2])); + } + else + { + rtx temp = gen_reg_rtx (SImode); + emit_insn (gen_subsi3 (temp, force_reg (SImode, GEN_INT (64)), + lowpart_subreg (SImode, operands[2], + DImode))); + amount = gen_reg_rtx (V4SImode); + emit_insn (gen_vec_setv4si_0 (amount, CONST0_RTX (V4SImode), + temp)); + } + amount = lowpart_subreg (DImode, amount, GET_MODE (amount)); + emit_insn (gen_ashlv4di3 (ashl_res, zero_or_all_ones, amount)); + emit_insn (gen_iorv4di3 (operands[0], lshr_res, ashl_res)); + DONE; + } +}) + (define_insn "<mask_codefor><insn><mode>3<mask_name>" [(set (match_operand:VI248_AVX512BW_2 0 "register_operand" "=v,v") (any_lshift:VI248_AVX512BW_2 @@ -15939,11 +16062,11 @@ (set_attr "prefix" "orig,maybe_evex,orig,orig,maybe_evex") (set_attr "mode" "TI,TI,V4SF,V2SF,V2SF")]) -(define_insn "*vec_concatv4si_0" - [(set (match_operand:V4SI 0 "register_operand" "=v,x") - (vec_concat:V4SI - (match_operand:V2SI 1 "nonimmediate_operand" "vm,?!*y") - (match_operand:V2SI 2 "const0_operand" " C,C")))] +(define_insn "*vec_concat<mode>_0" + [(set (match_operand:VI124_128 0 "register_operand" "=v,x") + (vec_concat:VI124_128 + (match_operand:<ssehalfvecmode> 1 "nonimmediate_operand" "vm,?!*y") + (match_operand:<ssehalfvecmode> 2 "const0_operand" " C,C")))] "TARGET_SSE2" "@ %vmovq\t{%1, %0|%0, %1} @@ -17734,6 +17857,35 @@ (set_attr "btver2_decode" "vector,vector,vector") (set_attr "mode" "<sseinsnmode>")]) +(define_split + [(set (match_operand:VI1_AVX2 0 "register_operand") + (unspec:VI1_AVX2 + [(match_operand:VI1_AVX2 1 "vector_operand") + (match_operand:VI1_AVX2 2 "register_operand") + (not:VI1_AVX2 (match_operand:VI1_AVX2 3 "register_operand"))] + UNSPEC_BLENDV))] + "TARGET_SSE4_1" + [(set (match_dup 0) + (unspec:VI1_AVX2 + [(match_dup 2) (match_dup 1) (match_dup 3)] + UNSPEC_BLENDV))]) + +(define_split + [(set (match_operand:VI1_AVX2 0 "register_operand") + (unspec:VI1_AVX2 + [(match_operand:VI1_AVX2 1 "vector_operand") + (match_operand:VI1_AVX2 2 "register_operand") + (subreg:VI1_AVX2 (not (match_operand 3 "register_operand")) 0)] + UNSPEC_BLENDV))] + "TARGET_SSE4_1 + && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_VECTOR_INT + && GET_MODE_SIZE (GET_MODE (operands[3])) == <MODE_SIZE>" + [(set (match_dup 0) + (unspec:VI1_AVX2 + [(match_dup 2) (match_dup 1) (match_dup 4)] + UNSPEC_BLENDV))] + "operands[4] = gen_lowpart (<MODE>mode, operands[3]);") + (define_insn_and_split "*<sse4_1_avx2>_pblendvb_lt" [(set (match_operand:VI1_AVX2 0 "register_operand" "=Yr,*x,x") (unspec:VI1_AVX2 @@ -20297,10 +20449,132 @@ (ashiftrt:V2DI (match_operand:V2DI 1 "register_operand") (match_operand:DI 2 "nonmemory_operand")))] - "TARGET_XOP || TARGET_AVX512VL" + "TARGET_SSE2" { if (!TARGET_AVX512VL) { + if (TARGET_SSE4_2 + && CONST_INT_P (operands[2]) + && UINTVAL (operands[2]) >= 63) + { + rtx zero = force_reg (V2DImode, CONST0_RTX (V2DImode)); + emit_insn (gen_sse4_2_gtv2di3 (operands[0], zero, operands[1])); + DONE; + } + if (operands[2] == const0_rtx) + { + emit_move_insn (operands[0], operands[1]); + DONE; + } + if (CONST_INT_P (operands[2]) + && (!TARGET_XOP || UINTVAL (operands[2]) >= 63)) + { + vec_perm_builder sel (4, 4, 1); + sel.quick_grow (4); + rtx arg0, arg1; + rtx op1 = lowpart_subreg (V4SImode, operands[1], V2DImode); + rtx target = gen_reg_rtx (V4SImode); + if (UINTVAL (operands[2]) >= 63) + { + arg0 = arg1 = gen_reg_rtx (V4SImode); + emit_insn (gen_ashrv4si3 (arg0, op1, GEN_INT (31))); + sel[0] = 1; + sel[1] = 1; + sel[2] = 3; + sel[3] = 3; + } + else if (INTVAL (operands[2]) > 32) + { + arg0 = gen_reg_rtx (V4SImode); + arg1 = gen_reg_rtx (V4SImode); + emit_insn (gen_ashrv4si3 (arg1, op1, GEN_INT (31))); + emit_insn (gen_ashrv4si3 (arg0, op1, + GEN_INT (INTVAL (operands[2]) - 32))); + sel[0] = 1; + sel[1] = 5; + sel[2] = 3; + sel[3] = 7; + } + else if (INTVAL (operands[2]) == 32) + { + arg0 = op1; + arg1 = gen_reg_rtx (V4SImode); + emit_insn (gen_ashrv4si3 (arg1, op1, GEN_INT (31))); + sel[0] = 1; + sel[1] = 5; + sel[2] = 3; + sel[3] = 7; + } + else + { + arg0 = gen_reg_rtx (V2DImode); + arg1 = gen_reg_rtx (V4SImode); + emit_insn (gen_lshrv2di3 (arg0, operands[1], operands[2])); + emit_insn (gen_ashrv4si3 (arg1, op1, operands[2])); + arg0 = lowpart_subreg (V4SImode, arg0, V2DImode); + sel[0] = 0; + sel[1] = 5; + sel[2] = 2; + sel[3] = 7; + } + vec_perm_indices indices (sel, arg0 != arg1 ? 2 : 1, 4); + bool ok = targetm.vectorize.vec_perm_const (V4SImode, target, + arg0, arg1, indices); + gcc_assert (ok); + emit_move_insn (operands[0], + lowpart_subreg (V2DImode, target, V4SImode)); + DONE; + } + if (!TARGET_XOP) + { + rtx zero = force_reg (V2DImode, CONST0_RTX (V2DImode)); + rtx zero_or_all_ones; + if (TARGET_SSE4_2) + { + zero_or_all_ones = gen_reg_rtx (V2DImode); + emit_insn (gen_sse4_2_gtv2di3 (zero_or_all_ones, zero, + operands[1])); + } + else + { + rtx temp = gen_reg_rtx (V4SImode); + emit_insn (gen_ashrv4si3 (temp, lowpart_subreg (V4SImode, + operands[1], + V2DImode), + GEN_INT (31))); + zero_or_all_ones = gen_reg_rtx (V4SImode); + emit_insn (gen_sse2_pshufd_1 (zero_or_all_ones, temp, + const1_rtx, const1_rtx, + GEN_INT (3), GEN_INT (3))); + zero_or_all_ones = lowpart_subreg (V2DImode, zero_or_all_ones, + V4SImode); + } + rtx lshr_res = gen_reg_rtx (V2DImode); + emit_insn (gen_lshrv2di3 (lshr_res, operands[1], operands[2])); + rtx ashl_res = gen_reg_rtx (V2DImode); + rtx amount; + if (TARGET_64BIT) + { + amount = gen_reg_rtx (DImode); + emit_insn (gen_subdi3 (amount, force_reg (DImode, GEN_INT (64)), + operands[2])); + } + else + { + rtx temp = gen_reg_rtx (SImode); + emit_insn (gen_subsi3 (temp, force_reg (SImode, GEN_INT (64)), + lowpart_subreg (SImode, operands[2], + DImode))); + amount = gen_reg_rtx (V4SImode); + emit_insn (gen_vec_setv4si_0 (amount, CONST0_RTX (V4SImode), + temp)); + } + amount = lowpart_subreg (DImode, amount, GET_MODE (amount)); + emit_insn (gen_ashlv2di3 (ashl_res, zero_or_all_ones, amount)); + emit_insn (gen_iorv2di3 (operands[0], lshr_res, ashl_res)); + DONE; + } + rtx reg = gen_reg_rtx (V2DImode); rtx par; bool negate = false; @@ -22129,6 +22403,24 @@ (set_attr "prefix" "maybe_evex") (set_attr "mode" "<sseinsnmode>")]) +(define_insn_and_split "*vec_concat<mode>_0_1" + [(set (match_operand:V 0 "register_operand") + (vec_select:V + (vec_concat:<ssedoublevecmode> + (match_operand:V 1 "nonimmediate_operand") + (match_operand:V 2 "const0_operand")) + (match_parallel 3 "movq_parallel" + [(match_operand 4 "const_int_operand")])))] + "ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (match_dup 0) + (vec_concat:V (match_dup 1) (match_dup 5)))] +{ + operands[1] = gen_lowpart (<ssehalfvecmode>mode, operands[1]); + operands[5] = CONST0_RTX (<ssehalfvecmode>mode); +}) + (define_insn "vcvtph2ps<mask_name>" [(set (match_operand:V4SF 0 "register_operand" "=v") (vec_select:V4SF diff --git a/gcc/config/nvptx/nvptx-opts.h b/gcc/config/nvptx/nvptx-opts.h index ce88245..bfa926e 100644 --- a/gcc/config/nvptx/nvptx-opts.h +++ b/gcc/config/nvptx/nvptx-opts.h @@ -26,5 +26,11 @@ enum ptx_isa PTX_ISA_SM35 }; +enum ptx_version +{ + PTX_VERSION_3_1, + PTX_VERSION_6_3 +}; + #endif diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c index 7a7a913..ebbfa92 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -5309,7 +5309,10 @@ static void nvptx_file_start (void) { fputs ("// BEGIN PREAMBLE\n", asm_out_file); - fputs ("\t.version\t3.1\n", asm_out_file); + if (TARGET_PTX_6_3) + fputs ("\t.version\t6.3\n", asm_out_file); + else + fputs ("\t.version\t3.1\n", asm_out_file); if (TARGET_SM35) fputs ("\t.target\tsm_35\n", asm_out_file); else diff --git a/gcc/config/nvptx/nvptx.h b/gcc/config/nvptx/nvptx.h index 2451703..fdaacdd 100644 --- a/gcc/config/nvptx/nvptx.h +++ b/gcc/config/nvptx/nvptx.h @@ -98,6 +98,8 @@ #define TARGET_SM35 (ptx_isa_option >= PTX_ISA_SM35) +#define TARGET_PTX_6_3 (ptx_version_option >= PTX_VERSION_6_3) + /* Registers. Since ptx is a virtual target, we just define a few hard registers for special purposes and leave pseudos unallocated. We have to have some available hard registers, to keep gcc setup diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md index 0f15609..00bb8fe 100644 --- a/gcc/config/nvptx/nvptx.md +++ b/gcc/config/nvptx/nvptx.md @@ -1452,14 +1452,24 @@ (match_operand:SI 3 "const_int_operand" "n")] UNSPEC_SHUFFLE))] "" - "%.\\tshfl%S3.b32\\t%0, %1, %2, 31;") + { + if (TARGET_PTX_6_3) + return "%.\\tshfl.sync%S3.b32\\t%0, %1, %2, 31, 0xffffffff;"; + else + return "%.\\tshfl%S3.b32\\t%0, %1, %2, 31;"; + }) (define_insn "nvptx_vote_ballot" [(set (match_operand:SI 0 "nvptx_register_operand" "=R") (unspec:SI [(match_operand:BI 1 "nvptx_register_operand" "R")] UNSPEC_VOTE_BALLOT))] "" - "%.\\tvote.ballot.b32\\t%0, %1;") + { + if (TARGET_PTX_6_3) + return "%.\\tvote.sync.ballot.b32\\t%0, %1, 0xffffffff;"; + else + return "%.\\tvote.ballot.b32\\t%0, %1;"; + }) ;; Patterns for OpenMP SIMD-via-SIMT lowering diff --git a/gcc/config/nvptx/nvptx.opt b/gcc/config/nvptx/nvptx.opt index 51363e4..468c6ca 100644 --- a/gcc/config/nvptx/nvptx.opt +++ b/gcc/config/nvptx/nvptx.opt @@ -65,3 +65,17 @@ Enum(ptx_isa) String(sm_35) Value(PTX_ISA_SM35) misa= Target RejectNegative ToLower Joined Enum(ptx_isa) Var(ptx_isa_option) Init(PTX_ISA_SM35) Specify the version of the ptx ISA to use. + +Enum +Name(ptx_version) Type(int) +Known PTX versions (for use with the -mptx= option): + +EnumValue +Enum(ptx_version) String(3.1) Value(PTX_VERSION_3_1) + +EnumValue +Enum(ptx_version) String(6.3) Value(PTX_VERSION_6_3) + +mptx= +Target RejectNegative ToLower Joined Enum(ptx_version) Var(ptx_version_option) Init(PTX_VERSION_3_1) +Specify the version of the ptx version to use. diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index 0f8a629..afcb5bb 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -602,6 +602,9 @@ rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags, /* Whether pc-relative code is being generated. */ if ((flags & OPTION_MASK_PCREL) != 0) rs6000_define_or_undefine_macro (define_p, "__PCREL__"); + /* Tell the user -mrop-protect is in play. */ + if (rs6000_rop_protect) + rs6000_define_or_undefine_macro (define_p, "__ROP_PROTECT__"); } void diff --git a/gcc/config/rs6000/rs6000-internal.h b/gcc/config/rs6000/rs6000-internal.h index 428a786..88cf9bd 100644 --- a/gcc/config/rs6000/rs6000-internal.h +++ b/gcc/config/rs6000/rs6000-internal.h @@ -39,6 +39,7 @@ typedef struct rs6000_stack { int gp_save_offset; /* offset to save GP regs from initial SP */ int fp_save_offset; /* offset to save FP regs from initial SP */ int altivec_save_offset; /* offset to save AltiVec regs from initial SP */ + int rop_hash_save_offset; /* offset to save ROP hash from initial SP */ int lr_save_offset; /* offset to save LR from initial SP */ int cr_save_offset; /* offset to save CR from initial SP */ int vrsave_save_offset; /* offset to save VRSAVE from initial SP */ @@ -53,6 +54,7 @@ typedef struct rs6000_stack { int gp_size; /* size of saved GP registers */ int fp_size; /* size of saved FP registers */ int altivec_size; /* size of saved AltiVec registers */ + int rop_hash_size; /* size of ROP hash slot */ int cr_size; /* size to hold CR if not in fixed area */ int vrsave_size; /* size to hold VRSAVE */ int altivec_padding_size; /* size of altivec alignment padding */ diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c index b0ac183..13c00e7 100644 --- a/gcc/config/rs6000/rs6000-logue.c +++ b/gcc/config/rs6000/rs6000-logue.c @@ -595,19 +595,21 @@ rs6000_savres_strategy (rs6000_stack_t *info, +---------------------------------------+ | Parameter save area (+padding*) (P) | 32 +---------------------------------------+ - | Alloca space (A) | 32+P + | Optional ROP hash slot (R) | 32+P +---------------------------------------+ - | Local variable space (L) | 32+P+A + | Alloca space (A) | 32+P+R +---------------------------------------+ - | Save area for AltiVec registers (W) | 32+P+A+L + | Local variable space (L) | 32+P+R+A +---------------------------------------+ - | AltiVec alignment padding (Y) | 32+P+A+L+W + | Save area for AltiVec registers (W) | 32+P+R+A+L +---------------------------------------+ - | Save area for GP registers (G) | 32+P+A+L+W+Y + | AltiVec alignment padding (Y) | 32+P+R+A+L+W +---------------------------------------+ - | Save area for FP registers (F) | 32+P+A+L+W+Y+G + | Save area for GP registers (G) | 32+P+R+A+L+W+Y +---------------------------------------+ - old SP->| back chain to caller's caller | 32+P+A+L+W+Y+G+F + | Save area for FP registers (F) | 32+P+R+A+L+W+Y+G + +---------------------------------------+ + old SP->| back chain to caller's caller | 32+P+R+A+L+W+Y+G+F +---------------------------------------+ * If the alloca area is present, the parameter save area is @@ -716,6 +718,19 @@ rs6000_stack_info (void) /* Does this function call anything (apart from sibling calls)? */ info->calls_p = (!crtl->is_leaf || cfun->machine->ra_needs_full_frame); + info->rop_hash_size = 0; + + if (TARGET_POWER10 + && info->calls_p + && DEFAULT_ABI == ABI_ELFv2 + && rs6000_rop_protect) + info->rop_hash_size = 8; + else if (rs6000_rop_protect && DEFAULT_ABI != ABI_ELFv2) + { + /* We can't check this in rs6000_option_override_internal since + DEFAULT_ABI isn't established yet. */ + error ("%qs requires the ELFv2 ABI", "-mrop-protect"); + } /* Determine if we need to save the condition code registers. */ if (save_reg_p (CR2_REGNO) @@ -808,6 +823,11 @@ rs6000_stack_info (void) /* Adjust for AltiVec case. */ info->ehrd_offset = info->altivec_save_offset - ehrd_size; + + /* Adjust for ROP protection. */ + info->rop_hash_save_offset + = info->altivec_save_offset - info->rop_hash_size; + info->ehrd_offset -= info->rop_hash_size; } else info->ehrd_offset = info->gp_save_offset - ehrd_size; @@ -849,6 +869,7 @@ rs6000_stack_info (void) + info->gp_size + info->altivec_size + info->altivec_padding_size + + info->rop_hash_size + ehrd_size + ehcr_size + info->cr_size @@ -987,6 +1008,10 @@ debug_stack_info (rs6000_stack_t *info) fprintf (stderr, "\tvrsave_save_offset = %5d\n", info->vrsave_save_offset); + if (info->rop_hash_size) + fprintf (stderr, "\trop_hash_save_offset = %5d\n", + info->rop_hash_save_offset); + if (info->lr_save_p) fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset); @@ -1026,6 +1051,9 @@ debug_stack_info (rs6000_stack_t *info) fprintf (stderr, "\taltivec_padding_size= %5d\n", info->altivec_padding_size); + if (info->rop_hash_size) + fprintf (stderr, "\trop_hash_size = %5d\n", info->rop_hash_size); + if (info->cr_size) fprintf (stderr, "\tcr_size = %5d\n", info->cr_size); @@ -3252,6 +3280,22 @@ rs6000_emit_prologue (void) } } + /* The ROP hash store must occur before a stack frame is created, + since the hash operates on r1. */ + /* NOTE: The hashst isn't needed if we're going to do a sibcall, + but there's no way to know that here. Harmless except for + performance, of course. */ + if (TARGET_POWER10 && rs6000_rop_protect && info->rop_hash_size != 0) + { + gcc_assert (DEFAULT_ABI == ABI_ELFv2); + rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); + rtx addr = gen_rtx_PLUS (Pmode, stack_ptr, + GEN_INT (info->rop_hash_save_offset)); + rtx mem = gen_rtx_MEM (Pmode, addr); + rtx reg0 = gen_rtx_REG (Pmode, 0); + emit_insn (gen_hashst (mem, reg0)); + } + /* If we need to save CR, put it into r12 or r11. Choose r12 except when r12 will be needed by out-of-line gpr save. */ cr_save_regno = ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) @@ -4980,6 +5024,22 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa)); } + /* The ROP hash check must occur after the stack pointer is restored + (since the hash involves r1), and is not performed for a sibcall. */ + if (TARGET_POWER10 + && rs6000_rop_protect + && info->rop_hash_size != 0 + && epilogue_type != EPILOGUE_TYPE_SIBCALL) + { + gcc_assert (DEFAULT_ABI == ABI_ELFv2); + rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); + rtx addr = gen_rtx_PLUS (Pmode, stack_ptr, + GEN_INT (info->rop_hash_save_offset)); + rtx mem = gen_rtx_MEM (Pmode, addr); + rtx reg0 = gen_rtx_REG (Pmode, 0); + emit_insn (gen_hashchk (reg0, mem)); + } + if (epilogue_type != EPILOGUE_TYPE_SIBCALL && restoring_FPRs_inline) { if (cfa_restores) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d1b76f6..53a9f54 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -4040,6 +4040,10 @@ rs6000_option_override_internal (bool global_init_p) && ((rs6000_isa_flags_explicit & OPTION_MASK_QUAD_MEMORY_ATOMIC) == 0)) rs6000_isa_flags |= OPTION_MASK_QUAD_MEMORY_ATOMIC; + /* If we are inserting ROP-protect instructions, disable shrink wrap. */ + if (rs6000_rop_protect) + flag_shrink_wrap = 0; + /* If we can shrink-wrap the TOC register save separately, then use -msave-toc-indirect unless explicitly disabled. */ if ((rs6000_isa_flags_explicit & OPTION_MASK_SAVE_TOC_INDIRECT) == 0 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index c8cdc42..0bfeb24 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -154,6 +154,8 @@ UNSPEC_CNTTZDM UNSPEC_PDEPD UNSPEC_PEXTD + UNSPEC_HASHST + UNSPEC_HASHCHK ]) ;; @@ -14948,6 +14950,35 @@ "TARGET_P9_MISC && TARGET_64BIT" "cmpeqb %0,%1,%2" [(set_attr "type" "logical")]) + + +;; ROP mitigation instructions. + +(define_insn "hashst" + [(set (match_operand:DI 0 "simple_offsettable_mem_operand" "=m") + (unspec_volatile:DI [(match_operand:DI 1 "int_reg_operand" "r")] + UNSPEC_HASHST))] + "TARGET_POWER10 && rs6000_rop_protect" +{ + static char templ[32]; + const char *p = rs6000_privileged ? "p" : ""; + sprintf (templ, "hashst%s %%1,%%0", p); + return templ; +} + [(set_attr "type" "store")]) + +(define_insn "hashchk" + [(unspec_volatile [(match_operand:DI 0 "int_reg_operand" "r") + (match_operand:DI 1 "simple_offsettable_mem_operand" "m")] + UNSPEC_HASHCHK)] + "TARGET_POWER10 && rs6000_rop_protect" +{ + static char templ[32]; + const char *p = rs6000_privileged ? "p" : ""; + sprintf (templ, "hashchk%s %%0,%%1", p); + return templ; +} + [(set_attr "type" "load")]) (include "sync.md") diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 0dbdf75..2685fa7 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -619,3 +619,11 @@ Generate (do not generate) MMA instructions. mrelative-jumptables Target Undocumented Var(rs6000_relative_jumptables) Init(1) Save + +mrop-protect +Target Var(rs6000_rop_protect) Init(0) +Enable instructions that guard against return-oriented programming attacks. + +mprivileged +Target Var(rs6000_privileged) Init(0) +Generate code that will run in privileged state. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 122808e..48425b9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,61 @@ +2021-05-14 Jason Merrill <jason@redhat.com> + + PR c++/95870 + * pt.c (enclosing_instantiation_of): Just compare + DECL_SOURCE_LOCATION. + (regenerate_decl_from_template): Copy DECL_SOURCE_LOCATION. + +2021-05-14 Marek Polacek <polacek@redhat.com> + Jason Merrill <jason@redhat.com> + + PR c++/99032 + * cp-tree.h (any_non_type_attribute_p): Declare. + * decl.c (grokdeclarator): Diagnose when an attribute appertains to + a friend declaration that is not a definition. + * decl2.c (any_non_type_attribute_p): New. + * parser.c (cp_parser_decl_specifier_seq): Diagnose standard attributes + in the middle of decl-specifiers. + (cp_parser_elaborated_type_specifier): Diagnose when an attribute + appertains to a friend declaration that is not a definition. + (cp_parser_member_declaration): Likewise. + +2021-05-12 Marek Polacek <polacek@redhat.com> + + * pt.c (tsubst_copy_and_build): Add warn_int_in_bool_context + sentinel. + +2021-05-12 Marcel Vollweiler <marcel@codesourcery.com> + + * parser.c (cp_parser_omp_clause_map): Support map-type-modifier + 'close'. + +2021-05-11 Jason Merrill <jason@redhat.com> + + PR c++/100517 + * typeck.c (build_reinterpret_cast_1): Check intype on + cast to vector. + +2021-05-11 Patrick Palka <ppalka@redhat.com> + + PR c++/51577 + * name-lookup.c (maybe_save_operator_binding): Unconditionally + enable for all function templates, not just generic lambdas. + Handle compound-assignment operator expressions. + * typeck.c (build_x_compound_expr): Call maybe_save_operator_binding + in the type-dependent case. + (build_x_modify_expr): Likewise. Move declaration of 'op' closer + to its first use. + +2021-05-11 Patrick Palka <ppalka@redhat.com> + + PR c++/100138 + * constraint.cc (tsubst_constraint): Set up cp_unevaluated. + (satisfy_atom): Set up iloc_sentinel before calling + cxx_constant_value. + * pt.c (tsubst_pack_expansion): When returning a rebuilt pack + expansion, carry over PACK_EXPANSION_LOCAL_P and + PACK_EXPANSION_SIZEOF_P from the original pack expansion. + 2021-05-10 Richard Biener <rguenther@suse.de> PR middle-end/100464 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 122dadf..580db91 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6763,6 +6763,7 @@ extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *, tree, tree, tree); extern tree splice_template_attributes (tree *, tree); extern bool any_dependent_type_attributes_p (tree); +extern bool any_non_type_attribute_p (tree); extern tree cp_reconstruct_complex_type (tree, tree); extern bool attributes_naming_typedef_ok (tree); extern void cplus_decl_attributes (tree *, tree, int); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index bc3928d..17511f0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13741,6 +13741,11 @@ grokdeclarator (const cp_declarator *declarator, if (friendp) { + if (attrlist && !funcdef_flag + /* Hack to allow attributes like vector_size on a friend. */ + && any_non_type_attribute_p (*attrlist)) + error_at (id_loc, "attribute appertains to a friend " + "declaration that is not a definition"); /* Friends are treated specially. */ if (ctype == current_class_type) ; /* We already issued a permerror. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 89f874a..8e4dd6b 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1331,6 +1331,20 @@ any_dependent_type_attributes_p (tree attrs) return false; } +/* True if ATTRS contains any attribute that does not require a type. */ + +bool +any_non_type_attribute_p (tree attrs) +{ + for (tree a = attrs; a; a = TREE_CHAIN (a)) + { + const attribute_spec *as = lookup_attribute_spec (get_attribute_name (a)); + if (as && !as->type_required) + return true; + } + return false; +} + /* Return true iff ATTRS are acceptable attributes to be applied in-place to a typedef which gives a previously unnamed class or enum a name for linkage purposes. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0fe29c6..c0b5795 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -15146,6 +15146,16 @@ cp_parser_decl_specifier_seq (cp_parser* parser, if (!found_decl_spec) break; + if (decl_specs->std_attributes) + { + error_at (decl_specs->locations[ds_std_attribute], + "standard attributes in middle of decl-specifiers"); + inform (decl_specs->locations[ds_std_attribute], + "standard attributes must precede the decl-specifiers to " + "apply to the declaration, or follow them to apply to " + "the type"); + } + decl_specs->any_specifiers_p = true; /* After we see one decl-specifier, further decl-specifiers are always optional. */ @@ -19764,11 +19774,15 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, && ! processing_explicit_instantiation) warning (OPT_Wattributes, "attributes ignored on template instantiation"); + else if (is_friend && attributes) + error ("attribute appertains to a friend declaration that is not " + "a definition"); else if (is_declaration && cp_parser_declares_only_class_p (parser)) cplus_decl_attributes (&type, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE); else warning (OPT_Wattributes, - "attributes ignored on elaborated-type-specifier that is not a forward declaration"); + "attributes ignored on elaborated-type-specifier that is " + "not a forward declaration"); } if (tag_type == enum_type) @@ -26054,6 +26068,13 @@ cp_parser_member_declaration (cp_parser* parser) error_at (decl_spec_token_start->location, "friend declaration does not name a class or " "function"); + /* Give an error if an attribute cannot appear here, as per + [dcl.attr.grammar]/5. But not when declares_class_or_enum: + we ignore attributes in elaborated-type-specifiers. */ + else if (!declares_class_or_enum && decl_specifiers.attributes) + error_at (decl_spec_token_start->location, + "attribute appertains to a friend declaration " + "that is not a definition"); else make_friend_class (current_class_type, type, /*complain=*/true); @@ -37859,40 +37880,90 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc) map-kind: alloc | to | from | tofrom | release | delete - map ( always [,] map-kind: variable-list ) */ + map ( always [,] map-kind: variable-list ) + + OpenMP 5.0: + map ( [map-type-modifier[,] ...] map-kind: variable-list ) + + map-type-modifier: + always | close */ static tree cp_parser_omp_clause_map (cp_parser *parser, tree list) { tree nlist, c; enum gomp_map_kind kind = GOMP_MAP_TOFROM; - bool always = false; if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return list; - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + int pos = 1; + int map_kind_pos = 0; + while (cp_lexer_peek_nth_token (parser->lexer, pos)->type == CPP_NAME + || cp_lexer_peek_nth_token (parser->lexer, pos)->keyword == RID_DELETE) { - tree id = cp_lexer_peek_token (parser->lexer)->u.value; - const char *p = IDENTIFIER_POINTER (id); + if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_COLON) + { + map_kind_pos = pos; + break; + } + + if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_COMMA) + pos++; + pos++; + } + bool always_modifier = false; + bool close_modifier = false; + for (int pos = 1; pos < map_kind_pos; ++pos) + { + cp_token *tok = cp_lexer_peek_token (parser->lexer); + if (tok->type == CPP_COMMA) + { + cp_lexer_consume_token (parser->lexer); + continue; + } + + const char *p = IDENTIFIER_POINTER (tok->u.value); if (strcmp ("always", p) == 0) { - int nth = 2; - if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COMMA) - nth++; - if ((cp_lexer_peek_nth_token (parser->lexer, nth)->type == CPP_NAME - || (cp_lexer_peek_nth_token (parser->lexer, nth)->keyword - == RID_DELETE)) - && (cp_lexer_peek_nth_token (parser->lexer, nth + 1)->type - == CPP_COLON)) + if (always_modifier) { - always = true; - cp_lexer_consume_token (parser->lexer); - if (nth == 3) - cp_lexer_consume_token (parser->lexer); + cp_parser_error (parser, "too many %<always%> modifiers"); + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; } + always_modifier = true; } + else if (strcmp ("close", p) == 0) + { + if (close_modifier) + { + cp_parser_error (parser, "too many %<close%> modifiers"); + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; + } + close_modifier = true; + } + else + { + cp_parser_error (parser, "%<#pragma omp target%> with " + "modifier other than %<always%> or %<close%>" + "on %<map%> clause"); + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; + } + + cp_lexer_consume_token (parser->lexer); } if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) @@ -37904,11 +37975,11 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list) if (strcmp ("alloc", p) == 0) kind = GOMP_MAP_ALLOC; else if (strcmp ("to", p) == 0) - kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO; + kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO; else if (strcmp ("from", p) == 0) - kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM; + kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM; else if (strcmp ("tofrom", p) == 0) - kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM; + kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM; else if (strcmp ("release", p) == 0) kind = GOMP_MAP_RELEASE; else diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 85c05af..bf99635 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14437,55 +14437,22 @@ most_general_lambda (tree t) } /* We're instantiating a variable from template function TCTX. Return the - corresponding current enclosing scope. This gets complicated because lambda - functions in templates are regenerated rather than instantiated, but generic - lambda functions are subsequently instantiated. */ + corresponding current enclosing scope. We can match them up using + DECL_SOURCE_LOCATION because lambdas only ever have one source location, and + the DECL_SOURCE_LOCATION for a function instantiation is updated to match + the template definition in regenerate_decl_from_template. */ static tree -enclosing_instantiation_of (tree otctx) +enclosing_instantiation_of (tree tctx) { - tree tctx = otctx; tree fn = current_function_decl; - int lambda_count = 0; - for (; tctx && (lambda_fn_in_template_p (tctx) - || regenerated_lambda_fn_p (tctx)); - tctx = decl_function_context (tctx)) - ++lambda_count; - - if (!tctx) - { - /* Match using DECL_SOURCE_LOCATION, which is unique for all lambdas. - - For GCC 11 the above condition limits this to the previously failing - case where all enclosing functions are lambdas (95870). FIXME. */ - for (tree ofn = fn; ofn; ofn = decl_function_context (ofn)) - if (DECL_SOURCE_LOCATION (ofn) == DECL_SOURCE_LOCATION (otctx)) - return ofn; - gcc_unreachable (); - } + /* We shouldn't ever need to do this for other artificial functions. */ + gcc_assert (!DECL_ARTIFICIAL (tctx) || LAMBDA_FUNCTION_P (tctx)); for (; fn; fn = decl_function_context (fn)) - { - tree ofn = fn; - int flambda_count = 0; - for (; fn && regenerated_lambda_fn_p (fn); - fn = decl_function_context (fn)) - ++flambda_count; - if ((fn && DECL_TEMPLATE_INFO (fn)) - ? most_general_template (fn) != most_general_template (tctx) - : fn != tctx) - continue; - if (flambda_count != lambda_count) - { - gcc_assert (flambda_count > lambda_count); - for (; flambda_count > lambda_count; --flambda_count) - ofn = decl_function_context (ofn); - } - gcc_assert (DECL_NAME (ofn) == DECL_NAME (otctx) - || DECL_CONV_FN_P (ofn)); - return ofn; - } + if (DECL_SOURCE_LOCATION (fn) == DECL_SOURCE_LOCATION (tctx)) + return fn; gcc_unreachable (); } @@ -19801,6 +19768,7 @@ tsubst_copy_and_build (tree t, warning_sentinel s(warn_useless_cast); warning_sentinel s2(warn_ignored_qualifiers); + warning_sentinel s3(warn_int_in_bool_context); switch (TREE_CODE (t)) { case CAST_EXPR: @@ -25491,6 +25459,9 @@ regenerate_decl_from_template (tree decl, tree tmpl, tree args) int args_depth; int parms_depth; + /* Use the source location of the definition. */ + DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (tmpl); + args_depth = TMPL_ARGS_DEPTH (args); parms_depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)); if (args_depth > parms_depth) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 852617d..dc0bde8 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1240,7 +1240,8 @@ See RS/6000 and PowerPC Options. -mgnu-attribute -mno-gnu-attribute @gol -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol -mstack-protector-guard-offset=@var{offset} -mprefixed -mno-prefixed @gol --mpcrel -mno-pcrel -mmma -mno-mmma} +-mpcrel -mno-pcrel -mmma -mno-mmma -mrop-protect -mno-rop-protect @gol +-mprivileged -mno-privileged} @emph{RX Options} @gccoptlist{-m64bit-doubles -m32bit-doubles -fpu -nofpu@gol @@ -26284,6 +26285,12 @@ Generate code for given the specified PTX ISA (e.g.@: @samp{sm_35}). ISA strings must be lower-case. Valid ISA strings include @samp{sm_30} and @samp{sm_35}. The default ISA is sm_35. +@item -mptx=@var{version-string} +@opindex mptx +Generate code for given the specified PTX version (e.g.@: @samp{6.3}). +Valid version strings include @samp{3.1} and @samp{6.3}. The default PTX +version is 3.1. + @item -mmainkernel @opindex mmainkernel Link in code for a __main kernel. This is for stand-alone instead of @@ -27023,7 +27030,8 @@ following options: -mmulhw -mdlmzb -mmfpgpr -mvsx @gol -mcrypto -mhtm -mpower8-fusion -mpower8-vector @gol -mquad-memory -mquad-memory-atomic -mfloat128 @gol --mfloat128-hardware -mprefixed -mpcrel -mmma} +-mfloat128-hardware -mprefixed -mpcrel -mmma @gol +-mrop-protect} The particular options set for any particular CPU varies between compiler versions, depending on what setting seems to produce optimal @@ -28028,6 +28036,20 @@ store instructions when the option @option{-mcpu=future} is used. Generate (do not generate) the MMA instructions when the option @option{-mcpu=future} is used. +@item -mrop-protect +@itemx -mno-rop-protect +@opindex mrop-protect +@opindex mno-rop-protect +Generate (do not generate) ROP protection instructions when the target +processor supports them. Currently this option disables the shrink-wrap +optimization (@option{-fshrink-wrap}). + +@item -mprivileged +@itemx -mno-privileged +@opindex mprivileged +@opindex mno-privileged +Generate (do not generate) code that will run in privileged state. + @item -mblock-ops-unaligned-vsx @itemx -mno-block-ops-unaligned-vsx @opindex block-ops-unaligned-vsx diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 3a1d653..ceb6b99 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2125,9 +2125,9 @@ ARM Target supports options suitable for accessing the SIMD32 intrinsics from @code{arm_acle.h}. Some multilibs may be incompatible with these options. -@item arm_qbit_ok -@anchor{arm_qbit_ok} -ARM Target supports options suitable for accessing the Q-bit manipulation +@item arm_sat_ok +@anchor{arm_sat_ok} +ARM Target supports options suitable for accessing the saturation intrinsics from @code{arm_acle.h}. Some multilibs may be incompatible with these options. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 8fc8298..b99598e 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -31956,6 +31956,7 @@ dwarf2out_finish (const char *filename) add_AT_addr (main_comp_unit_die, DW_AT_entry_pc, const0_rtx, true); add_ranges (NULL); + have_multiple_function_sections = true; } } @@ -10949,61 +10949,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, goto normal_inner_ref; case COMPONENT_REF: - /* If the operand is a CONSTRUCTOR, we can just extract the - appropriate field if it is present. */ - if (TREE_CODE (treeop0) == CONSTRUCTOR) - { - unsigned HOST_WIDE_INT idx; - tree field, value; - scalar_int_mode field_mode; - - FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (treeop0), - idx, field, value) - if (field == treeop1 - /* We can normally use the value of the field in the - CONSTRUCTOR. However, if this is a bitfield in - an integral mode that we can fit in a HOST_WIDE_INT, - we must mask only the number of bits in the bitfield, - since this is done implicitly by the constructor. If - the bitfield does not meet either of those conditions, - we can't do this optimization. */ - && (! DECL_BIT_FIELD (field) - || (is_int_mode (DECL_MODE (field), &field_mode) - && (GET_MODE_PRECISION (field_mode) - <= HOST_BITS_PER_WIDE_INT)))) - { - if (DECL_BIT_FIELD (field) - && modifier == EXPAND_STACK_PARM) - target = 0; - op0 = expand_expr (value, target, tmode, modifier); - if (DECL_BIT_FIELD (field)) - { - HOST_WIDE_INT bitsize = TREE_INT_CST_LOW (DECL_SIZE (field)); - scalar_int_mode imode - = SCALAR_INT_TYPE_MODE (TREE_TYPE (field)); - - if (TYPE_UNSIGNED (TREE_TYPE (field))) - { - op1 = gen_int_mode ((HOST_WIDE_INT_1 << bitsize) - 1, - imode); - op0 = expand_and (imode, op0, op1, target); - } - else - { - int count = GET_MODE_PRECISION (imode) - bitsize; - - op0 = expand_shift (LSHIFT_EXPR, imode, op0, count, - target, 0); - op0 = expand_shift (RSHIFT_EXPR, imode, op0, count, - target, 0); - } - } - - return op0; - } - } - goto normal_inner_ref; - + gcc_assert (TREE_CODE (treeop0) != CONSTRUCTOR); + /* Fall through. */ case BIT_FIELD_REF: case ARRAY_RANGE_REF: normal_inner_ref: diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 71cc3d8..781dedd 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,28 @@ +2021-05-14 Tobias Burnus <tobias@codesourcery.com> + + * dump-parse-tree.c (show_omp_node, show_code_node): Handle + EXEC_OMP_PARALLEL_MASTER. + * frontend-passes.c (gfc_code_walker): Likewise. + * gfortran.h (enum gfc_statement): Add ST_OMP_PARALLEL_MASTER and + ST_OMP_END_PARALLEL_MASTER. + (enum gfc_exec_op): Add EXEC_OMP_PARALLEL_MASTER.. + * match.h (gfc_match_omp_parallel_master): Handle it. + * openmp.c (gfc_match_omp_parallel_master, resolve_omp_clauses, + omp_code_to_statement, gfc_resolve_omp_directive): Likewise. + * parse.c (decode_omp_directive, case_exec_markers, + gfc_ascii_statement, parse_omp_structured_block, + parse_executable): Likewise. + * resolve.c (gfc_resolve_blocks, gfc_resolve_code): Likewise. + * st.c (gfc_free_statement): Likewise. + * trans-openmp.c (gfc_trans_omp_parallel_master, + gfc_trans_omp_workshare, gfc_trans_omp_directive): Likewise. + * trans.c (trans_code): Likewise. + +2021-05-14 Tobias Burnus <tobias@codesourcery.com> + + * resolve.c (resolve_symbol): Handle implicit SAVE of main-program + for vars in 'omp threadprivate' and 'omp declare target'. + 2021-05-10 Martin Liska <mliska@suse.cz> * decl.c (variable_decl): Use startswith diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index b50265a..874e6d4 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -1856,6 +1856,7 @@ show_omp_node (int level, gfc_code *c) case EXEC_OMP_PARALLEL: name = "PARALLEL"; break; case EXEC_OMP_PARALLEL_DO: name = "PARALLEL DO"; break; case EXEC_OMP_PARALLEL_DO_SIMD: name = "PARALLEL DO SIMD"; break; + case EXEC_OMP_PARALLEL_MASTER: name = "PARALLEL MASTER"; break; case EXEC_OMP_PARALLEL_SECTIONS: name = "PARALLEL SECTIONS"; break; case EXEC_OMP_PARALLEL_WORKSHARE: name = "PARALLEL WORKSHARE"; break; case EXEC_OMP_SCAN: name = "SCAN"; break; @@ -1927,6 +1928,7 @@ show_omp_node (int level, gfc_code *c) case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SCAN: @@ -3139,6 +3141,7 @@ show_code_node (int level, gfc_code *c) case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SCAN: diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 93ac4b4..ffe2db4 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -5542,6 +5542,7 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn, case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: in_omp_workshare = false; diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 4f5d2f8..bab785b 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -266,7 +266,8 @@ enum gfc_statement ST_OMP_REQUIRES, ST_PROCEDURE, ST_GENERIC, ST_CRITICAL, ST_END_CRITICAL, ST_GET_FCN_CHARACTERISTICS, ST_LOCK, ST_UNLOCK, ST_EVENT_POST, ST_EVENT_WAIT, ST_FAIL_IMAGE, ST_FORM_TEAM, ST_CHANGE_TEAM, - ST_END_TEAM, ST_SYNC_TEAM, ST_NONE + ST_END_TEAM, ST_SYNC_TEAM, ST_OMP_PARALLEL_MASTER, + ST_OMP_END_PARALLEL_MASTER, ST_NONE }; /* Types of interfaces that we can have. Assignment interfaces are @@ -2704,7 +2705,8 @@ enum gfc_exec_op EXEC_OMP_TARGET_ENTER_DATA, EXEC_OMP_TARGET_EXIT_DATA, EXEC_OMP_TARGET_PARALLEL, EXEC_OMP_TARGET_PARALLEL_DO, EXEC_OMP_TARGET_PARALLEL_DO_SIMD, EXEC_OMP_TARGET_SIMD, - EXEC_OMP_TASKLOOP, EXEC_OMP_TASKLOOP_SIMD, EXEC_OMP_SCAN, EXEC_OMP_DEPOBJ + EXEC_OMP_TASKLOOP, EXEC_OMP_TASKLOOP_SIMD, EXEC_OMP_SCAN, EXEC_OMP_DEPOBJ, + EXEC_OMP_PARALLEL_MASTER }; typedef struct gfc_code diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h index b72ec67..09c5723 100644 --- a/gcc/fortran/match.h +++ b/gcc/fortran/match.h @@ -174,6 +174,7 @@ match gfc_match_omp_ordered_depend (void); match gfc_match_omp_parallel (void); match gfc_match_omp_parallel_do (void); match gfc_match_omp_parallel_do_simd (void); +match gfc_match_omp_parallel_master (void); match gfc_match_omp_parallel_sections (void); match gfc_match_omp_parallel_workshare (void); match gfc_match_omp_requires (void); diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 7eeabff..294b6d0 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -3770,6 +3770,13 @@ gfc_match_omp_parallel_do_simd (void) match +gfc_match_omp_parallel_master (void) +{ + return match_omp (EXEC_OMP_PARALLEL_MASTER, OMP_PARALLEL_CLAUSES); +} + + +match gfc_match_omp_parallel_sections (void) { return match_omp (EXEC_OMP_PARALLEL_SECTIONS, @@ -4833,6 +4840,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_DISTRIBUTE_PARALLEL_DO: @@ -6796,6 +6804,8 @@ omp_code_to_statement (gfc_code *code) { case EXEC_OMP_PARALLEL: return ST_OMP_PARALLEL; + case EXEC_OMP_PARALLEL_MASTER: + return ST_OMP_PARALLEL_MASTER; case EXEC_OMP_PARALLEL_SECTIONS: return ST_OMP_PARALLEL_SECTIONS; case EXEC_OMP_SECTIONS: @@ -7312,6 +7322,7 @@ gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns) case EXEC_OMP_CANCEL: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_PARALLEL: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_SECTIONS: case EXEC_OMP_SINGLE: diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 9bbe9e8..6efb3fd 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -925,6 +925,8 @@ decode_omp_directive (void) matchs ("end parallel do simd", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_DO_SIMD); matcho ("end parallel do", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_DO); + matcho ("end parallel master", gfc_match_omp_eos_error, + ST_OMP_END_PARALLEL_MASTER); matcho ("end parallel sections", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_SECTIONS); matcho ("end parallel workshare", gfc_match_omp_eos_error, @@ -990,6 +992,8 @@ decode_omp_directive (void) matchs ("parallel do simd", gfc_match_omp_parallel_do_simd, ST_OMP_PARALLEL_DO_SIMD); matcho ("parallel do", gfc_match_omp_parallel_do, ST_OMP_PARALLEL_DO); + matcho ("parallel master", gfc_match_omp_parallel_master, + ST_OMP_PARALLEL_MASTER); matcho ("parallel sections", gfc_match_omp_parallel_sections, ST_OMP_PARALLEL_SECTIONS); matcho ("parallel workshare", gfc_match_omp_parallel_workshare, @@ -1605,7 +1609,7 @@ next_statement (void) #define case_exec_markers case ST_DO: case ST_FORALL_BLOCK: \ case ST_IF_BLOCK: case ST_BLOCK: case ST_ASSOCIATE: \ case ST_WHERE_BLOCK: case ST_SELECT_CASE: case ST_SELECT_TYPE: \ - case ST_SELECT_RANK: case ST_OMP_PARALLEL: \ + case ST_SELECT_RANK: case ST_OMP_PARALLEL: case ST_OMP_PARALLEL_MASTER: \ case ST_OMP_PARALLEL_SECTIONS: case ST_OMP_SECTIONS: case ST_OMP_ORDERED: \ case ST_OMP_CRITICAL: case ST_OMP_MASTER: case ST_OMP_SINGLE: \ case ST_OMP_DO: case ST_OMP_PARALLEL_DO: case ST_OMP_ATOMIC: \ @@ -2349,6 +2353,9 @@ gfc_ascii_statement (gfc_statement st) case ST_OMP_END_PARALLEL_DO_SIMD: p = "!$OMP END PARALLEL DO SIMD"; break; + case ST_OMP_END_PARALLEL_MASTER: + p = "!$OMP END PARALLEL MASTER"; + break; case ST_OMP_END_PARALLEL_SECTIONS: p = "!$OMP END PARALLEL SECTIONS"; break; @@ -2443,6 +2450,9 @@ gfc_ascii_statement (gfc_statement st) case ST_OMP_PARALLEL_DO_SIMD: p = "!$OMP PARALLEL DO SIMD"; break; + case ST_OMP_PARALLEL_MASTER: + p = "!$OMP PARALLEL MASTER"; + break; case ST_OMP_PARALLEL_SECTIONS: p = "!$OMP PARALLEL SECTIONS"; break; @@ -5255,6 +5265,9 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) case ST_OMP_PARALLEL: omp_end_st = ST_OMP_END_PARALLEL; break; + case ST_OMP_PARALLEL_MASTER: + omp_end_st = ST_OMP_END_PARALLEL_MASTER; + break; case ST_OMP_PARALLEL_SECTIONS: omp_end_st = ST_OMP_END_PARALLEL_SECTIONS; break; @@ -5379,6 +5392,7 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) break; case ST_OMP_PARALLEL: + case ST_OMP_PARALLEL_MASTER: case ST_OMP_PARALLEL_SECTIONS: parse_omp_structured_block (st, false); break; @@ -5580,6 +5594,7 @@ parse_executable (gfc_statement st) break; case ST_OMP_PARALLEL: + case ST_OMP_PARALLEL_MASTER: case ST_OMP_PARALLEL_SECTIONS: case ST_OMP_SECTIONS: case ST_OMP_ORDERED: diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 5a81387..747516f 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -10802,6 +10802,7 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns) case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SECTIONS: @@ -11763,6 +11764,7 @@ gfc_resolve_code (gfc_code *code, gfc_namespace *ns) case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_TARGET_PARALLEL: case EXEC_OMP_TARGET_PARALLEL_DO: @@ -11938,6 +11940,12 @@ start: if (resolve_ordinary_assign (code, ns)) { + if (omp_workshare_flag) + { + gfc_error ("Expected intrinsic assignment in OMP WORKSHARE " + "at %L", &code->loc); + break; + } if (code->op == EXEC_COMPCALL) goto compcall; else @@ -12243,6 +12251,7 @@ start: case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: omp_workshare_save = omp_workshare_flag; @@ -16039,7 +16048,8 @@ resolve_symbol (gfc_symbol *sym) && !(sym->ns->save_all && !sym->attr.automatic) && sym->module == NULL && (sym->ns->proc_name == NULL - || sym->ns->proc_name->attr.flavor != FL_MODULE)) + || (sym->ns->proc_name->attr.flavor != FL_MODULE + && !sym->ns->proc_name->attr.is_main_program))) gfc_error ("Threadprivate at %L isn't SAVEd", &sym->declared_at); /* Check omp declare target restrictions. */ @@ -16050,7 +16060,8 @@ resolve_symbol (gfc_symbol *sym) && (!sym->attr.in_common && sym->module == NULL && (sym->ns->proc_name == NULL - || sym->ns->proc_name->attr.flavor != FL_MODULE))) + || (sym->ns->proc_name->attr.flavor != FL_MODULE + && !sym->ns->proc_name->attr.is_main_program)))) gfc_error ("!$OMP DECLARE TARGET variable %qs at %L isn't SAVEd", sym->name, &sym->declared_at); diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c index 9e76199..02a81da 100644 --- a/gcc/fortran/st.c +++ b/gcc/fortran/st.c @@ -230,6 +230,7 @@ gfc_free_statement (gfc_code *p) case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SCAN: diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index aa3a82e..5666cd6 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -5554,6 +5554,28 @@ gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock, } static tree +gfc_trans_omp_parallel_master (gfc_code *code) +{ + stmtblock_t block; + tree stmt, omp_clauses; + + gfc_start_block (&block); + omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses, + code->loc); + pushlevel (); + stmt = gfc_trans_omp_master (code); + if (TREE_CODE (stmt) != BIND_EXPR) + stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0)); + else + poplevel (0, 0); + stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL, + void_type_node, stmt, omp_clauses); + OMP_PARALLEL_COMBINED (stmt) = 1; + gfc_add_expr_to_block (&block, stmt); + return gfc_finish_block (&block); +} + +static tree gfc_trans_omp_parallel_sections (gfc_code *code) { stmtblock_t block; @@ -6092,6 +6114,7 @@ gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses) case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_CRITICAL: @@ -6273,6 +6296,8 @@ gfc_trans_omp_directive (gfc_code *code) return gfc_trans_omp_parallel_do (code, NULL, NULL); case EXEC_OMP_PARALLEL_DO_SIMD: return gfc_trans_omp_parallel_do_simd (code, NULL, NULL); + case EXEC_OMP_PARALLEL_MASTER: + return gfc_trans_omp_parallel_master (code); case EXEC_OMP_PARALLEL_SECTIONS: return gfc_trans_omp_parallel_sections (code); case EXEC_OMP_PARALLEL_WORKSHARE: diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index 624c713..9f296bd 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -2174,6 +2174,7 @@ trans_code (gfc_code * code, tree cond) case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_PARALLEL_MASTER: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SECTIONS: diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c index 21ca394..4b1e11d 100644 --- a/gcc/gcov-io.c +++ b/gcc/gcov-io.c @@ -27,40 +27,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Routines declared in gcov-io.h. This file should be #included by another source file, after having #included gcov-io.h. */ -#if !IN_GCOV -static void gcov_write_block (unsigned); -static gcov_unsigned_t *gcov_write_words (unsigned); -#endif -static const gcov_unsigned_t *gcov_read_words (unsigned); -#if !IN_LIBGCOV -static void gcov_allocate (unsigned); -#endif - -/* Optimum number of gcov_unsigned_t's read from or written to disk. */ -#define GCOV_BLOCK_SIZE (1 << 10) +static gcov_unsigned_t *gcov_read_words (void *buffer, unsigned); struct gcov_var { FILE *file; - gcov_position_t start; /* Position of first byte of block */ - unsigned offset; /* Read/write position within the block. */ - unsigned length; /* Read limit in the block. */ - unsigned overread; /* Number of words overread. */ int error; /* < 0 overflow, > 0 disk error. */ - int mode; /* < 0 writing, > 0 reading */ + int mode; /* < 0 writing, > 0 reading. */ int endian; /* Swap endianness. */ -#if IN_LIBGCOV - /* Holds one block plus 4 bytes, thus all coverage reads & writes - fit within this buffer and we always can transfer GCOV_BLOCK_SIZE - to and from the disk. libgcov never backtracks and only writes 4 - or 8 byte objects. */ - gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1]; -#else - /* Holds a variable length block, as the compiler can write - strings and needs to backtrack. */ - size_t alloc; - gcov_unsigned_t *buffer; -#endif } gcov_var; /* Save the current position in the gcov file. */ @@ -71,8 +45,7 @@ static inline gcov_position_t gcov_position (void) { - gcov_nonruntime_assert (gcov_var.mode > 0); - return gcov_var.start + gcov_var.offset; + return ftell (gcov_var.file); } /* Return nonzero if the error flag is set. */ @@ -92,20 +65,16 @@ GCOV_LINKAGE inline void gcov_rewrite (void) { gcov_var.mode = -1; - gcov_var.start = 0; - gcov_var.offset = 0; fseek (gcov_var.file, 0L, SEEK_SET); } #endif -static inline gcov_unsigned_t from_file (gcov_unsigned_t value) +static inline gcov_unsigned_t +from_file (gcov_unsigned_t value) { #if !IN_LIBGCOV || defined (IN_GCOV_TOOL) if (gcov_var.endian) - { - value = (value >> 16) | (value << 16); - value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff); - } + return __builtin_bswap32 (value); #endif return value; } @@ -142,9 +111,6 @@ gcov_open (const char *name, int mode) #endif gcov_nonruntime_assert (!gcov_var.file); - gcov_var.start = 0; - gcov_var.offset = gcov_var.length = 0; - gcov_var.overread = -1u; gcov_var.error = 0; #if !IN_LIBGCOV || defined (IN_GCOV_TOOL) gcov_var.endian = 0; @@ -222,8 +188,6 @@ gcov_open (const char *name, int mode) gcov_var.mode = mode ? mode : 1; - setbuf (gcov_var.file, (char *)0); - return 1; } @@ -235,19 +199,9 @@ gcov_close (void) { if (gcov_var.file) { -#if !IN_GCOV - if (gcov_var.offset && gcov_var.mode < 0) - gcov_write_block (gcov_var.offset); -#endif fclose (gcov_var.file); gcov_var.file = 0; - gcov_var.length = 0; } -#if !IN_LIBGCOV - free (gcov_var.buffer); - gcov_var.alloc = 0; - gcov_var.buffer = 0; -#endif gcov_var.mode = 0; return gcov_var.error; } @@ -262,9 +216,8 @@ gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected) { if (magic == expected) return 1; - magic = (magic >> 16) | (magic << 16); - magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff); - if (magic == expected) + + if (__builtin_bswap32 (magic) == expected) { gcov_var.endian = 1; return -1; @@ -273,71 +226,15 @@ gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected) } #endif -#if !IN_LIBGCOV -static void -gcov_allocate (unsigned length) -{ - size_t new_size = gcov_var.alloc; - - if (!new_size) - new_size = GCOV_BLOCK_SIZE; - new_size += length; - new_size *= 2; - - gcov_var.alloc = new_size; - gcov_var.buffer = XRESIZEVAR (gcov_unsigned_t, gcov_var.buffer, new_size << 2); -} -#endif - #if !IN_GCOV -/* Write out the current block, if needs be. */ - -static void -gcov_write_block (unsigned size) -{ - if (fwrite (gcov_var.buffer, size << 2, 1, gcov_var.file) != 1) - gcov_var.error = 1; - gcov_var.start += size; - gcov_var.offset -= size; -} - -/* Allocate space to write BYTES bytes to the gcov file. Return a - pointer to those bytes, or NULL on failure. */ - -static gcov_unsigned_t * -gcov_write_words (unsigned words) -{ - gcov_unsigned_t *result; - - gcov_nonruntime_assert (gcov_var.mode < 0); -#if IN_LIBGCOV - if (gcov_var.offset >= GCOV_BLOCK_SIZE) - { - gcov_write_block (GCOV_BLOCK_SIZE); - if (gcov_var.offset) - { - memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4); - } - } -#else - if (gcov_var.offset + words > gcov_var.alloc) - gcov_allocate (gcov_var.offset + words); -#endif - result = &gcov_var.buffer[gcov_var.offset]; - gcov_var.offset += words; - - return result; -} - -/* Write unsigned VALUE to coverage file. Sets error flag - appropriately. */ +/* Write unsigned VALUE to coverage file. */ GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t value) { - gcov_unsigned_t *buffer = gcov_write_words (1); - - buffer[0] = value; + gcov_unsigned_t r = fwrite (&value, sizeof (value), 1, gcov_var.file); + if (r != 1) + gcov_var.error = 1; } /* Write counter VALUE to coverage file. Sets error flag @@ -347,13 +244,11 @@ gcov_write_unsigned (gcov_unsigned_t value) GCOV_LINKAGE void gcov_write_counter (gcov_type value) { - gcov_unsigned_t *buffer = gcov_write_words (2); - - buffer[0] = (gcov_unsigned_t) value; + gcov_write_unsigned ((gcov_unsigned_t) value); if (sizeof (value) > sizeof (gcov_unsigned_t)) - buffer[1] = (gcov_unsigned_t) (value >> 32); + gcov_write_unsigned ((gcov_unsigned_t) (value >> 32)); else - buffer[1] = 0; + gcov_write_unsigned (0); } #endif /* IN_LIBGCOV */ @@ -365,23 +260,16 @@ GCOV_LINKAGE void gcov_write_string (const char *string) { unsigned length = 0; - unsigned alloc = 0; - gcov_unsigned_t *buffer; if (string) - { - length = strlen (string); - alloc = (length + 4) >> 2; - } - - buffer = gcov_write_words (1 + alloc); + length = strlen (string) + 1; - buffer[0] = alloc; - - if (alloc > 0) + gcov_write_unsigned (length); + if (length > 0) { - buffer[alloc] = 0; /* place nul terminators. */ - memcpy (&buffer[1], string, length); + gcov_unsigned_t r = fwrite (string, length, 1, gcov_var.file); + if (r != 1) + gcov_var.error = 1; } } #endif @@ -418,6 +306,14 @@ gcov_write_filename (const char *filename) } #endif +/* Move to a given position in a gcov file. */ + +GCOV_LINKAGE void +gcov_seek (gcov_position_t base) +{ + fseek (gcov_var.file, base, SEEK_SET); +} + #if !IN_LIBGCOV /* Write a tag TAG and reserve space for the record length. Return a value to be used for gcov_write_length. */ @@ -425,11 +321,9 @@ gcov_write_filename (const char *filename) GCOV_LINKAGE gcov_position_t gcov_write_tag (gcov_unsigned_t tag) { - gcov_position_t result = gcov_var.start + gcov_var.offset; - gcov_unsigned_t *buffer = gcov_write_words (2); - - buffer[0] = tag; - buffer[1] = 0; + gcov_position_t result = gcov_position (); + gcov_write_unsigned (tag); + gcov_write_unsigned (0); return result; } @@ -442,19 +336,13 @@ gcov_write_tag (gcov_unsigned_t tag) GCOV_LINKAGE void gcov_write_length (gcov_position_t position) { - unsigned offset; - gcov_unsigned_t length; - gcov_unsigned_t *buffer; - + gcov_position_t current_position = gcov_position (); gcov_nonruntime_assert (gcov_var.mode < 0); - gcov_nonruntime_assert (position + 2 <= gcov_var.start + gcov_var.offset); - gcov_nonruntime_assert (position >= gcov_var.start); - offset = position - gcov_var.start; - length = gcov_var.offset - offset - 2; - buffer = (gcov_unsigned_t *) &gcov_var.buffer[offset]; - buffer[1] = length; - if (gcov_var.offset >= GCOV_BLOCK_SIZE) - gcov_write_block (gcov_var.offset); + gcov_nonruntime_assert (current_position >= position + 2 * GCOV_WORD_SIZE); + + gcov_seek (position + GCOV_WORD_SIZE); + gcov_write_unsigned (current_position - position - 2 * GCOV_WORD_SIZE); + gcov_seek (current_position); } #else /* IN_LIBGCOV */ @@ -464,10 +352,8 @@ gcov_write_length (gcov_position_t position) GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length) { - gcov_unsigned_t *buffer = gcov_write_words (2); - - buffer[0] = tag; - buffer[1] = length; + gcov_write_unsigned (tag); + gcov_write_unsigned (length); } /* Write a summary structure to the gcov file. Return nonzero on @@ -485,52 +371,28 @@ gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary) #endif /*!IN_GCOV */ -/* Return a pointer to read BYTES bytes from the gcov file. Returns +/* Return a pointer to read COUNT bytes from the gcov file. Returns NULL on failure (read past EOF). */ -static const gcov_unsigned_t * -gcov_read_words (unsigned words) +static void * +gcov_read_bytes (void *buffer, unsigned count) { - const gcov_unsigned_t *result; - unsigned excess = gcov_var.length - gcov_var.offset; - if (gcov_var.mode <= 0) return NULL; - if (excess < words) - { - gcov_var.start += gcov_var.offset; - if (excess) - { -#if IN_LIBGCOV - memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4); -#else - memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, - excess * 4); -#endif - } - gcov_var.offset = 0; - gcov_var.length = excess; -#if IN_LIBGCOV - excess = GCOV_BLOCK_SIZE; -#else - if (gcov_var.length + words > gcov_var.alloc) - gcov_allocate (gcov_var.length + words); - excess = gcov_var.alloc - gcov_var.length; -#endif - excess = fread (gcov_var.buffer + gcov_var.length, - 1, excess << 2, gcov_var.file) >> 2; - gcov_var.length += excess; - if (gcov_var.length < words) - { - gcov_var.overread += words - gcov_var.length; - gcov_var.length = 0; - return 0; - } - } - result = &gcov_var.buffer[gcov_var.offset]; - gcov_var.offset += words; - return result; + unsigned read = fread (buffer, count, 1, gcov_var.file); + if (read != 1) + return NULL; + + return buffer; +} + +/* Read WORDS gcov_unsigned_t values from gcov file. */ + +static gcov_unsigned_t * +gcov_read_words (void *buffer, unsigned words) +{ + return (gcov_unsigned_t *)gcov_read_bytes (buffer, GCOV_WORD_SIZE * words); } /* Read unsigned value from a coverage file. Sets error flag on file @@ -540,10 +402,12 @@ GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) { gcov_unsigned_t value; - const gcov_unsigned_t *buffer = gcov_read_words (1); + gcov_unsigned_t allocated_buffer[1]; + gcov_unsigned_t *buffer = gcov_read_words (&allocated_buffer, 1); if (!buffer) return 0; + value = from_file (buffer[0]); return value; } @@ -555,7 +419,8 @@ GCOV_LINKAGE gcov_type gcov_read_counter (void) { gcov_type value; - const gcov_unsigned_t *buffer = gcov_read_words (2); + gcov_unsigned_t allocated_buffer[2]; + gcov_unsigned_t *buffer = gcov_read_words (&allocated_buffer, 2); if (!buffer) return 0; @@ -632,7 +497,8 @@ gcov_read_string (void) if (!length) return 0; - return (const char *) gcov_read_words (length); + void *buffer = XNEWVEC (char *, length); + return (const char *) gcov_read_bytes (buffer, length); } #endif @@ -654,27 +520,7 @@ gcov_sync (gcov_position_t base, gcov_unsigned_t length) { gcov_nonruntime_assert (gcov_var.mode > 0); base += length; - if (base - gcov_var.start <= gcov_var.length) - gcov_var.offset = base - gcov_var.start; - else - { - gcov_var.offset = gcov_var.length = 0; - fseek (gcov_var.file, base << 2, SEEK_SET); - gcov_var.start = ftell (gcov_var.file) >> 2; - } -} -#endif - -#if IN_LIBGCOV -/* Move to a given position in a gcov file. */ - -GCOV_LINKAGE void -gcov_seek (gcov_position_t base) -{ - if (gcov_var.offset) - gcov_write_block (gcov_var.offset); - fseek (gcov_var.file, base << 2, SEEK_SET); - gcov_var.start = ftell (gcov_var.file) >> 2; + fseek (gcov_var.file, base, SEEK_SET); } #endif diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h index c536554..f7584eb 100644 --- a/gcc/gcov-io.h +++ b/gcc/gcov-io.h @@ -243,22 +243,25 @@ typedef uint64_t gcov_type_unsigned; /* The record tags. Values [1..3f] are for tags which may be in either file. Values [41..9f] for those in the note file and [a1..ff] for the data file. The tag value zero is used as an explicit end of - file marker -- it is not required to be present. */ + file marker -- it is not required to be present. + All length values are in bytes. */ + +#define GCOV_WORD_SIZE 4 #define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000) -#define GCOV_TAG_FUNCTION_LENGTH (3) +#define GCOV_TAG_FUNCTION_LENGTH (3 * GCOV_WORD_SIZE) #define GCOV_TAG_BLOCKS ((gcov_unsigned_t)0x01410000) #define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM) #define GCOV_TAG_ARCS ((gcov_unsigned_t)0x01430000) -#define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2) -#define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH) - 1) / 2) +#define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2 * GCOV_WORD_SIZE) +#define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH / GCOV_WORD_SIZE) - 1) / 2) #define GCOV_TAG_LINES ((gcov_unsigned_t)0x01450000) #define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000) -#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2) -#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2) +#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2 * GCOV_WORD_SIZE) +#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH / GCOV_WORD_SIZE) / 2) #define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000) #define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000) /* Obsolete */ -#define GCOV_TAG_SUMMARY_LENGTH (2) +#define GCOV_TAG_SUMMARY_LENGTH (2 * GCOV_WORD_SIZE) #define GCOV_TAG_AFDO_FILE_NAMES ((gcov_unsigned_t)0xaa000000) #define GCOV_TAG_AFDO_FUNCTION ((gcov_unsigned_t)0xac000000) #define GCOV_TAG_AFDO_WORKING_SET ((gcov_unsigned_t)0xaf000000) diff --git a/gcc/genoutput.c b/gcc/genoutput.c index 8e911cc..6d4ab81 100644 --- a/gcc/genoutput.c +++ b/gcc/genoutput.c @@ -757,6 +757,7 @@ validate_insn_alternatives (class data *d) int which_alternative = 0; int alternative_count_unsure = 0; bool seen_write = false; + bool alt_mismatch = false; for (p = d->operand[start].constraint; (c = *p); p += len) { @@ -813,8 +814,19 @@ validate_insn_alternatives (class data *d) if (n == 0) n = d->operand[start].n_alternatives; else if (n != d->operand[start].n_alternatives) - error_at (d->loc, "wrong number of alternatives in operand %d", - start); + { + if (!alt_mismatch) + { + alt_mismatch = true; + error_at (d->loc, + "alternative number mismatch: " + "operand %d has %d, operand %d has %d", + 0, n, start, d->operand[start].n_alternatives); + } + else + error_at (d->loc, "operand %d has %d alternatives", + start, d->operand[start].n_alternatives); + } } } diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index e94bb35..5b288d8 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -737,7 +737,7 @@ range_of_builtin_call (range_query &query, irange &r, gcall *call) query.range_of_expr (r, arg, call); // From clz of minimum we can compute result maximum. - if (r.constant_p ()) + if (r.constant_p () && !r.varying_p ()) { int newmaxi = prec - 1 - wi::floor_log2 (r.lower_bound ()); // Argument is unsigned, so do nothing if it is [0, ...] range. @@ -47,14 +47,18 @@ extern const char *fake_ngettext (const char *singular, const char *plural, #endif +/* Used to immediately translate the argument. */ #ifndef _ # define _(msgid) gettext (msgid) #endif +/* Used to mark strings that will be translated later. */ #ifndef N_ # define N_(msgid) msgid #endif +/* Like N_, but for GCC diagnostic format strings. See ABOUT-GCC-NLS for + details. */ #ifndef G_ # define G_(gmsgid) gmsgid #endif diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index d6be7f0..1c26439 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include "simple-object.h" #include "lto-section-names.h" #include "collect-utils.h" +#include "opts-diagnostic.h" /* Environment variable, used for passing the names of offload targets from GCC driver to lto-wrapper. */ @@ -139,12 +140,12 @@ maybe_unlink (const char *file) /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS environment. */ -static void +static vec<cl_decoded_option> get_options_from_collect_gcc_options (const char *collect_gcc, - const char *collect_gcc_options, - struct cl_decoded_option **decoded_options, - unsigned int *decoded_options_count) + const char *collect_gcc_options) { + cl_decoded_option *decoded_options; + unsigned int decoded_options_count; struct obstack argv_obstack; const char **argv; int argc; @@ -157,57 +158,80 @@ get_options_from_collect_gcc_options (const char *collect_gcc, argv = XOBFINISH (&argv_obstack, const char **); decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER, - decoded_options, decoded_options_count); + &decoded_options, &decoded_options_count); + vec<cl_decoded_option> decoded; + decoded.create (decoded_options_count); + for (unsigned i = 0; i < decoded_options_count; ++i) + decoded.quick_push (decoded_options[i]); + free (decoded_options); + obstack_free (&argv_obstack, NULL); + + return decoded; } -/* Append OPTION to the options array DECODED_OPTIONS with size - DECODED_OPTIONS_COUNT. */ +/* Find option in OPTIONS based on OPT_INDEX. -1 value is returned + if the option is not present. */ -static void -append_option (struct cl_decoded_option **decoded_options, - unsigned int *decoded_options_count, - struct cl_decoded_option *option) +static int +find_option (vec<cl_decoded_option> &options, size_t opt_index) { - ++*decoded_options_count; - *decoded_options - = (struct cl_decoded_option *) - xrealloc (*decoded_options, - (*decoded_options_count - * sizeof (struct cl_decoded_option))); - memcpy (&(*decoded_options)[*decoded_options_count - 1], option, - sizeof (struct cl_decoded_option)); + for (unsigned i = 0; i < options.length (); ++i) + if (options[i].opt_index == opt_index) + return i; + + return -1; +} + +static int +find_option (vec<cl_decoded_option> &options, cl_decoded_option *option) +{ + return find_option (options, option->opt_index); } -/* Remove option number INDEX from DECODED_OPTIONS, update - DECODED_OPTIONS_COUNT. */ +/* Merge -flto FOPTION into vector of DECODED_OPTIONS. */ static void -remove_option (struct cl_decoded_option **decoded_options, - int index, unsigned int *decoded_options_count) +merge_flto_options (vec<cl_decoded_option> &decoded_options, + cl_decoded_option *foption) { - --*decoded_options_count; - memmove (&(*decoded_options)[index + 1], - &(*decoded_options)[index], - sizeof (struct cl_decoded_option) - * (*decoded_options_count - index)); + int existing_opt = find_option (decoded_options, foption); + if (existing_opt == -1) + decoded_options.safe_push (*foption); + else + { + if (strcmp (foption->arg, decoded_options[existing_opt].arg) != 0) + { + /* -flto=auto is preferred. */ + if (strcmp (decoded_options[existing_opt].arg, "auto") == 0) + ; + else if (strcmp (foption->arg, "auto") == 0 + || strcmp (foption->arg, "jobserver") == 0) + decoded_options[existing_opt].arg = foption->arg; + else if (strcmp (decoded_options[existing_opt].arg, + "jobserver") != 0) + { + int n = atoi (foption->arg); + int original_n = atoi (decoded_options[existing_opt].arg); + if (n > original_n) + decoded_options[existing_opt].arg = foption->arg; + } + } + } } /* Try to merge and complain about options FDECODED_OPTIONS when applied ontop of DECODED_OPTIONS. */ static void -merge_and_complain (struct cl_decoded_option **decoded_options, - unsigned int *decoded_options_count, - struct cl_decoded_option *fdecoded_options, - unsigned int fdecoded_options_count, - struct cl_decoded_option *decoded_cl_options, - unsigned int decoded_cl_options_count) +merge_and_complain (vec<cl_decoded_option> decoded_options, + vec<cl_decoded_option> fdecoded_options, + vec<cl_decoded_option> decoded_cl_options) { unsigned int i, j; - struct cl_decoded_option *pic_option = NULL; - struct cl_decoded_option *pie_option = NULL; - struct cl_decoded_option *cf_protection_option = NULL; + cl_decoded_option *pic_option = NULL; + cl_decoded_option *pie_option = NULL; + cl_decoded_option *cf_protection_option = NULL; /* ??? Merge options from files. Most cases can be handled by either unioning or intersecting @@ -224,9 +248,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options, /* Look for a -fcf-protection option in the link-time options which overrides any -fcf-protection from the lto sections. */ - for (i = 0; i < decoded_cl_options_count; ++i) + for (i = 0; i < decoded_cl_options.length (); ++i) { - struct cl_decoded_option *foption = &decoded_cl_options[i]; + cl_decoded_option *foption = &decoded_cl_options[i]; if (foption->opt_index == OPT_fcf_protection_) { cf_protection_option = foption; @@ -235,9 +259,10 @@ merge_and_complain (struct cl_decoded_option **decoded_options, /* The following does what the old LTO option code did, union all target and a selected set of common options. */ - for (i = 0; i < fdecoded_options_count; ++i) + for (i = 0; i < fdecoded_options.length (); ++i) { - struct cl_decoded_option *foption = &fdecoded_options[i]; + cl_decoded_option *foption = &fdecoded_options[i]; + int existing_opt = find_option (decoded_options, foption); switch (foption->opt_index) { case OPT_SPECIAL_unknown: @@ -265,11 +290,8 @@ merge_and_complain (struct cl_decoded_option **decoded_options, setting per OPT code, we pick the first we encounter. ??? This doesn't make too much sense, but when it doesn't then we should complain. */ - for (j = 0; j < *decoded_options_count; ++j) - if ((*decoded_options)[j].opt_index == foption->opt_index) - break; - if (j == *decoded_options_count) - append_option (decoded_options, decoded_options_count, foption); + if (existing_opt == -1) + decoded_options.safe_push (*foption); break; /* Figure out what PIC/PIE level wins and merge the results. */ @@ -285,25 +307,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options, case OPT_fopenmp: case OPT_fopenacc: /* For selected options we can merge conservatively. */ - for (j = 0; j < *decoded_options_count; ++j) - if ((*decoded_options)[j].opt_index == foption->opt_index) - break; - if (j == *decoded_options_count) - append_option (decoded_options, decoded_options_count, foption); + if (existing_opt == -1) + decoded_options.safe_push (*foption); /* -fopenmp > -fno-openmp, -fopenacc > -fno-openacc */ - else if (foption->value > (*decoded_options)[j].value) - (*decoded_options)[j] = *foption; + else if (foption->value > decoded_options[existing_opt].value) + decoded_options[existing_opt] = *foption; break; case OPT_fopenacc_dim_: /* Append or check identical. */ - for (j = 0; j < *decoded_options_count; ++j) - if ((*decoded_options)[j].opt_index == foption->opt_index) - break; - if (j == *decoded_options_count) - append_option (decoded_options, decoded_options_count, foption); - else if (strcmp ((*decoded_options)[j].arg, foption->arg)) + if (existing_opt == -1) + decoded_options.safe_push (*foption); + else if (strcmp (decoded_options[existing_opt].arg, foption->arg)) fatal_error (input_location, "option %s with different values", foption->orig_option_with_args_text); @@ -314,12 +330,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options, if (!cf_protection_option || cf_protection_option->value == CF_CHECK) { - for (j = 0; j < *decoded_options_count; ++j) - if ((*decoded_options)[j].opt_index == foption->opt_index) - break; - if (j == *decoded_options_count) - append_option (decoded_options, decoded_options_count, foption); - else if ((*decoded_options)[j].value != foption->value) + if (existing_opt == -1) + decoded_options.safe_push (*foption); + else if (decoded_options[existing_opt].value != foption->value) { if (cf_protection_option && cf_protection_option->value == CF_CHECK) @@ -327,22 +340,23 @@ merge_and_complain (struct cl_decoded_option **decoded_options, "option %qs with mismatching values" " (%s, %s)", "-fcf-protection", - (*decoded_options)[j].arg, foption->arg); + decoded_options[existing_opt].arg, + foption->arg); else { /* Merge and update the -fcf-protection option. */ - (*decoded_options)[j].value &= (foption->value - & CF_FULL); - switch ((*decoded_options)[j].value) + decoded_options[existing_opt].value + &= (foption->value & CF_FULL); + switch (decoded_options[existing_opt].value) { case CF_NONE: - (*decoded_options)[j].arg = "none"; + decoded_options[existing_opt].arg = "none"; break; case CF_BRANCH: - (*decoded_options)[j].arg = "branch"; + decoded_options[existing_opt].arg = "branch"; break; case CF_RETURN: - (*decoded_options)[j].arg = "return"; + decoded_options[existing_opt].arg = "return"; break; default: gcc_unreachable (); @@ -356,15 +370,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options, case OPT_Ofast: case OPT_Og: case OPT_Os: - for (j = 0; j < *decoded_options_count; ++j) - if ((*decoded_options)[j].opt_index == OPT_O - || (*decoded_options)[j].opt_index == OPT_Ofast - || (*decoded_options)[j].opt_index == OPT_Og - || (*decoded_options)[j].opt_index == OPT_Os) - break; - if (j == *decoded_options_count) - append_option (decoded_options, decoded_options_count, foption); - else if ((*decoded_options)[j].opt_index == foption->opt_index + existing_opt = -1; + for (j = 0; j < decoded_options.length (); ++j) + if (decoded_options[j].opt_index == OPT_O + || decoded_options[j].opt_index == OPT_Ofast + || decoded_options[j].opt_index == OPT_Og + || decoded_options[j].opt_index == OPT_Os) + { + existing_opt = j; + break; + } + if (existing_opt == -1) + decoded_options.safe_push (*foption); + else if (decoded_options[existing_opt].opt_index == foption->opt_index && foption->opt_index != OPT_O) /* Exact same options get merged. */ ; @@ -394,13 +412,14 @@ merge_and_complain (struct cl_decoded_option **decoded_options, default: gcc_unreachable (); } - switch ((*decoded_options)[j].opt_index) + switch (decoded_options[existing_opt].opt_index) { case OPT_O: - if ((*decoded_options)[j].arg[0] == '\0') + if (decoded_options[existing_opt].arg[0] == '\0') level = MAX (level, 1); else - level = MAX (level, atoi ((*decoded_options)[j].arg)); + level = MAX (level, + atoi (decoded_options[existing_opt].arg)); break; case OPT_Ofast: level = MAX (level, 3); @@ -414,23 +433,20 @@ merge_and_complain (struct cl_decoded_option **decoded_options, default: gcc_unreachable (); } - (*decoded_options)[j].opt_index = OPT_O; + decoded_options[existing_opt].opt_index = OPT_O; char *tem; tem = xasprintf ("-O%d", level); - (*decoded_options)[j].arg = &tem[2]; - (*decoded_options)[j].canonical_option[0] = tem; - (*decoded_options)[j].value = 1; + decoded_options[existing_opt].arg = &tem[2]; + decoded_options[existing_opt].canonical_option[0] = tem; + decoded_options[existing_opt].value = 1; } break; case OPT_foffload_abi_: - for (j = 0; j < *decoded_options_count; ++j) - if ((*decoded_options)[j].opt_index == foption->opt_index) - break; - if (j == *decoded_options_count) - append_option (decoded_options, decoded_options_count, foption); - else if (foption->value != (*decoded_options)[j].value) + if (existing_opt == -1) + decoded_options.safe_push (*foption); + else if (foption->value != decoded_options[existing_opt].value) fatal_error (input_location, "option %s not used consistently in all LTO input" " files", foption->orig_option_with_args_text); @@ -438,7 +454,11 @@ merge_and_complain (struct cl_decoded_option **decoded_options, case OPT_foffload_: - append_option (decoded_options, decoded_options_count, foption); + decoded_options.safe_push (*foption); + break; + + case OPT_flto_: + merge_flto_options (decoded_options, foption); break; } } @@ -458,12 +478,12 @@ merge_and_complain (struct cl_decoded_option **decoded_options, It would be good to warn on mismatches, but it is bit hard to do as we do not know what nothing translates to. */ - for (unsigned int j = 0; j < *decoded_options_count;) - if ((*decoded_options)[j].opt_index == OPT_fPIC - || (*decoded_options)[j].opt_index == OPT_fpic) + for (unsigned int j = 0; j < decoded_options.length ();) + if (decoded_options[j].opt_index == OPT_fPIC + || decoded_options[j].opt_index == OPT_fpic) { /* -fno-pic in one unit implies -fno-pic everywhere. */ - if ((*decoded_options)[j].value == 0) + if (decoded_options[j].value == 0) j++; /* If we have no pic option or merge in -fno-pic, we still may turn existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present. */ @@ -472,41 +492,41 @@ merge_and_complain (struct cl_decoded_option **decoded_options, { if (pie_option) { - bool big = (*decoded_options)[j].opt_index == OPT_fPIC + bool big = decoded_options[j].opt_index == OPT_fPIC && pie_option->opt_index == OPT_fPIE; - (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie; + decoded_options[j].opt_index = big ? OPT_fPIE : OPT_fpie; if (pie_option->value) - (*decoded_options)[j].canonical_option[0] + decoded_options[j].canonical_option[0] = big ? "-fPIE" : "-fpie"; else - (*decoded_options)[j].canonical_option[0] = "-fno-pie"; - (*decoded_options)[j].value = pie_option->value; - j++; + decoded_options[j].canonical_option[0] = "-fno-pie"; + decoded_options[j].value = pie_option->value; + j++; } else if (pic_option) { - (*decoded_options)[j] = *pic_option; - j++; + decoded_options[j] = *pic_option; + j++; } /* We do not know if target defaults to pic or not, so just remove option if it is missing in one unit but enabled in other. */ else - remove_option (decoded_options, j, decoded_options_count); + decoded_options.ordered_remove (j); } else if (pic_option->opt_index == OPT_fpic - && (*decoded_options)[j].opt_index == OPT_fPIC) + && decoded_options[j].opt_index == OPT_fPIC) { - (*decoded_options)[j] = *pic_option; + decoded_options[j] = *pic_option; j++; } else j++; } - else if ((*decoded_options)[j].opt_index == OPT_fPIE - || (*decoded_options)[j].opt_index == OPT_fpie) + else if (decoded_options[j].opt_index == OPT_fPIE + || decoded_options[j].opt_index == OPT_fpie) { /* -fno-pie in one unit implies -fno-pie everywhere. */ - if ((*decoded_options)[j].value == 0) + if (decoded_options[j].value == 0) j++; /* If we have no pie option or merge in -fno-pie, we still preserve PIE/pie if pic/PIC is present. */ @@ -517,32 +537,32 @@ merge_and_complain (struct cl_decoded_option **decoded_options, if (pic_option) { if (pic_option->opt_index == OPT_fpic - && (*decoded_options)[j].opt_index == OPT_fPIE) + && decoded_options[j].opt_index == OPT_fPIE) { - (*decoded_options)[j].opt_index = OPT_fpie; - (*decoded_options)[j].canonical_option[0] + decoded_options[j].opt_index = OPT_fpie; + decoded_options[j].canonical_option[0] = pic_option->value ? "-fpie" : "-fno-pie"; } else if (!pic_option->value) - (*decoded_options)[j].canonical_option[0] = "-fno-pie"; - (*decoded_options)[j].value = pic_option->value; + decoded_options[j].canonical_option[0] = "-fno-pie"; + decoded_options[j].value = pic_option->value; j++; } else if (pie_option) { - (*decoded_options)[j] = *pie_option; + decoded_options[j] = *pie_option; j++; } /* Because we always append pic/PIE options this code path should not happen unless the LTO object was built by old lto1 which did not contain that logic yet. */ else - remove_option (decoded_options, j, decoded_options_count); + decoded_options.ordered_remove (j); } else if (pie_option->opt_index == OPT_fpie - && (*decoded_options)[j].opt_index == OPT_fPIE) + && decoded_options[j].opt_index == OPT_fPIE) { - (*decoded_options)[j] = *pie_option; + decoded_options[j] = *pie_option; j++; } else @@ -554,37 +574,41 @@ merge_and_complain (struct cl_decoded_option **decoded_options, if (!xassembler_options_error) for (i = j = 0; ; i++, j++) { - for (; i < *decoded_options_count; i++) - if ((*decoded_options)[i].opt_index == OPT_Xassembler) - break; - - for (; j < fdecoded_options_count; j++) - if (fdecoded_options[j].opt_index == OPT_Xassembler) - break; - - if (i == *decoded_options_count && j == fdecoded_options_count) + int existing_opt_index + = find_option (decoded_options, OPT_Xassembler); + int existing_opt2_index + = find_option (fdecoded_options, OPT_Xassembler); + + cl_decoded_option *existing_opt = NULL; + cl_decoded_option *existing_opt2 = NULL; + if (existing_opt_index != -1) + existing_opt = &decoded_options[existing_opt_index]; + if (existing_opt2_index != -1) + existing_opt2 = &fdecoded_options[existing_opt2_index]; + + if (existing_opt == NULL && existing_opt2 == NULL) break; - else if (i < *decoded_options_count && j == fdecoded_options_count) + else if (existing_opt != NULL && existing_opt2 == NULL) { warning (0, "Extra option to %<-Xassembler%>: %s," " dropping all %<-Xassembler%> and %<-Wa%> options.", - (*decoded_options)[i].arg); + existing_opt->arg); xassembler_options_error = true; break; } - else if (i == *decoded_options_count && j < fdecoded_options_count) + else if (existing_opt == NULL && existing_opt2 != NULL) { warning (0, "Extra option to %<-Xassembler%>: %s," " dropping all %<-Xassembler%> and %<-Wa%> options.", - fdecoded_options[j].arg); + existing_opt2->arg); xassembler_options_error = true; break; } - else if (strcmp ((*decoded_options)[i].arg, fdecoded_options[j].arg)) + else if (strcmp (existing_opt->arg, existing_opt2->arg) != 0) { warning (0, "Options to %<-Xassembler%> do not match: %s, %s," " dropping all %<-Xassembler%> and %<-Wa%> options.", - (*decoded_options)[i].arg, fdecoded_options[j].arg); + existing_opt->arg, existing_opt2->arg); xassembler_options_error = true; break; } @@ -655,13 +679,12 @@ parse_env_var (const char *str, char ***pvalues, const char *append) /* Append options OPTS from lto or offload_lto sections to ARGV_OBSTACK. */ static void -append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts, - unsigned int count) +append_compiler_options (obstack *argv_obstack, vec<cl_decoded_option> opts) { /* Append compiler driver arguments as far as they were merged. */ - for (unsigned int j = 1; j < count; ++j) + for (unsigned int j = 1; j < opts.length (); ++j) { - struct cl_decoded_option *option = &opts[j]; + cl_decoded_option *option = &opts[j]; /* File options have been properly filtered by lto-opts.c. */ switch (option->opt_index) @@ -722,16 +745,15 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts, } } -/* Append diag options in OPTS with length COUNT to ARGV_OBSTACK. */ +/* Append diag options in OPTS to ARGV_OBSTACK. */ static void -append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts, - unsigned int count) +append_diag_options (obstack *argv_obstack, vec<cl_decoded_option> opts) { /* Append compiler driver arguments as far as they were merged. */ - for (unsigned int j = 1; j < count; ++j) + for (unsigned int j = 1; j < opts.length (); ++j) { - struct cl_decoded_option *option = &opts[j]; + cl_decoded_option *option = &opts[j]; switch (option->opt_index) { @@ -758,14 +780,13 @@ append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts, /* Append linker options OPTS to ARGV_OBSTACK. */ static void -append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts, - unsigned int count) +append_linker_options (obstack *argv_obstack, vec<cl_decoded_option> opts) { /* Append linker driver arguments. Compiler options from the linker driver arguments will override / merge with those from the compiler. */ - for (unsigned int j = 1; j < count; ++j) + for (unsigned int j = 1; j < opts.length (); ++j) { - struct cl_decoded_option *option = &opts[j]; + cl_decoded_option *option = &opts[j]; /* Do not pass on frontend specific flags not suitable for lto. */ if (!(cl_options[option->opt_index].flags @@ -803,15 +824,14 @@ append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts, static void append_offload_options (obstack *argv_obstack, const char *target, - struct cl_decoded_option *options, - unsigned int options_count) + vec<cl_decoded_option> options) { - for (unsigned i = 0; i < options_count; i++) + for (unsigned i = 0; i < options.length (); i++) { const char *cur, *next, *opts; char **argv; unsigned argc; - struct cl_decoded_option *option = &options[i]; + cl_decoded_option *option = &options[i]; if (option->opt_index != OPT_foffload_) continue; @@ -883,10 +903,8 @@ access_check (const char *name, int mode) static char * compile_offload_image (const char *target, const char *compiler_path, unsigned in_argc, char *in_argv[], - struct cl_decoded_option *compiler_opts, - unsigned int compiler_opt_count, - struct cl_decoded_option *linker_opts, - unsigned int linker_opt_count) + vec<cl_decoded_option> compiler_opts, + vec<cl_decoded_option> linker_opts) { char *filename = NULL; char *dumpbase; @@ -943,19 +961,16 @@ compile_offload_image (const char *target, const char *compiler_path, obstack_ptr_grow (&argv_obstack, in_argv[i]); /* Append options from offload_lto sections. */ - append_compiler_options (&argv_obstack, compiler_opts, - compiler_opt_count); - append_diag_options (&argv_obstack, linker_opts, linker_opt_count); + append_compiler_options (&argv_obstack, compiler_opts); + append_diag_options (&argv_obstack, linker_opts); obstack_ptr_grow (&argv_obstack, "-dumpbase"); obstack_ptr_grow (&argv_obstack, dumpbase); /* Append options specified by -foffload last. In case of conflicting options we expect offload compiler to choose the latest. */ - append_offload_options (&argv_obstack, target, compiler_opts, - compiler_opt_count); - append_offload_options (&argv_obstack, target, linker_opts, - linker_opt_count); + append_offload_options (&argv_obstack, target, compiler_opts); + append_offload_options (&argv_obstack, target, linker_opts); obstack_ptr_grow (&argv_obstack, NULL); argv = XOBFINISH (&argv_obstack, char **); @@ -974,10 +989,8 @@ compile_offload_image (const char *target, const char *compiler_path, static void compile_images_for_offload_targets (unsigned in_argc, char *in_argv[], - struct cl_decoded_option *compiler_opts, - unsigned int compiler_opt_count, - struct cl_decoded_option *linker_opts, - unsigned int linker_opt_count) + vec<cl_decoded_option> compiler_opts, + vec<cl_decoded_option> linker_opts) { char **names = NULL; const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV); @@ -997,8 +1010,7 @@ compile_images_for_offload_targets (unsigned in_argc, char *in_argv[], { offload_names[next_name_entry] = compile_offload_image (names[i], compiler_path, in_argc, in_argv, - compiler_opts, compiler_opt_count, - linker_opts, linker_opt_count); + compiler_opts, linker_opts); if (!offload_names[next_name_entry]) #if OFFLOAD_DEFAULTED continue; @@ -1080,25 +1092,22 @@ find_crtoffloadtable (int save_temps, const char *dumppfx) } /* A subroutine of run_gcc. Examine the open file FD for lto sections with - name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS - and OPT_COUNT. Return true if we found a matching section, false + name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS. + Return true if we found a matching section, false otherwise. COLLECT_GCC holds the value of the environment variable with the same name. */ static bool find_and_merge_options (int fd, off_t file_offset, const char *prefix, - struct cl_decoded_option *decoded_cl_options, - unsigned int decoded_cl_options_count, - struct cl_decoded_option **opts, - unsigned int *opt_count, const char *collect_gcc) + vec<cl_decoded_option> decoded_cl_options, + vec<cl_decoded_option> *opts, const char *collect_gcc) { off_t offset, length; char *data; char *fopts; const char *errmsg; int err; - struct cl_decoded_option *fdecoded_options = *opts; - unsigned int fdecoded_options_count = *opt_count; + vec<cl_decoded_option> fdecoded_options; simple_object_read *sobj; sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO", @@ -1120,24 +1129,19 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix, data = (char *)xmalloc (length); read (fd, data, length); fopts = data; + bool first = true; do { - struct cl_decoded_option *f2decoded_options; - unsigned int f2decoded_options_count; - get_options_from_collect_gcc_options (collect_gcc, fopts, - &f2decoded_options, - &f2decoded_options_count); - if (!fdecoded_options) - { - fdecoded_options = f2decoded_options; - fdecoded_options_count = f2decoded_options_count; - } + vec<cl_decoded_option> f2decoded_options + = get_options_from_collect_gcc_options (collect_gcc, fopts); + if (first) + { + fdecoded_options = f2decoded_options; + first = false; + } else - merge_and_complain (&fdecoded_options, - &fdecoded_options_count, - f2decoded_options, f2decoded_options_count, - decoded_cl_options, - decoded_cl_options_count); + merge_and_complain (fdecoded_options, f2decoded_options, + decoded_cl_options); fopts += strlen (fopts) + 1; } @@ -1146,7 +1150,6 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix, free (data); simple_object_release_read (sobj); *opts = fdecoded_options; - *opt_count = fdecoded_options_count; return true; } @@ -1355,6 +1358,23 @@ jobserver_active_p (void) return JS_PREFIX "cannot access %<" JS_NEEDLE "%> file descriptors"; } +/* Print link to -flto documentation with a hint message. */ + +void +print_lto_docs_link () +{ + const char *url = get_option_url (NULL, OPT_flto); + + pretty_printer pp; + pp.url_format = URL_FORMAT_DEFAULT; + pp_string (&pp, "see the "); + pp_begin_url (&pp, url); + pp_string (&pp, "%<-flto%> option documentation"); + pp_end_url (&pp); + pp_string (&pp, " for more information"); + inform (UNKNOWN_LOCATION, pp_formatted_text (&pp)); +} + /* Test that a make command is present and working, return true if so. */ static bool @@ -1389,14 +1409,13 @@ run_gcc (unsigned argc, char *argv[]) char *collect_gcc_options; int parallel = 0; int jobserver = 0; + bool jobserver_requested = false; int auto_parallel = 0; bool no_partition = false; - struct cl_decoded_option *fdecoded_options = NULL; - struct cl_decoded_option *offload_fdecoded_options = NULL; - unsigned int fdecoded_options_count = 0; - unsigned int offload_fdecoded_options_count = 0; - struct cl_decoded_option *decoded_options; - unsigned int decoded_options_count; + const char *jobserver_error = NULL; + vec<cl_decoded_option> fdecoded_options; + fdecoded_options.create (16); + vec<cl_decoded_option> offload_fdecoded_options = vNULL; struct obstack argv_obstack; int new_head_argc; bool have_lto = false; @@ -1438,9 +1457,8 @@ run_gcc (unsigned argc, char *argv[]) NULL); } - get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options, - &decoded_options, - &decoded_options_count); + vec<cl_decoded_option> decoded_options + = get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options); /* Allocate array for input object files with LTO IL, and for possible preceding arguments. */ @@ -1489,8 +1507,7 @@ run_gcc (unsigned argc, char *argv[]) } if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX, - decoded_options, decoded_options_count, - &fdecoded_options, &fdecoded_options_count, + decoded_options, &fdecoded_options, collect_gcc)) { have_lto = true; @@ -1505,14 +1522,13 @@ run_gcc (unsigned argc, char *argv[]) obstack_ptr_grow (&argv_obstack, "-xlto"); obstack_ptr_grow (&argv_obstack, "-c"); - append_compiler_options (&argv_obstack, fdecoded_options, - fdecoded_options_count); - append_linker_options (&argv_obstack, decoded_options, decoded_options_count); + append_compiler_options (&argv_obstack, fdecoded_options); + append_linker_options (&argv_obstack, decoded_options); /* Scan linker driver arguments for things that are of relevance to us. */ - for (j = 1; j < decoded_options_count; ++j) + for (j = 1; j < decoded_options.length (); ++j) { - struct cl_decoded_option *option = &decoded_options[j]; + cl_decoded_option *option = &decoded_options[j]; switch (option->opt_index) { case OPT_o: @@ -1537,6 +1553,37 @@ run_gcc (unsigned argc, char *argv[]) break; case OPT_flto_: + /* Merge linker -flto= option with what we have in IL files. */ + merge_flto_options (fdecoded_options, option); + if (strcmp (option->arg, "jobserver") == 0) + jobserver_requested = true; + break; + + case OPT_flinker_output_: + linker_output_rel = !strcmp (option->arg, "rel"); + break; + + case OPT_g: + /* Recognize -g0. */ + skip_debug = option->arg && !strcmp (option->arg, "0"); + break; + + case OPT_dumpdir: + incoming_dumppfx = dumppfx = option->arg; + break; + + default: + break; + } + } + + /* Process LTO-related options on merged options. */ + for (j = 1; j < fdecoded_options.length (); ++j) + { + cl_decoded_option *option = &fdecoded_options[j]; + switch (option->opt_index) + { + case OPT_flto_: if (strcmp (option->arg, "jobserver") == 0) { parallel = 1; @@ -1558,22 +1605,6 @@ run_gcc (unsigned argc, char *argv[]) case OPT_flto: lto_mode = LTO_MODE_WHOPR; break; - - case OPT_flinker_output_: - linker_output_rel = !strcmp (option->arg, "rel"); - break; - - case OPT_g: - /* Recognize -g0. */ - skip_debug = option->arg && !strcmp (option->arg, "0"); - break; - - case OPT_dumpdir: - incoming_dumppfx = dumppfx = option->arg; - break; - - default: - break; } } @@ -1595,15 +1626,15 @@ run_gcc (unsigned argc, char *argv[]) { lto_mode = LTO_MODE_LTO; jobserver = 0; + jobserver_requested = false; auto_parallel = 0; parallel = 0; } else { - const char *jobserver_error = jobserver_active_p (); + jobserver_error = jobserver_active_p (); if (jobserver && jobserver_error != NULL) { - warning (0, jobserver_error); /* Fall back to auto parallelism. */ jobserver = 0; auto_parallel = 1; @@ -1731,9 +1762,7 @@ cont1: fatal_error (input_location, "cannot open %s: %m", filename); if (!find_and_merge_options (fd, file_offset, OFFLOAD_SECTION_NAME_PREFIX, - decoded_options, decoded_options_count, - &offload_fdecoded_options, - &offload_fdecoded_options_count, + decoded_options, &offload_fdecoded_options, collect_gcc)) fatal_error (input_location, "cannot read %s: %m", filename); close (fd); @@ -1742,10 +1771,7 @@ cont1: } compile_images_for_offload_targets (num_offload_files, offload_argv, - offload_fdecoded_options, - offload_fdecoded_options_count, - decoded_options, - decoded_options_count); + offload_fdecoded_options, decoded_options); free_array_of_ptrs ((void **) offload_argv, num_offload_files); @@ -1923,6 +1949,20 @@ cont: maybe_unlink (ltrans_output_file); ltrans_output_file = NULL; + if (nr > 1) + { + if (jobserver_requested && jobserver_error != NULL) + { + warning (0, jobserver_error); + print_lto_docs_link (); + } + else if (parallel == 0) + { + warning (0, "using serial compilation of %d LTRANS jobs", nr); + print_lto_docs_link (); + } + } + if (parallel) { makefile = make_temp_file (".mk"); diff --git a/gcc/match.pd b/gcc/match.pd index 19f4a78..cdb8763 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4764,6 +4764,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (cmp:c (bit_xor:c @0 @1) @0) (cmp @1 { build_zero_cst (TREE_TYPE (@1)); })) +#if GIMPLE + /* (X & Y) == X becomes (X & ~Y) == 0. */ + (simplify + (cmp:c (bit_and:c @0 @1) @0) + (cmp (bit_and @0 (bit_not! @1)) { build_zero_cst (TREE_TYPE (@0)); })) + + /* (X | Y) == Y becomes (X & ~Y) == 0. */ + (simplify + (cmp:c (bit_ior:c @0 @1) @1) + (cmp (bit_and @0 (bit_not! @1)) { build_zero_cst (TREE_TYPE (@0)); })) +#endif + /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2). */ (simplify (cmp (convert?@3 (bit_xor @0 INTEGER_CST@1)) INTEGER_CST@2) diff --git a/gcc/omp-low.c b/gcc/omp-low.c index c0ce1a4..cadca7e 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -2460,7 +2460,7 @@ finish_taskreg_scan (omp_context *ctx) TYPE_FIELDS (ctx->record_type) = field; if (ctx->srecord_type) { - field = lookup_sfield (OMP_CLAUSE_DECL (detach_clause), ctx); + field = lookup_sfield (OMP_CLAUSE_DECL (c), ctx); p = &TYPE_FIELDS (ctx->srecord_type); while (*p) if (*p == field) @@ -3243,9 +3243,13 @@ get_option_html_page (int option_index) const cl_option *cl_opt = &cl_options[option_index]; /* Analyzer options are on their own page. */ - if (strstr(cl_opt->opt_text, "analyzer-")) + if (strstr (cl_opt->opt_text, "analyzer-")) return "gcc/Static-Analyzer-Options.html"; + /* Handle -flto= option. */ + if (strstr (cl_opt->opt_text, "flto")) + return "gcc/Optimize-Options.html"; + #ifdef CL_Fortran if ((cl_opt->flags & CL_Fortran) != 0 /* If it is option common to both C/C++ and Fortran, it is documented diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index 6c78000..cc54ad4 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,7 @@ +2021-05-11 Joseph Myers <joseph@codesourcery.com> + + * ja.po: Update. + 2021-04-29 Joseph Myers <joseph@codesourcery.com> * sv.po: Update. diff --git a/gcc/po/ja.po b/gcc/po/ja.po index 049450e..4199919 100644 --- a/gcc/po/ja.po +++ b/gcc/po/ja.po @@ -19,10 +19,10 @@ # Hiroshi Takekawa <sian@big.or.jp>, <sian.ht@gmail.com>, 2020, 2021 msgid "" msgstr "" -"Project-Id-Version: gcc 11.1-b20210207\n" +"Project-Id-Version: gcc 11.1.0\n" "Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n" "POT-Creation-Date: 2021-04-20 18:19+0000\n" -"PO-Revision-Date: 2021-02-10 19:45+0900\n" +"PO-Revision-Date: 2021-05-11 22:47+0900\n" "Last-Translator: Hiroshi Takekawa <sian@big.or.jp>\n" "Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n" "Language: ja\n" @@ -512,10 +512,6 @@ msgid "" " 'none' means revert to the default behavior of\n" " guessing the language based on the file's extension.\n" msgstr "" -" -x <language> これ以降入力するファイルの言語を指定する。\n" -" 指定可能な言語は: c c++ assembler none\n" -" 'none' が指定されるとデフォルトのふるまいである\n" -" 拡張子から言語を推測する。\n" #: gcc.c:3798 #, c-format @@ -908,14 +904,14 @@ msgid " -p, --preserve-paths Preserve all pathname components\n" msgstr " -p, --preserve-paths すべてのパス名要素を保護する\n" #: gcov.c:944 -#, fuzzy, c-format +#, c-format msgid " -q, --use-hotness-colors Emit perf-like colored output for hot lines\n" -msgstr " -n, --no-output 出力ファイルを作成しない\n" +msgstr " -q, --use-hotness-colors perf のように hot line に色をつける\n" #: gcov.c:945 -#, fuzzy, c-format +#, c-format msgid " -r, --relative-only Only show data for relative sources\n" -msgstr " -a, --all-blocks 各基本ブロックに関する情報を表示する\n" +msgstr " -r, --relative-only 相対ソースのデータのみ表示する\n" #: gcov.c:946 #, c-format @@ -1498,9 +1494,8 @@ msgid "function not considered for inlining" msgstr "inline に出来ると見なされていない関数です" #: cif-code.def:43 -#, fuzzy msgid "caller is not optimized" -msgstr "%qE は初期化されていません" +msgstr "caller は最適化されていません" #: cif-code.def:47 msgid "function body not available" @@ -1596,9 +1591,8 @@ msgid "callee refers to comdat-local symbols" msgstr "" #: cif-code.def:134 -#, fuzzy msgid "sanitizer function attribute mismatch" -msgstr "関数属性が合いません" +msgstr "sanitizer関数属性が合いません" #: cif-code.def:139 msgid "function has external linkage when the user requests only inlining static for live patching" @@ -1993,14 +1987,12 @@ msgid "invalid address mode" msgstr "無効なアドレスモードです" #: config/aarch64/aarch64.c:25211 config/arm/arm.c:33660 -#, fuzzy msgid "invalid conversion from type %<bfloat16_t%>" -msgstr "%<__fpreg%> からの無効な変換です" +msgstr "%<bfloat16_t%> からの無効な変換です" #: config/aarch64/aarch64.c:25213 config/arm/arm.c:33662 -#, fuzzy msgid "invalid conversion to type %<bfloat16_t%>" -msgstr "無効なバージョン番号形式" +msgstr "%<bfloat16_t%> への無効な変換です" #: config/aarch64/aarch64.c:25228 config/aarch64/aarch64.c:25244 #: config/arm/arm.c:33677 config/arm/arm.c:33693 @@ -2008,9 +2000,8 @@ msgid "operation not permitted on type %<bfloat16_t%>" msgstr "" #: config/aarch64/aarch64.c:25252 -#, fuzzy msgid "cannot combine GNU and SVE vectors in a binary operation" -msgstr "二進演算内で無効な被演算子です" +msgstr "GNU と SVE ベクタの二項演算はできません" #: config/alpha/alpha.c:5076 config/i386/i386.c:13227 #: config/rs6000/rs6000.c:14147 config/sparc/sparc.c:9323 @@ -2233,9 +2224,8 @@ msgid "operands to %T/%t must be reg + const_int:" msgstr "出力被演算子 %d は %<&%> 制約を使用しなければいけません" #: config/avr/avr.c:2863 config/avr/avr.c:2930 -#, fuzzy msgid "bad address, not an I/O address:" -msgstr "誤ったアドレスです。(reg+disp) ではありません:" +msgstr "誤ったアドレスです。I/O アドレスではありません:" #: config/avr/avr.c:2872 msgid "bad address, not a constant:" @@ -2304,9 +2294,8 @@ msgid "structure field" msgstr "構造体フィールド" #: config/avr/avr.c:10039 -#, fuzzy msgid "return type of function" -msgstr "`%s' の宣言は関数の配列" +msgstr "関数の戻り値の型" #: config/avr/avr.c:10044 msgid "pointer" @@ -2567,9 +2556,9 @@ msgid "operand %%xn code invalid for QImode" msgstr "被演算子は条件コードではありません。無効な被演算子コード 'Y' です" #: config/gcn/gcn.c:6171 -#, fuzzy, c-format +#, c-format msgid "invalid fp constant" -msgstr "無効な命令:" +msgstr "無効な浮動小数点定数です" #: config/h8300/h8300.c:1565 config/h8300/h8300.c:1573 #: config/h8300/h8300.c:1581 config/h8300/h8300.c:1589 @@ -2584,9 +2573,9 @@ msgid "invalid UNSPEC as operand" msgstr "被演算子として無効な UNSPEC です" #: config/i386/i386.c:12591 -#, fuzzy, c-format +#, c-format msgid "invalid use of register '%s'" -msgstr "%<restrict%> の誤った使用法です" +msgstr "'%s' の誤った用法です" #: config/i386/i386.c:12596 #, fuzzy, c-format @@ -2673,9 +2662,9 @@ msgid "unknown insn mode" msgstr "不明な命令モード" #: config/i386/djgpp.h:143 -#, fuzzy, c-format +#, c-format msgid "-f%s ignored (not supported for DJGPP)\n" -msgstr "Unicos/Mk 用としては -f%s は無視されました (サポートされていません)" +msgstr "-f%s は (DJGPP ではサポートされていないので) 無視されました\n" #: config/ia64/ia64.c:5459 #, c-format @@ -2874,14 +2863,14 @@ msgid "invalid zero extract" msgstr "%<restrict%> の誤った使用法です" #: config/or1k/or1k.c:1116 config/or1k/or1k.c:1124 -#, fuzzy, c-format +#, c-format msgid "invalid relocation" -msgstr "無効な %%d 被演算子です" +msgstr "無効な再配置です" #: config/or1k/or1k.c:1218 -#, fuzzy, c-format +#, c-format msgid "invalid %%H value" -msgstr "無効な %%J 値" +msgstr "無効な %%H 値" #: config/or1k/or1k.c:1231 config/xtensa/xtensa.c:2473 #, c-format @@ -2919,14 +2908,14 @@ msgid "unsupported operand %s for code '%c'" msgstr "コード '%c' に対する無効な被演算子です" #: config/pru/pru.c:1870 -#, fuzzy, c-format +#, c-format msgid "unexpected text address:" -msgstr "アドレス内の予期しない副作用" +msgstr "予期しないテキストアドレス:" #: config/pru/pru.c:1889 -#, fuzzy, c-format +#, c-format msgid "unsupported constant address:" -msgstr "サポートされていない組み合わせです: %s" +msgstr "サポートされていない定数アドレス:" #: config/pru/pru.c:1950 #, fuzzy, c-format @@ -2991,7 +2980,7 @@ msgid "Bad 128-bit move" msgstr "誤った 128 ビット move" #: config/rs6000/rs6000.c:13589 -#, fuzzy, c-format +#, c-format msgid "invalid %%A value" msgstr "無効な %%A 値" @@ -3001,7 +2990,7 @@ msgid "invalid %%D value" msgstr "無効な %%D 値です" #: config/rs6000/rs6000.c:13613 -#, fuzzy, c-format +#, c-format msgid "invalid %%e value" msgstr "無効な %%e 値" @@ -3051,7 +3040,7 @@ msgid "invalid %%q value" msgstr "無効な %%q 値です" #: config/rs6000/rs6000.c:13858 -#, fuzzy, c-format +#, c-format msgid "invalid %%t value" msgstr "無効な %%t 値" @@ -3081,9 +3070,9 @@ msgid "invalid %%x value" msgstr "無効な %%x 値です" #: config/rs6000/rs6000.c:14025 -#, fuzzy, c-format +#, c-format msgid "invalid %%z value" -msgstr "無効な %%J 値" +msgstr "無効な %%z 値" #: config/rs6000/rs6000.c:14094 #, c-format @@ -3114,14 +3103,12 @@ msgid "Bad GPR fusion" msgstr "" #: config/rs6000/rs6000.c:27776 -#, fuzzy msgid "invalid conversion from type %<__vector_quad%>" -msgstr "%<__fpreg%> からの無効な変換です" +msgstr "%<__vector_quad%> からの無効な変換です" #: config/rs6000/rs6000.c:27778 -#, fuzzy msgid "invalid conversion to type %<__vector_quad%>" -msgstr "無効なバージョン番号形式" +msgstr "%<__vector_quad%> への無効な変換です" #: config/rs6000/rs6000.c:27780 #, fuzzy @@ -58665,8 +58652,9 @@ msgstr "クラス名が予期されます" #: d/dmd/dsymbolsem.c:1372 #, fuzzy, gcc-internal-format +#| msgid "unexpected text address:" msgid "function name expected for start address" -msgstr "アドレス内の予期しない副作用" +msgstr "予期しないテキストアドレス:" #: d/dmd/dsymbolsem.c:1387 #, gcc-internal-format, gfc-internal-format diff --git a/gcc/regcprop.c b/gcc/regcprop.c index 02753a1..7c271e2 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -358,34 +358,26 @@ copy_value (rtx dest, rtx src, struct value_data *vd) else if (sn > hard_regno_nregs (sr, vd->e[sr].mode)) return; - /* It is not safe to link DEST into the chain if SRC was defined in some - narrower mode M and if M is also narrower than the mode of the first - register in the chain. For example: - (set (reg:DI r1) (reg:DI r0)) - (set (reg:HI r2) (reg:HI r1)) - (set (reg:SI r3) (reg:SI r2)) //Should be a new chain start at r3 - (set (reg:SI r4) (reg:SI r1)) - (set (reg:SI r5) (reg:SI r4)) - - the upper part of r3 is undefined. If we added it to the chain, - it may be used to replace r5, which has defined upper bits. - See PR98694 for details. - - [A] partial_subreg_p (vd->e[sr].mode, GET_MODE (src)) - [B] partial_subreg_p (vd->e[sr].mode, vd->e[vd->e[sr].oldest_regno].mode) - Condition B is added to to catch optimization opportunities of - - (set (reg:HI R1) (reg:HI R0)) - (set (reg:SI R2) (reg:SI R1)) // [A] - (set (reg:DI R3) (reg:DI R2)) // [A] - (set (reg:SI R4) (reg:SI R[0-3])) - (set (reg:HI R5) (reg:HI R[0-4])) - - in which all registers have only 16 defined bits. */ - else if (partial_subreg_p (vd->e[sr].mode, GET_MODE (src)) - && partial_subreg_p (vd->e[sr].mode, - vd->e[vd->e[sr].oldest_regno].mode)) - return; + /* If a narrower value is copied using wider mode, the upper bits + are undefined (could be e.g. a former paradoxical subreg). Signal + in that case we've only copied value using the narrower mode. + Consider: + (set (reg:DI r14) (mem:DI ...)) + (set (reg:QI si) (reg:QI r14)) + (set (reg:DI bp) (reg:DI r14)) + (set (reg:DI r14) (const_int ...)) + (set (reg:DI dx) (reg:DI si)) + (set (reg:DI si) (const_int ...)) + (set (reg:DI dx) (reg:DI bp)) + The last set is not redundant, while the low 8 bits of dx are already + equal to low 8 bits of bp, the other bits are undefined. */ + else if (partial_subreg_p (vd->e[sr].mode, GET_MODE (src))) + { + if (!REG_CAN_CHANGE_MODE_P (sr, GET_MODE (src), vd->e[sr].mode) + || !REG_CAN_CHANGE_MODE_P (dr, vd->e[sr].mode, GET_MODE (dest))) + return; + set_value_regno (dr, vd->e[sr].mode, vd); + } /* Link DR at the end of the value chain used by SR. */ diff --git a/gcc/reorg.c b/gcc/reorg.c index 4595f9a..7f06a6f 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -2375,6 +2375,16 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition, if (! insn_references_resource_p (trial, &set, true) && ! insn_sets_resource_p (trial, filter_flags ? &fset : &set, true) && ! insn_sets_resource_p (trial, &needed, true) + /* If we're handling sets to the flags register specially, we + only allow an insn into a delay-slot, if it either: + - doesn't set the flags register, + - the "set" of the flags register isn't used (clobbered), + - insns between the delay-slot insn and the trial-insn + as accounted in "set", have not affected the flags register. */ + && (! filter_flags + || ! insn_sets_resource_p (trial, &flags_res, true) + || find_regno_note (trial, REG_UNUSED, targetm.flags_regnum) + || ! TEST_HARD_REG_BIT (set.regs, targetm.flags_regnum)) && ! can_throw_internal (trial)) { rtx_insn *prior_insn; @@ -158,10 +158,13 @@ static size_t rtvec_alloc_sizes; Store the length, and initialize all elements to zero. */ rtvec -rtvec_alloc (int n) +rtvec_alloc (size_t n) { rtvec rt; + /* rtvec_def.num_elem is an int. */ + gcc_assert (n < INT_MAX); + rt = ggc_alloc_rtvec_sized (n); /* Clear out the vector. */ memset (&rt->elem[0], 0, n * sizeof (rtx)); @@ -2976,7 +2976,7 @@ extern rtx rtx_alloc_stat_v (RTX_CODE MEM_STAT_DECL, int); (sizeof (struct hwivec_def) \ + ((NWORDS)-1) * sizeof (HOST_WIDE_INT))) \ -extern rtvec rtvec_alloc (int); +extern rtvec rtvec_alloc (size_t); extern rtvec shallow_copy_rtvec (rtvec); extern bool shared_const_p (const_rtx); extern rtx copy_rtx (rtx); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 2e0fdb7..1947ef2 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1001,6 +1001,13 @@ default_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs) { gcc_assert (!hard_reg_set_empty_p (need_zeroed_hardregs)); + HARD_REG_SET failed; + CLEAR_HARD_REG_SET (failed); + bool progress = false; + + /* First, try to zero each register in need_zeroed_hardregs by + loading a zero into it, taking note of any failures in + FAILED. */ for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno)) { @@ -1010,16 +1017,88 @@ default_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs) rtx_insn *insn = emit_move_insn (regno_reg_rtx[regno], zero); if (!valid_insn_p (insn)) { - static bool issued_error; - if (!issued_error) - { - issued_error = true; - sorry ("%qs not supported on this target", - "-fzero-call-used-regs"); - } + SET_HARD_REG_BIT (failed, regno); delete_insns_since (last_insn); } + else + progress = true; } + + /* Now retry with copies from zeroed registers, as long as we've + made some PROGRESS, and registers remain to be zeroed in + FAILED. */ + while (progress && !hard_reg_set_empty_p (failed)) + { + HARD_REG_SET retrying = failed; + + CLEAR_HARD_REG_SET (failed); + progress = false; + + for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (TEST_HARD_REG_BIT (retrying, regno)) + { + machine_mode mode = GET_MODE (regno_reg_rtx[regno]); + bool success = false; + /* Look for a source. */ + for (unsigned int src = 0; src < FIRST_PSEUDO_REGISTER; src++) + { + /* If SRC hasn't been zeroed (yet?), skip it. */ + if (! TEST_HARD_REG_BIT (need_zeroed_hardregs, src)) + continue; + if (TEST_HARD_REG_BIT (retrying, src)) + continue; + + /* Check that SRC can hold MODE, and that any other + registers needed to hold MODE in SRC have also been + zeroed. */ + if (!targetm.hard_regno_mode_ok (src, mode)) + continue; + unsigned n = targetm.hard_regno_nregs (src, mode); + bool ok = true; + for (unsigned i = 1; ok && i < n; i++) + ok = (TEST_HARD_REG_BIT (need_zeroed_hardregs, src + i) + && !TEST_HARD_REG_BIT (retrying, src + i)); + if (!ok) + continue; + + /* SRC is usable, try to copy from it. */ + rtx_insn *last_insn = get_last_insn (); + rtx zsrc = gen_rtx_REG (mode, src); + rtx_insn *insn = emit_move_insn (regno_reg_rtx[regno], zsrc); + if (!valid_insn_p (insn)) + /* It didn't work, remove any inserts. We'll look + for another SRC. */ + delete_insns_since (last_insn); + else + { + /* We're done for REGNO. */ + success = true; + break; + } + } + + /* If nothing worked for REGNO this round, marked it to be + retried if we get another round. */ + if (!success) + SET_HARD_REG_BIT (failed, regno); + else + /* Take note so as to enable another round if needed. */ + progress = true; + } + } + + /* If any register remained, report it. */ + if (!progress) + { + static bool issued_error; + if (!issued_error) + { + issued_error = true; + sorry ("%qs not supported on this target", + "-fzero-call-used-regs"); + } + } + return need_zeroed_hardregs; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 75e235b..936f37a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,322 @@ +2021-05-16 David Edelsohn <dje.gcc@gmail.com> + + * g++.dg/ext/attrib63.C: Add -Wno-psabi option. + +2021-05-16 David Edelsohn <dje.gcc@gmail.com> + + * g++.dg/warn/uninit-pr93100.C: Require fsantize support. + +2021-05-16 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.target/arm/unsigned-float.c: Remove arm_fp_ok, adjust + dg-options. + +2021-05-15 Bill Schmidt <wschmidt@linux.ibm.com> + + * gcc.target/powerpc/rop-1.c: New. + * gcc.target/powerpc/rop-2.c: New. + * gcc.target/powerpc/rop-3.c: New. + * gcc.target/powerpc/rop-4.c: New. + * gcc.target/powerpc/rop-5.c: New. + +2021-05-15 Martin Jambor <mjambor@suse.cz> + + Revert: + 2021-05-15 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/100453 + * gcc.dg/tree-ssa/pr100453.c: New test. + +2021-05-15 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/100342 + * gcc.target/i386/pr100342.c: New test. + +2021-05-14 Tobias Burnus <tobias@codesourcery.com> + + * gfortran.dg/gomp/parallel-master-1.f90: New test. + * gfortran.dg/gomp/parallel-master-2.f90: New test. + +2021-05-14 Tobias Burnus <tobias@codesourcery.com> + + * gfortran.dg/gomp/implicit-save.f90: New test. + +2021-05-14 Jakub Jelinek <jakub@redhat.com> + + PR c++/95226 + * g++.dg/cpp1y/pr95226.C: New test. + +2021-05-14 Jakub Jelinek <jakub@redhat.com> + + PR c++/94616 + * g++.dg/cpp0x/pr94616.C: New test. + +2021-05-14 Jakub Jelinek <jakub@redhat.com> + + PR c++/90019 + * g++.dg/cpp0x/sfinae68.C: New test. + +2021-05-14 Jakub Jelinek <jakub@redhat.com> + + * g++.dg/cpp1y/pr88872.C: New test. + +2021-05-14 Michael de Lang <kingoipo@gmail.com> + + * g++.dg/tsan/pthread_cond_clockwait.C: New test. + +2021-05-14 Marek Polacek <polacek@redhat.com> + Jason Merrill <jason@redhat.com> + + PR c++/99032 + * g++.dg/cpp0x/friend7.C: New test. + * g++.dg/cpp0x/gen-attrs-4.C: Add dg-error. + * g++.dg/cpp0x/gen-attrs-39-1.C: Likewise. + * g++.dg/cpp0x/gen-attrs-74.C: New test. + * g++.dg/ext/attrib63.C: New test. + +2021-05-13 Martin Sebor <msebor@redhat.com> + + PR tree-optimization/93100 + PR middle-end/98583 + * g++.dg/warn/uninit-pr93100.C: New test. + * gcc.dg/uninit-pr93100.c: New test. + * gcc.dg/uninit-pr98583.c: New test. + +2021-05-13 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/100453 + * gcc.dg/tree-ssa/pr100453.c: New test. + +2021-05-13 Martin Sebor <msebor@redhat.com> + + * g++.dg/pr100574.C: Use size_t as operator new argument type. + +2021-05-13 Martin Liska <mliska@suse.cz> + + PR middle-end/100504 + * gcc.target/i386/pr100504.c: New test. + +2021-05-13 Martin Sebor <msebor@redhat.com> + + PR c/100550 + * gcc.dg/Wvla-parameter-9.c: New test. + +2021-05-13 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/99928 + * c-c++-common/gomp/pr99928-1.c: New test. + * c-c++-common/gomp/pr99928-2.c: New test. + * c-c++-common/gomp/pr99928-3.c: New test. + * c-c++-common/gomp/pr99928-4.c: New test. + * c-c++-common/gomp/pr99928-5.c: New test. + * c-c++-common/gomp/pr99928-6.c: New test. + * c-c++-common/gomp/pr99928-7.c: New test. + * c-c++-common/gomp/pr99928-8.c: New test. + * c-c++-common/gomp/pr99928-9.c: New test. + * c-c++-common/gomp/pr99928-10.c: New test. + * c-c++-common/gomp/pr99928-11.c: New test. + +2021-05-13 Richard Earnshaw <rearnsha@arm.com> + + PR target/100563 + * gcc.dg/pr100563.c (dg-options): Add -wno-pointer-to-int-cast. + +2021-05-13 Richard Earnshaw <rearnsha@arm.com> + + * gcc.dg/pr100563.c: New test. + +2021-05-13 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/98856 + * gcc.target/i386/sse2-psraq-1.c: New test. + * gcc.target/i386/sse4_2-psraq-1.c: New test. + * gcc.target/i386/avx-psraq-1.c: New test. + * gcc.target/i386/avx2-psraq-1.c: New test. + * gcc.target/i386/avx-pr82370.c: Adjust expected number of vpsrad + instructions. + * gcc.target/i386/avx2-pr82370.c: Likewise. + * gcc.target/i386/avx512f-pr82370.c: Likewise. + * gcc.target/i386/avx512bw-pr82370.c: Likewise. + * gcc.dg/torture/vshuf-4.inc: Add two further permutations. + * gcc.dg/torture/vshuf-8.inc: Likewise. + +2021-05-13 Uroš Bizjak <ubizjak@gmail.com> + + PR target/100581 + * g++.target/i386/pr100581.C: New test. + +2021-05-13 Eric Botcazou <ebotcazou@adacore.com> + + PR testsuite/100569 + * gnat.dg/lto21.adb: Prune new LTO warning. + +2021-05-13 Martin Liska <mliska@suse.cz> + + PR testsuite/100569 + * gcc.dg/atomic/c11-atomic-exec-2.c: Prune new LTO warning. + * gcc.dg/torture/pr94947-1.c: Likewise. + +2021-05-13 liuhongt <hongtao.liu@intel.com> + + * gcc.target/i386/avx-pr94680.c: Fix typo in testcase. + +2021-05-13 liuhongt <hongtao.liu@intel.com> + + PR target/94680 + * gcc.target/i386/avx-pr94680.c: New test. + * gcc.target/i386/avx512f-pr94680.c: New test. + * gcc.target/i386/sse2-pr94680.c: New test. + +2021-05-12 Martin Sebor <msebor@redhat.com> + + PR middle-end/100571 + * gcc.dg/Wstringop-overflow-67.c: New test. + +2021-05-12 Aldy Hernandez <aldyh@redhat.com> + + PR c/100521 + * gcc.dg/pr100521.c: New file. + +2021-05-12 Marek Polacek <polacek@redhat.com> + + * g++.dg/warn/Wint-in-bool-context-2.C: New test. + +2021-05-12 Marcel Vollweiler <marcel@codesourcery.com> + + * c-c++-common/gomp/map-6.c: New test. + * c-c++-common/gomp/map-7.c: New test. + +2021-05-12 Richard Biener <rguenther@suse.de> + + PR tree-optimization/100566 + * gcc.dg/torture/pr100566.c: New testcase. + +2021-05-12 Jakub Jelinek <jakub@redhat.com> + + PR preprocessor/100392 + * gcc.dg/cpp/pr100392.c: New test. + * gcc.dg/cpp/pr100392.h: New file. + +2021-05-12 Martin Liska <mliska@suse.cz> + + * lib/lto.exp: When running tests without jobserver, one can see + the following warning for tests that use 1to1 partitioning. + +2021-05-12 liuhongt <hongtao.liu@intel.com> + + PR target/99908 + * gcc.target/i386/avx2-pr99908.c: New test. + * gcc.target/i386/sse4_1-pr99908.c: New test. + +2021-05-12 Richard Biener <rguenther@suse.de> + + PR tree-optimization/100519 + * gcc.dg/torture/pr100519.c: New testcase. + +2021-05-12 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR debug/100515 + * gcc.dg/debug/dwarf2/pr100515.c: New testcase. + +2021-05-12 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/100508 + * gcc.dg/gomp/pr100508.c: New test. + +2021-05-12 Jakub Jelinek <jakub@redhat.com> + Marc Glisse <marc.glisse@inria.fr> + + PR tree-optimization/94589 + * gcc.dg/tree-ssa/pr94589-1.c: New test. + +2021-05-12 Uroš Bizjak <ubizjak@gmail.com> + + PR target/98218 + * g++.target/i386/pr98218-1.C: Ditto. + * gcc.target/i386/pr98218-4.c: New test. + * gcc.target/i386/pr98218-1.c: Correct PR number. + * gcc.target/i386/pr98218-1a.c: Ditto. + * gcc.target/i386/pr98218-2.c: Ditto. + * gcc.target/i386/pr98218-2a.c: Ditto. + * gcc.target/i386/pr98218-3.c: Ditto. + * gcc.target/i386/pr98218-3a.c: Ditto. + +2021-05-11 Joseph Myers <joseph@codesourcery.com> + + * gcc.dg/cpp/c11-elifdef-1.c, gcc.dg/cpp/c2x-elifdef-1.c, + gcc.dg/cpp/c2x-elifdef-2.c: New tests. + +2021-05-11 Joseph Myers <joseph@codesourcery.com> + + * g++.dg/cpp1y/digit-sep-paste.C, gcc.dg/c2x-digit-separators-3.c: + New tests. + +2021-05-11 Stefan Schulze Frielinghaus <stefansf@linux.ibm.com> + + * gcc.dg/guality/pr43077-1.c: Align types of output and input + operands by lifting immediates to type long. + +2021-05-11 Joseph Myers <joseph@codesourcery.com> + + * gcc.dg/c11-digit-separators-1.c, + gcc.dg/c2x-digit-separators-1.c, gcc.dg/c2x-digit-separators-2.c: + New tests. + +2021-05-11 Jason Merrill <jason@redhat.com> + + PR c++/100517 + * g++.dg/ext/vector41.C: New test. + +2021-05-11 Martin Liska <mliska@suse.cz> + + * gfortran.dg/goacc/pr78027.f90: Remove -Wno-hsa option. + * brig.dg/README: Removed. + * brig.dg/dg.exp: Removed. + * brig.dg/test/gimple/alloca.hsail: Removed. + * brig.dg/test/gimple/atomics.hsail: Removed. + * brig.dg/test/gimple/branches.hsail: Removed. + * brig.dg/test/gimple/fbarrier.hsail: Removed. + * brig.dg/test/gimple/function_calls.hsail: Removed. + * brig.dg/test/gimple/internal-casts.hsail: Removed. + * brig.dg/test/gimple/kernarg.hsail: Removed. + * brig.dg/test/gimple/mem.hsail: Removed. + * brig.dg/test/gimple/mulhi.hsail: Removed. + * brig.dg/test/gimple/packed.hsail: Removed. + * brig.dg/test/gimple/priv-array-offset-access.hsail: Removed. + * brig.dg/test/gimple/smoke_test.hsail: Removed. + * brig.dg/test/gimple/variables.hsail: Removed. + * brig.dg/test/gimple/vector.hsail: Removed. + * lib/brig-dg.exp: Removed. + * lib/brig.exp: Removed. + +2021-05-11 Alex Coplan <alex.coplan@arm.com> + + PR target/99725 + * gcc.target/arm/cmse/pr99725.c: New test. + +2021-05-11 Richard Sandiford <richard.sandiford@arm.com> + + * gcc.target/aarch64/fmul_lane_1.c: New test. + +2021-05-11 Richard Biener <rguenther@suse.de> + + PR middle-end/100509 + * gcc.dg/pr100509.c: New testcase. + +2021-05-11 Robin Dapp <rdapp@linux.ibm.com> + + * gcc.target/s390/risbg-ll-3.c: Change match pattern. + +2021-05-11 Patrick Palka <ppalka@redhat.com> + + PR c++/51577 + * g++.dg/lookup/operator-3.C: New test. + +2021-05-11 Patrick Palka <ppalka@redhat.com> + + PR c++/100138 + * g++.dg/cpp2a/concepts-ctad4.C: New test. + 2021-05-10 Eric Botcazou <ebotcazou@adacore.com> * gnat.dg/specs/opt5.ads: New test. diff --git a/gcc/testsuite/c-c++-common/gomp/map-6.c b/gcc/testsuite/c-c++-common/gomp/map-6.c new file mode 100644 index 0000000..6ee5971 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/map-6.c @@ -0,0 +1,135 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fdump-tree-original" } */ + +void +foo (void) +{ + /* Test to ensure that the close modifier is parsed and ignored in map clauses. */ + int a, b, b1, b2, b3, b4, b5, b6, b7; + + #pragma omp target map (a) + ; + + #pragma omp target map (to:a) + ; + + #pragma omp target map (a to: b) /* { dg-error "'#pragma omp target' with modifier other than 'always' or 'close'" } */ + ; + + #pragma omp target map (close, a to: b) /* { dg-error "'#pragma omp target' with modifier other than 'always' or 'close'" } */ + ; + + #pragma omp target map (close a) /* { dg-error "'close' undeclared" "" { target c } } */ + /* { dg-error "'close' has not been declared" "" { target c++ } .-1 } */ + /* { dg-error "expected '\\)' before 'a'" "" { target *-*-* } .-2 } */ + ; + + #pragma omp target map (always a) /* { dg-error "'always' undeclared" "" { target c } } */ + /* { dg-error "'always' has not been declared" "" { target c++ } .-1 } */ + /* { dg-error "expected '\\)' before 'a'" "" { target *-*-* } .-2 } */ + ; + + #pragma omp target map (close to:a) + ; + + #pragma omp target map (close, to:a) + ; + + #pragma omp target map (close delete:a) /* { dg-error "'#pragma omp target' with map-type other than 'to', 'from', 'tofrom' or 'alloc' on 'map' clause" } */ + ; + + #pragma omp target map (close always to:b1) + ; + + #pragma omp target map (close, always to:b2) + ; + + #pragma omp target map (close, always, to:b3) + ; + + #pragma omp target map (always close to:b4) + ; + + #pragma omp target map (always, close to:b5) + ; + + #pragma omp target map (always, close, to:b6) + ; + + #pragma omp target map (always, always, to:a) /* { dg-error "too many 'always' modifiers" } */ + ; + + #pragma omp target map (always always, to:a) /* { dg-error "too many 'always' modifiers" } */ + ; + + #pragma omp target map (always, always to:a) /* { dg-error "too many 'always' modifiers" } */ + ; + + #pragma omp target map (always always to:a) /* { dg-error "too many 'always' modifiers" } */ + ; + + #pragma omp target map (close, close, to:a) /* { dg-error "too many 'close' modifiers" } */ + ; + + #pragma omp target map (close close, to:a) /* { dg-error "too many 'close' modifiers" } */ + ; + + #pragma omp target map (close, close to:a) /* { dg-error "too many 'close' modifiers" } */ + ; + + #pragma omp target map (close close to:a) /* { dg-error "too many 'close' modifiers" } */ + ; + + #pragma omp target map (always to : a) map (close to : b) + ; + + int close = 0; + #pragma omp target map (close) + ; + + #pragma omp target map (close a) /* { dg-error "expected '\\)' before 'a'" } */ + ; + + int always = 0; + #pragma omp target map (always) + ; + + #pragma omp target map (always a) /* { dg-error "expected '\\)' before 'a'" } */ + ; + + #pragma omp target map (always, close) + ; + + #pragma omp target map (always, always) /* { dg-error "'always' appears more than once in map clauses" } */ + ; + + #pragma omp target map (always, always, close) /* { dg-error "'always' appears more than once in map clauses" } */ + ; + + #pragma omp target map (always, close, to: always, close, b7) + ; + + int to = 0; + #pragma omp target map (always, close, to) + ; + + #pragma omp target map (to, always, close) + { + to = always = close = 1; + } + if (to != 1 || always != 1 || close != 1) + __builtin_abort (); + ; +} + +/* { dg-final { scan-tree-dump-not "map\\(\[^\n\r)]*close\[^\n\r)]*to:" "original" } } */ + +/* { dg-final { scan-tree-dump-times "pragma omp target map\\(always,to:" 7 "original" } } */ + +/* { dg-final { scan-tree-dump "pragma omp target map\\(always,to:b1" "original" } } */ +/* { dg-final { scan-tree-dump "pragma omp target map\\(always,to:b2" "original" } } */ +/* { dg-final { scan-tree-dump "pragma omp target map\\(always,to:b3" "original" } } */ +/* { dg-final { scan-tree-dump "pragma omp target map\\(always,to:b4" "original" } } */ +/* { dg-final { scan-tree-dump "pragma omp target map\\(always,to:b5" "original" } } */ +/* { dg-final { scan-tree-dump "pragma omp target map\\(always,to:b6" "original" } } */ +/* { dg-final { scan-tree-dump "pragma omp target map\\(always,to:b7\\) map\\(always,to:close\\) map\\(always,to:always\\)" "original" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/map-7.c b/gcc/testsuite/c-c++-common/gomp/map-7.c new file mode 100644 index 0000000..3f1e972 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/map-7.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +void +foo (void) +{ + /* Test to ensure that the close modifier is parsed and ignored in map clauses. */ + + #define N 1024 + int always[N]; + int close; + + #pragma omp target map(always[:N]) + ; + + #pragma omp target map(close, always[:N]) + ; + + #pragma omp target map(always[:N], close) + ; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-1.c b/gcc/testsuite/c-c++-common/gomp/pr99928-1.c new file mode 100644 index 0000000..37181fd --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-1.c @@ -0,0 +1,206 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +int f00, f01, f02, f03, f04, f05, f06, f07, f08, f09; +int f12, f13, f14, f15, f16, f17, f18, f19; +int f20, f21, f22, f23, f24, f25, f26, f27, f28, f29; + +void +foo (void) +{ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*firstprivate\\(f00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f00\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f00\\)" "gimple" } } *//* FIXME. */ + #pragma omp distribute parallel for firstprivate (f00) + for (int i = 0; i < 64; i++) + f00++; + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*firstprivate\\(f01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f01\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f01\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f01\\)" "gimple" } } */ + #pragma omp distribute parallel for simd firstprivate (f01) + for (int i = 0; i < 64; i++) + f01++; + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*firstprivate\\(f02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f02\\)" "gimple" } } */ + #pragma omp distribute simd firstprivate (f02) + for (int i = 0; i < 64; i++) + f02++; +} + +void +bar (void) +{ + int f10 = 0, f11 = 0; + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*firstprivate\\(f03\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f03\\)" "gimple" } } */ + #pragma omp for simd firstprivate (f03) + for (int i = 0; i < 64; i++) + f03++; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(f04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(f04\\)" "gimple" } } */ + #pragma omp master taskloop firstprivate (f04) + for (int i = 0; i < 64; i++) + f04++; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(f05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(f05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f05\\)" "gimple" } } */ + #pragma omp master taskloop simd firstprivate (f05) + for (int i = 0; i < 64; i++) + f05++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f06\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f06\\)" "gimple" } } *//* FIXME. */ + #pragma omp parallel for firstprivate (f06) + for (int i = 0; i < 64; i++) + f06++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f07\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f07\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f07\\)" "gimple" } } */ + #pragma omp parallel for simd firstprivate (f07) + for (int i = 0; i < 64; i++) + f07++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f08\\)" "gimple" } } */ + #pragma omp parallel loop firstprivate (f08) + for (int i = 0; i < 64; i++) + f08++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f09\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(f09\\)" "gimple" } } */ + #pragma omp parallel master firstprivate (f09) + f09++; + /* { 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" } } */ + #pragma omp parallel master taskloop firstprivate (f10) + for (int i = 0; i < 64; i++) + f10++; + /* { 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" } } */ + #pragma omp parallel master taskloop simd firstprivate (f11) + for (int i = 0; i < 64; i++) + f11++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f12\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*firstprivate\\(f12\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp section \[^\n\r]*firstprivate\\(f12\\)" "gimple" } } */ + #pragma omp parallel sections firstprivate (f12) + { + f12++; + #pragma omp section + f12++; + } + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f13\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f13\\)" "gimple" } } */ + #pragma omp target parallel firstprivate (f13) + f13++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f14\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f14\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f14\\)" "gimple" } } *//* FIXME. */ + #pragma omp target parallel for firstprivate (f14) + for (int i = 0; i < 64; i++) + f14++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f15\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f15\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f15\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f15\\)" "gimple" } } */ + #pragma omp target parallel for simd firstprivate (f15) + for (int i = 0; i < 64; i++) + f15++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f16\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f16\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f16\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f16\\)" "gimple" } } */ + #pragma omp target parallel loop firstprivate (f16) + for (int i = 0; i < 64; i++) + f16++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f17\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f17\\)" "gimple" } } */ + #pragma omp target teams firstprivate (f17) + f17++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f18\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f18\\)" "gimple" } } *//* FIXME: This should be on distribute instead. */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f18\\)" "gimple" } } *//* FIXME. */ + #pragma omp target teams distribute firstprivate (f18) + for (int i = 0; i < 64; i++) + f18++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f19\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f19\\)" "gimple" } } *//* FIXME: This should be on distribute instead. */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f19\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f19\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f19\\)" "gimple" } } *//* FIXME. */ + #pragma omp target teams distribute parallel for firstprivate (f19) + for (int i = 0; i < 64; i++) + f19++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f20\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f20\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f20\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f20\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f20\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f20\\)" "gimple" } } */ + #pragma omp target teams distribute parallel for simd firstprivate (f20) + for (int i = 0; i < 64; i++) + f20++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f21\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f21\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f21\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f21\\)" "gimple" } } */ + #pragma omp target teams distribute simd firstprivate (f21) + for (int i = 0; i < 64; i++) + f21++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f22\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f22\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f22\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(f22\\)" "gimple" } } *//* NOTE: This is an implementation detail. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f22\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f22\\)" "gimple" } } */ + #pragma omp target teams loop firstprivate (f22) + for (int i = 0; i < 64; i++) + f22++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f23\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f23\\)" "gimple" } } */ + #pragma omp target simd firstprivate (f23) + for (int i = 0; i < 64; i++) + f23++; + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(f24\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f24\\)" "gimple" } } */ + #pragma omp taskloop simd firstprivate (f24) + for (int i = 0; i < 64; i++) + f24++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f25\\)" "gimple" } } *//* FIXME: This should be on distribute instead. */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f25\\)" "gimple" } } *//* FIXME. */ + #pragma omp teams distribute firstprivate (f25) + for (int i = 0; i < 64; i++) + f25++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f26\\)" "gimple" } } *//* FIXME: This should be on distribute instead. */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f26\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f26\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f26\\)" "gimple" } } *//* FIXME. */ + #pragma omp teams distribute parallel for firstprivate (f26) + for (int i = 0; i < 64; i++) + f26++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f27\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f27\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f27\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f27\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f27\\)" "gimple" } } */ + #pragma omp teams distribute parallel for simd firstprivate (f27) + for (int i = 0; i < 64; i++) + f27++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f28\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f28\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f28\\)" "gimple" } } */ + #pragma omp teams distribute simd firstprivate (f28) + for (int i = 0; i < 64; i++) + f28++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f29\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f29\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(f29\\)" "gimple" } } *//* NOTE: This is an implementation detail. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f29\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f29\\)" "gimple" } } */ + #pragma omp teams loop firstprivate (f29) + for (int i = 0; i < 64; i++) + f29++; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-10.c b/gcc/testsuite/c-c++-common/gomp/pr99928-10.c new file mode 100644 index 0000000..4acff45 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-10.c @@ -0,0 +1,231 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +int *r00, *r01, *r02, *r03, *r04, *r05; +int *r13, *r14, *r15, *r16, *r17, *r18, *r19; +int *r20, *r21, *r22, *r23, *r24; +int *baz (void); + +void +foo (void) +{ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r00 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r00 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r00 \\+ 4" "gimple" } } *//* FIXME. */ + #pragma omp distribute parallel for reduction(+:r00[1:2]) + for (int i = 0; i < 64; i++) + r00[1]++; + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r01 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r01 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r01 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r01 \\+ 4" "gimple" } } */ + #pragma omp distribute parallel for simd reduction(+:r01[1:3]) + for (int i = 0; i < 64; i++) + r01[1]++; + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r02 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r02 \\+ 4" "gimple" } } */ + #pragma omp distribute simd reduction(+:r02[1:4]) + for (int i = 0; i < 64; i++) + r02[1]++; +} + +void +bar (void) +{ + int *r06 = baz (), *r07 = baz (), *r08 = baz (), *r09 = baz (); + int *r10 = baz (), *r11 = baz (), *r12 = baz (); + int *r25 = baz (), *r26 = baz (), *r27 = baz (), *r28 = baz (), *r29 = baz (); + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r03 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r03 \\+ 4" "gimple" } } */ + #pragma omp for simd reduction(+:r03[1:5]) + for (int i = 0; i < 64; i++) + r03[1]++; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r04 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r04 \\+ 4" "gimple" } } */ + #pragma omp master taskloop reduction(+:r04[1:6]) + for (int i = 0; i < 64; i++) + r04[1]++; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r05 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r05 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r05 \\+ 4" "gimple" } } */ + #pragma omp master taskloop simd reduction(+:r05[1:7]) + for (int i = 0; i < 64; i++) + r05[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r06 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r06 \\+ 4" "gimple" } } *//* FIXME. */ + #pragma omp parallel for reduction(+:r06[1:8]) + for (int i = 0; i < 64; i++) + r06[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r07 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r07 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r07 \\+ 4" "gimple" } } */ + #pragma omp parallel for simd reduction(+:r07[1:9]) + for (int i = 0; i < 64; i++) + r07[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(r08\\)" "gimple" } } *//* FIXME: Should be shared, but firstprivate is an optimization. */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r08 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r08 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp parallel loop reduction(+:r08[1:10]) + for (int i = 0; i < 64; i++) + r08[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r09 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r09 \\+ 4" "gimple" } } */ + #pragma omp parallel master reduction(+:r09[1:11]) + r09[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(r10\\)" "gimple" } } *//* FIXME: Should be shared, but firstprivate is an optimization. */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r10 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r10 \\+ 4" "gimple" } } */ + #pragma omp parallel master taskloop reduction(+:r10[1:12]) + for (int i = 0; i < 64; i++) + r10[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(r11\\)" "gimple" } } *//* FIXME: Should be shared, but firstprivate is an optimization. */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r11 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r11 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r11 \\+ 4" "gimple" } } */ + #pragma omp parallel master taskloop simd reduction(+:r11[1:13]) + for (int i = 0; i < 64; i++) + r11[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r12 \\+ 4" "gimple" } } *//* FIXME: This should be on sections instead. */ + /* { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r12 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp section \[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r12 \\+ 4" "gimple" } } */ + #pragma omp parallel sections reduction(+:r12[1:14]) + { + r12[1]++; + #pragma omp section + r12[1]++; + } + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 60\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r13 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r13\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r13 \\+ 4" "gimple" } } */ + #pragma omp target parallel reduction(+:r13[1:15]) + r13[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 64\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r14 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r14" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r14 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r14 \\+ 4" "gimple" } } *//* FIXME. */ + #pragma omp target parallel for reduction(+:r14[1:16]) + for (int i = 0; i < 64; i++) + r14[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 68\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r15 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r15\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r15 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r15 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r15 \\+ 4" "gimple" } } */ + #pragma omp target parallel for simd reduction(+:r15[1:17]) + for (int i = 0; i < 64; i++) + r15[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 72\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r16 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r16\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(r16\\)" "gimple" } } *//* FIXME: Should be shared, but firstprivate is an optimization. */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r16 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r16 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp target parallel loop reduction(+:r16[1:18]) + for (int i = 0; i < 64; i++) + r16[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 76\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r17 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r17\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r17 \\+ 4" "gimple" } } */ + #pragma omp target teams reduction(+:r17[1:19]) + r17[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 80\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r18 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r18\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r18 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r18 \\+ 4" "gimple" } } */ + #pragma omp target teams distribute reduction(+:r18[1:20]) + for (int i = 0; i < 64; i++) + r18[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 84\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r19 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r19\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r19 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r19 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r19 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r19 \\+ 4" "gimple" } } *//* FIXME. */ + #pragma omp target teams distribute parallel for reduction(+:r19[1:21]) + for (int i = 0; i < 64; i++) + r19[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 88\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r20 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r20\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r20 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r20 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r20 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r20 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r20 \\+ 4" "gimple" } } */ + #pragma omp target teams distribute parallel for simd reduction(+:r20[1:22]) + for (int i = 0; i < 64; i++) + r20[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 92\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r21 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r21\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r21 \\+ 4" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r21 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r21 \\+ 4" "gimple" } } */ + #pragma omp target teams distribute simd reduction(+:r21[1:23]) + for (int i = 0; i < 64; i++) + r21[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 96\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r22 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r22\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(r22\\)" "gimple" } } *//* FIXME: Should be shared, but firstprivate is an optimization. */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r22 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(r22\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r22 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r22 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp target teams loop reduction(+:r22[1:24]) + for (int i = 0; i < 64; i++) + r22[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 100\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r23 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r23\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r23 \\+ 4" "gimple" } } */ + #pragma omp target simd reduction(+:r23[1:25]) + for (int i = 0; i < 64; i++) + r23[1]++; + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r24 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r24 \\+ 4" "gimple" } } */ + #pragma omp taskloop simd reduction(+:r24[1:26]) + for (int i = 0; i < 64; i++) + r24[1]++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r25 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r25 \\+ 4" "gimple" } } */ + #pragma omp teams distribute reduction(+:r25[1:27]) + for (int i = 0; i < 64; i++) + r25[1]++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r26 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r26 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r26 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r26 \\+ 4" "gimple" } } *//* FIXME. */ + #pragma omp teams distribute parallel for reduction(+:r26[1:28]) + for (int i = 0; i < 64; i++) + r26[1]++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r27 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r27 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r27 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r27 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r27 \\+ 4" "gimple" } } */ + #pragma omp teams distribute parallel for simd reduction(+:r27[1:29]) + for (int i = 0; i < 64; i++) + r27[1]++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r28 \\+ 4" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r28 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r28 \\+ 4" "gimple" } } */ + #pragma omp teams distribute simd reduction(+:r28[1:30]) + for (int i = 0; i < 64; i++) + r28[1]++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(r29\\)" "gimple" } } *//* FIXME: Should be shared, but firstprivate is an optimization. */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r29 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(r29\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r29 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r29 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp teams loop reduction(+:r29[1:31]) + for (int i = 0; i < 64; i++) + r29[1]++; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-11.c b/gcc/testsuite/c-c++-common/gomp/pr99928-11.c new file mode 100644 index 0000000..66c2feb --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-11.c @@ -0,0 +1,28 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +int r00, r01, r02; + +void +bar (void) +{ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*in_reduction\\(\\+:r00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*in_reduction\\(\\+:r00\\)" "gimple" } } */ + #pragma omp master taskloop in_reduction(+:r00) + for (int i = 0; i < 64; i++) + r00++; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*in_reduction\\(\\+:r01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*in_reduction\\(\\+:r01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*in_reduction\\(\\+:r01\\)" "gimple" } } */ + #pragma omp master taskloop simd in_reduction(+:r01) + for (int i = 0; i < 64; i++) + r01++; + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*in_reduction\\(\\+:r02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*in_reduction\\(\\+:r02\\)" "gimple" } } */ + #pragma omp taskloop simd in_reduction(+:r02) + for (int i = 0; i < 64; i++) + r02++; + /* FIXME: We don't support in_reduction clause on target yet, once we do, should + add testcase coverage for all combined/composite constructs with target as leaf construct. */ +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-2.c b/gcc/testsuite/c-c++-common/gomp/pr99928-2.c new file mode 100644 index 0000000..313374c --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-2.c @@ -0,0 +1,208 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +int l00, l01, l02, l03, l04, l05, l06, l07; +int l10, l11, l12, l13, l14, l15, l16, l17, l18; + +void +foo (void) +{ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l00\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l00\\)" "gimple" } } *//* FIXME. */ + #pragma omp distribute parallel for lastprivate (l00) + for (int i = 0; i < 64; i++) + l00 = i; + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } */ + #pragma omp distribute parallel for simd lastprivate (l01) + for (int i = 0; i < 64; i++) + l01 = i; + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l02\\)" "gimple" } } */ + #pragma omp distribute simd lastprivate (l02) + for (int i = 0; i < 64; i++) + l02 = i; +} + +void +bar (void) +{ + int j00, j01, j02, j03; + int l08 = 0, l09 = 0, l19 = 0, l20 = 0, l21 = 0, l22 = 0; + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } */ + #pragma omp for simd lastprivate (l03) + for (int i = 0; i < 64; i++) + l03 = i; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(l04\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } */ + #pragma omp master taskloop lastprivate (l04) + for (int i = 0; i < 64; i++) + l04 = i; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(l05\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l05\\)" "gimple" } } */ + #pragma omp master taskloop simd lastprivate (l05) + for (int i = 0; i < 64; i++) + l05 = i; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } *//* FIXME. */ + #pragma omp parallel for lastprivate (l06) + for (int i = 0; i < 64; i++) + l06 = i; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l07\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l07\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l07\\)" "gimple" } } */ + #pragma omp parallel for simd lastprivate (l07) + for (int i = 0; i < 64; i++) + l07 = i; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp parallel loop lastprivate (j00) + for (j00 = 0; j00 < 64; j00++) + ; + /* { 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" } } */ + #pragma omp parallel master taskloop lastprivate (l08) + for (int i = 0; i < 64; i++) + l08 = i; + /* { 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" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l09\\)" "gimple" } } */ + #pragma omp parallel master taskloop simd lastprivate (l09) + for (int i = 0; i < 64; i++) + l09 = i; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l10\\)" "gimple" } } *//* FIXME: This should be on sections instead. */ + /* { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*lastprivate\\(l10\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp section \[^\n\r]*lastprivate\\(l10\\)" "gimple" } } */ + #pragma omp parallel sections lastprivate (l10) + { + l10 = 1; + #pragma omp section + l10 = 2; + } + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l11" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l11\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l11\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l11\\)" "gimple" } } *//* FIXME. */ + #pragma omp target parallel for lastprivate (l11) + for (int i = 0; i < 64; i++) + l11 = i; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l12" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l12\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l12\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l12\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l12\\)" "gimple" } } */ + #pragma omp target parallel for simd lastprivate (l12) + for (int i = 0; i < 64; i++) + l12 = i; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j01" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j01\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j01\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(j01\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp target parallel loop lastprivate (j01) + for (j01 = 0; j01 < 64; j01++) + ; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l13" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l13\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l13\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l13\\)" "gimple" } } */ + #pragma omp target teams distribute lastprivate (l13) + for (int i = 0; i < 64; i++) + l13 = i; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l14" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l14\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l14\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l14\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l14\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l14\\)" "gimple" } } *//* FIXME. */ + #pragma omp target teams distribute parallel for lastprivate (l14) + for (int i = 0; i < 64; i++) + l14 = i; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l15" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l15\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l15\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l15\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l15\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l15\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l15\\)" "gimple" } } */ + #pragma omp target teams distribute parallel for simd lastprivate (l15) + for (int i = 0; i < 64; i++) + l15 = i; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l16" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l16\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l16\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l16\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l16\\)" "gimple" } } */ + #pragma omp target teams distribute simd lastprivate (l16) + for (int i = 0; i < 64; i++) + l16 = i; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j02" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j02\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j02\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j02\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j02\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(j02\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp target teams loop lastprivate (j02) + for (j02 = 0; j02 < 64; j02++) + ; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l17" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l17\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l17\\)" "gimple" } } */ + #pragma omp target simd lastprivate (l17) + for (int i = 0; i < 64; i++) + l17 = i; + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(l18\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l18\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l18\\)" "gimple" } } */ + #pragma omp taskloop simd lastprivate (l18) + for (int i = 0; i < 64; i++) + l18 = i; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l19\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l19\\)" "gimple" } } */ + #pragma omp teams distribute lastprivate (l19) + for (int i = 0; i < 64; i++) + l19 = i; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l20\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l20\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l20\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l20\\)" "gimple" } } *//* FIXME. */ + #pragma omp teams distribute parallel for lastprivate (l20) + for (int i = 0; i < 64; i++) + l20 = i; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l21\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l21\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l21\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l21\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l21\\)" "gimple" } } */ + #pragma omp teams distribute parallel for simd lastprivate (l21) + for (int i = 0; i < 64; i++) + l21 = i; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l22\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l22\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l22\\)" "gimple" } } */ + #pragma omp teams distribute simd lastprivate (l22) + for (int i = 0; i < 64; i++) + l22 = i; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j03\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j03\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp teams loop lastprivate (j03) + for (j03 = 0; j03 < 64; j03++) + ; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-3.c b/gcc/testsuite/c-c++-common/gomp/pr99928-3.c new file mode 100644 index 0000000..67f590b --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-3.c @@ -0,0 +1,119 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +int l00, l01, l02, l03, l04, l07, l08, l09; +int l10, l11; + +void +bar (void) +{ + int l05 = 0, l06 = 0; + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*firstprivate\\(l00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(l00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l00\\)" "gimple" } } */ + #pragma omp for simd firstprivate (l00) lastprivate (l00) + for (int i = 0; i < 64; i++) + l00 = i; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } */ + #pragma omp master taskloop firstprivate (l01) lastprivate (l01) + for (int i = 0; i < 64; i++) + l01 = i; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l02\\)" "gimple" } } */ + #pragma omp master taskloop simd firstprivate (l02) lastprivate (l02) + for (int i = 0; i < 64; i++) + l02 = i; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l03\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l03\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } *//* FIXME. */ + #pragma omp parallel for firstprivate (l03) lastprivate (l03) + for (int i = 0; i < 64; i++) + l03 = i; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l04\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l04\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } */ + #pragma omp parallel for simd firstprivate (l04) lastprivate (l04) + for (int i = 0; i < 64; i++) + l04 = i; + /* { 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" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l05\\)" "gimple" } } */ + #pragma omp parallel master taskloop firstprivate (l05) lastprivate (l05) + for (int i = 0; i < 64; i++) + l05 = i; + /* { 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" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l06\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } */ + #pragma omp parallel master taskloop simd firstprivate (l06) lastprivate (l06) + for (int i = 0; i < 64; i++) + l06 = i; + /* FIXME: OpenMP 5.0/5.1 broken here, conceptually it should be shared on parallel and + firstprivate+lastprivate on sections, in GCC implementation we put firstprivate+lastprivate + on parallel for historic reasons, but OpenMP 5.0/5.1 mistakenly say firstprivate + should be on parallel and lastprivate on sections. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l07\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l07\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*firstprivate\\(l07\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*lastprivate\\(l07\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp section \[^\n\r]*firstprivate\\(l07\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp section \[^\n\r]*lastprivate\\(l07\\)" "gimple" } } */ + #pragma omp parallel sections firstprivate (l07) lastprivate (l07) + { + l07 = 1; + #pragma omp section + l07 = 2; + } + /* { 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 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. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l08\\)" "gimple" } } *//* FIXME. */ + #pragma omp target parallel for firstprivate (l08) lastprivate (l08) + for (int i = 0; i < 64; i++) + l08 = i; + /* { 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 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. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l09\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l09\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l09\\)" "gimple" } } */ + #pragma omp target parallel for simd firstprivate (l09) lastprivate (l09) + for (int i = 0; i < 64; i++) + l09 = i; + /* { 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-not "omp simd\[^\n\r]*firstprivate\\(l10\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l10\\)" "gimple" } } */ + #pragma omp target simd firstprivate (l10) lastprivate (l10) + for (int i = 0; i < 64; i++) + l10 = i; + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l11\\)" "gimple" } } */ + #pragma omp taskloop simd firstprivate (l11) lastprivate (l11) + for (int i = 0; i < 64; i++) + l11 = i; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-4.c b/gcc/testsuite/c-c++-common/gomp/pr99928-4.c new file mode 100644 index 0000000..c03afc4 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-4.c @@ -0,0 +1,76 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +int l00, l01, l05, l06, l07, l08; + +void +bar (void) +{ + int l02 = 0, l03 = 0, l04 = 0; + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*firstprivate\\(l00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(l00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l00:1\\)" "gimple" } } */ + #pragma omp for simd linear (l00) + for (int i = 0; i < 64; i++) + l00++; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l01:1\\)" "gimple" } } */ + #pragma omp master taskloop simd linear (l01) + for (int i = 0; i < 64; i++) + l01++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*linear\\(l02:1\\)" "gimple" } } */ + #pragma omp parallel for linear (l02) + for (int i = 0; i < 64; i++) + l02++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l03\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l03\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l03:1\\)" "gimple" } } */ + #pragma omp parallel for simd linear (l03) + for (int i = 0; i < 64; i++) + l03++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l04:1\\)" "gimple" } } */ + #pragma omp parallel master taskloop simd linear (l04) + for (int i = 0; i < 64; i++) + l04++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l05" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l05\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*linear\\(l05:1\\)" "gimple" } } */ + #pragma omp target parallel for linear (l05) + for (int i = 0; i < 64; i++) + l05++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l06" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l06\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l06\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l06\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l06:1\\)" "gimple" } } */ + #pragma omp target parallel for simd linear (l06) + for (int i = 0; i < 64; i++) + l06++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l07" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l07\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l07:1\\)" "gimple" } } */ + #pragma omp target simd linear (l07) + for (int i = 0; i < 64; i++) + l07++; + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l08:1\\)" "gimple" } } */ + #pragma omp taskloop simd linear (l08) + for (int i = 0; i < 64; i++) + l08++; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-5.c b/gcc/testsuite/c-c++-common/gomp/pr99928-5.c new file mode 100644 index 0000000..6eca9c8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-5.c @@ -0,0 +1,107 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +int j00, j01, j02, j03, j04, j06, j07, j08, j09; +int j10; + +void +foo (void) +{ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j00:1\\)" "gimple" } } */ + #pragma omp distribute parallel for simd linear (j00) + for (j00 = 0; j00 < 64; j00++) + ; + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j01:1\\)" "gimple" } } */ + #pragma omp distribute simd linear (j01) + for (j01 = 0; j01 < 64; j01++) + ; +} + +void +bar (void) +{ + int j05, j11, j12; + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j02:1\\)" "gimple" } } */ + #pragma omp for simd linear (j02) + for (j02 = 0; j02 < 64; j02++) + ; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j03\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j03:1\\)" "gimple" } } */ + #pragma omp master taskloop simd linear (j03) + for (j03 = 0; j03 < 64; j03++) + ; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j04\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j04\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j04:1\\)" "gimple" } } */ + #pragma omp parallel for simd linear (j04) + for (j04 = 0; j04 < 64; j04++) + ; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j05\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j05:1\\)" "gimple" } } */ + #pragma omp parallel master taskloop simd linear (j05) + for (j05 = 0; j05 < 64; j05++) + ; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j06" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j06\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j06:1\\)" "gimple" } } */ + #pragma omp target parallel for simd linear (j06) + for (j06 = 0; j06 < 64; j06++) + ; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j07" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j07\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j07:1\\)" "gimple" } } */ + #pragma omp target simd linear (j07) + for (j07 = 0; j07 < 64; j07++) + ; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j08" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j08\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j08:1\\)" "gimple" } } */ + #pragma omp target teams distribute parallel for simd linear (j08) + for (j08 = 0; j08 < 64; j08++) + ; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j09" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j09\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j09\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j09\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j09:1\\)" "gimple" } } */ + #pragma omp target teams distribute simd linear (j09) + for (j09 = 0; j09 < 64; j09++) + ; + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j10\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j10\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j10:1\\)" "gimple" } } */ + #pragma omp taskloop simd linear (j10) + for (j10 = 0; j10 < 64; j10++) + ; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j11:1\\)" "gimple" } } */ + #pragma omp teams distribute parallel for simd linear (j11) + for (j11 = 0; j11 < 64; j11++) + ; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j12\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j12\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j12:1\\)" "gimple" } } */ + #pragma omp teams distribute simd linear (j12) + for (j12 = 0; j12 < 64; j12++) + ; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-6.c b/gcc/testsuite/c-c++-common/gomp/pr99928-6.c new file mode 100644 index 0000000..9934047 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-6.c @@ -0,0 +1,107 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +int j00, j01, j02, j03, j04, j06, j07, j08, j09; +int j10; + +void +foo (void) +{ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j00:1\\)" "gimple" } } */ + #pragma omp distribute parallel for simd + for (j00 = 0; j00 < 64; j00++) + ; + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j01:1\\)" "gimple" } } */ + #pragma omp distribute simd + for (j01 = 0; j01 < 64; j01++) + ; +} + +void +bar (void) +{ + int j05, j11, j12; + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j02:1\\)" "gimple" } } */ + #pragma omp for simd + for (j02 = 0; j02 < 64; j02++) + ; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j03\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j03:1\\)" "gimple" } } */ + #pragma omp master taskloop simd + for (j03 = 0; j03 < 64; j03++) + ; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j04\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j04\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j04:1\\)" "gimple" } } */ + #pragma omp parallel for simd + for (j04 = 0; j04 < 64; j04++) + ; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j05\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j05:1\\)" "gimple" } } */ + #pragma omp parallel master taskloop simd + for (j05 = 0; j05 < 64; j05++) + ; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j06" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j06\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j06:1\\)" "gimple" } } */ + #pragma omp target parallel for simd + for (j06 = 0; j06 < 64; j06++) + ; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j07" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j07\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j07:1\\)" "gimple" } } */ + #pragma omp target simd + for (j07 = 0; j07 < 64; j07++) + ; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j08" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j08\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j08:1\\)" "gimple" } } */ + #pragma omp target teams distribute parallel for simd + for (j08 = 0; j08 < 64; j08++) + ; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j09" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j09\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j09\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j09\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j09:1\\)" "gimple" } } */ + #pragma omp target teams distribute simd + for (j09 = 0; j09 < 64; j09++) + ; + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j10\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j10\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j10:1\\)" "gimple" } } */ + #pragma omp taskloop simd + for (j10 = 0; j10 < 64; j10++) + ; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j11:1\\)" "gimple" } } */ + #pragma omp teams distribute parallel for simd + for (j11 = 0; j11 < 64; j11++) + ; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j12\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j12\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j12:1\\)" "gimple" } } */ + #pragma omp teams distribute simd + for (j12 = 0; j12 < 64; j12++) + ; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-7.c b/gcc/testsuite/c-c++-common/gomp/pr99928-7.c new file mode 100644 index 0000000..5db1101 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-7.c @@ -0,0 +1,103 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +void +foo (void) +{ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j00:1\\)" "gimple" } } */ + #pragma omp distribute parallel for simd + for (int j00 = 0; j00 < 64; j00++) + ; + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j01:1\\)" "gimple" } } */ + #pragma omp distribute simd + for (int j01 = 0; j01 < 64; j01++) + ; +} + +void +bar (void) +{ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j02:1\\)" "gimple" } } */ + #pragma omp for simd + for (int j02 = 0; j02 < 64; j02++) + ; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp taskloop\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j03:1\\)" "gimple" } } */ + #pragma omp master taskloop simd + for (int j03 = 0; j03 < 64; j03++) + ; + /* { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j04:1\\)" "gimple" } } */ + #pragma omp parallel for simd + for (int j04 = 0; j04 < 64; j04++) + ; + /* { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*shared\\(j05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp taskloop\[^\n\r]*lastprivate\\(j05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j05:1\\)" "gimple" } } */ + #pragma omp parallel master taskloop simd + for (int j05 = 0; j05 < 64; j05++) + ; + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*map\\(tofrom:j06" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j06\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*shared\\(j06\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j06:1\\)" "gimple" } } */ + #pragma omp target parallel for simd + for (int j06 = 0; j06 < 64; j06++) + ; + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*map\\(tofrom:j07" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j07\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j07:1\\)" "gimple" } } */ + #pragma omp target simd + for (int j07 = 0; j07 < 64; j07++) + ; + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*map\\(tofrom:j08" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp teams\[^\n\r]*shared\\(j08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*shared\\(j08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j08:1\\)" "gimple" } } */ + #pragma omp target teams distribute parallel for simd + for (int j08 = 0; j08 < 64; j08++) + ; + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*map\\(tofrom:j09" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j09\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp teams\[^\n\r]*shared\\(j09\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j09\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j09:1\\)" "gimple" } } */ + #pragma omp target teams distribute simd + for (int j09 = 0; j09 < 64; j09++) + ; + /* { dg-final { scan-tree-dump-not "omp taskloop\[^\n\r]*lastprivate\\(j10\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j10:1\\)" "gimple" } } */ + #pragma omp taskloop simd + for (int j10 = 0; j10 < 64; j10++) + ; + /* { dg-final { scan-tree-dump-not "omp teams\[^\n\r]*shared\\(j11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*shared\\(j11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j11:1\\)" "gimple" } } */ + #pragma omp teams distribute parallel for simd + for (int j11 = 0; j11 < 64; j11++) + ; + /* { dg-final { scan-tree-dump-not "omp teams\[^\n\r]*shared\\(j12\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j12\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j12:1\\)" "gimple" } } */ + #pragma omp teams distribute simd + for (int j12 = 0; j12 < 64; j12++) + ; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-8.c b/gcc/testsuite/c-c++-common/gomp/pr99928-8.c new file mode 100644 index 0000000..755da3b --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-8.c @@ -0,0 +1,219 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +int r00, r01, r02, r03, r04, r05; +int r13, r14, r15, r16, r17, r18, r19; +int r20, r21, r22, r23, r24; + +void +foo (void) +{ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r00\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r00\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r00\\)" "gimple" } } *//* FIXME. */ + #pragma omp distribute parallel for reduction(+:r00) + for (int i = 0; i < 64; i++) + r00++; + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r01\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r01\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r01\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r01\\)" "gimple" } } */ + #pragma omp distribute parallel for simd reduction(+:r01) + for (int i = 0; i < 64; i++) + r01++; + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r02\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r02\\)" "gimple" } } */ + #pragma omp distribute simd reduction(+:r02) + for (int i = 0; i < 64; i++) + r02++; +} + +void +bar (void) +{ + int r06 = 0, r07 = 0, r08 = 0, r09 = 0; + int r10 = 0, r11 = 0, r12 = 0; + int r25 = 0, r26 = 0, r27 = 0, r28 = 0, r29 = 0; + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r03\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r03\\)" "gimple" } } */ + #pragma omp for simd reduction(+:r03) + for (int i = 0; i < 64; i++) + r03++; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:r04\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:r04\\)" "gimple" } } */ + #pragma omp master taskloop reduction(+:r04) + for (int i = 0; i < 64; i++) + r04++; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:r05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:r05\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r05\\)" "gimple" } } */ + #pragma omp master taskloop simd reduction(+:r05) + for (int i = 0; i < 64; i++) + r05++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r06\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r06\\)" "gimple" } } *//* FIXME. */ + #pragma omp parallel for reduction(+:r06) + for (int i = 0; i < 64; i++) + r06++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r07\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r07\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r07\\)" "gimple" } } */ + #pragma omp parallel for simd reduction(+:r07) + for (int i = 0; i < 64; i++) + r07++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r08\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r08\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp parallel loop reduction(+:r08) + for (int i = 0; i < 64; i++) + r08++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r09\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:r09\\)" "gimple" } } */ + #pragma omp parallel master reduction(+:r09) + r09++; + /* { 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" } } */ + #pragma omp parallel master taskloop reduction(+:r10) + for (int i = 0; i < 64; i++) + r10++; + /* { 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" } } */ + #pragma omp parallel master taskloop simd reduction(+:r11) + for (int i = 0; i < 64; i++) + r11++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r12\\)" "gimple" } } *//* FIXME: This should be on sections instead. */ + /* { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*reduction\\(\\+:r12\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp section \[^\n\r]*reduction\\(\\+:r12\\)" "gimple" } } */ + #pragma omp parallel sections reduction(+:r12) + { + r12++; + #pragma omp section + r12++; + } + /* { 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 parallel\[^\n\r]*reduction\\(\\+:r13\\)" "gimple" } } */ + #pragma omp target parallel reduction(+:r13) + r13++; + /* { 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 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. */ + #pragma omp target parallel for reduction(+:r14) + for (int i = 0; i < 64; i++) + r14++; + /* { 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 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" } } */ + #pragma omp target parallel for simd reduction(+:r15) + for (int i = 0; i < 64; i++) + r15++; + /* { 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 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. */ + #pragma omp target parallel loop reduction(+:r16) + for (int i = 0; i < 64; i++) + r16++; + /* { 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 teams\[^\n\r]*reduction\\(\\+:r17\\)" "gimple" } } */ + #pragma omp target teams reduction(+:r17) + r17++; + /* { 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 teams\[^\n\r]*reduction\\(\\+:r18\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r18\\)" "gimple" } } */ + #pragma omp target teams distribute reduction(+:r18) + for (int i = 0; i < 64; i++) + r18++; + /* { 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 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. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } } *//* FIXME. */ + #pragma omp target teams distribute parallel for reduction(+:r19) + for (int i = 0; i < 64; i++) + r19++; + /* { 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 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. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } } */ + #pragma omp target teams distribute parallel for simd reduction(+:r20) + for (int i = 0; i < 64; i++) + r20++; + /* { 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 teams\[^\n\r]*reduction\\(\\+:r21\\)" "gimple" { xfail *-*-* } } } */ + /* { 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" } } */ + #pragma omp target teams distribute simd reduction(+:r21) + for (int i = 0; i < 64; i++) + r21++; + /* { 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 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. */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r22\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r22\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp target teams loop reduction(+:r22) + for (int i = 0; i < 64; i++) + r22++; + /* { 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 simd\[^\n\r]*reduction\\(\\+:r23\\)" "gimple" } } */ + #pragma omp target simd reduction(+:r23) + for (int i = 0; i < 64; i++) + r23++; + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:r24\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r24\\)" "gimple" } } */ + #pragma omp taskloop simd reduction(+:r24) + for (int i = 0; i < 64; i++) + r24++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r25\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r25\\)" "gimple" } } */ + #pragma omp teams distribute reduction(+:r25) + for (int i = 0; i < 64; i++) + r25++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r26\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r26\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r26\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r26\\)" "gimple" } } *//* FIXME. */ + #pragma omp teams distribute parallel for reduction(+:r26) + for (int i = 0; i < 64; i++) + r26++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r27\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r27\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r27\\)" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r27\\)" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r27\\)" "gimple" } } */ + #pragma omp teams distribute parallel for simd reduction(+:r27) + for (int i = 0; i < 64; i++) + r27++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r28\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r28\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r28\\)" "gimple" } } */ + #pragma omp teams distribute simd reduction(+:r28) + for (int i = 0; i < 64; i++) + r28++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(r29\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*reduction\\(\\+:r29\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r29\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r29\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r29\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp teams loop reduction(+:r29) + for (int i = 0; i < 64; i++) + r29++; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-9.c b/gcc/testsuite/c-c++-common/gomp/pr99928-9.c new file mode 100644 index 0000000..a766b72 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-9.c @@ -0,0 +1,219 @@ +/* PR middle-end/99928 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +int r00[4], r01[4], r02[4], r03[4], r04[4], r05[4]; +int r13[4], r14[4], r15[4], r16[4], r17[4], r18[4], r19[4]; +int r20[4], r21[4], r22[4], r23[4], r24[4]; + +void +foo (void) +{ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r00 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r00 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r00 \\+ 4" "gimple" } } *//* FIXME. */ + #pragma omp distribute parallel for reduction(+:r00[1:2]) + for (int i = 0; i < 64; i++) + r00[1]++; + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r01 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r01 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r01 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r01 \\+ 4" "gimple" } } */ + #pragma omp distribute parallel for simd reduction(+:r01[1:2]) + for (int i = 0; i < 64; i++) + r01[1]++; + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r02 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r02 \\+ 4" "gimple" } } */ + #pragma omp distribute simd reduction(+:r02[1:2]) + for (int i = 0; i < 64; i++) + r02[1]++; +} + +void +bar (void) +{ + int r06[4] = {}, r07[4] = {}, r08[4] = {}, r09[4] = {}; + int r10[4] = {}, r11[4] = {}, r12[4] = {}; + int r25[4] = {}, r26[4] = {}, r27[4] = {}, r28[4] = {}, r29[4] = {}; + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r03 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r03 \\+ 4" "gimple" } } */ + #pragma omp for simd reduction(+:r03[1:2]) + for (int i = 0; i < 64; i++) + r03[1]++; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r04 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r04 \\+ 4" "gimple" } } */ + #pragma omp master taskloop reduction(+:r04[1:2]) + for (int i = 0; i < 64; i++) + r04[1]++; + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r05 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r05 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r05 \\+ 4" "gimple" } } */ + #pragma omp master taskloop simd reduction(+:r05[1:2]) + for (int i = 0; i < 64; i++) + r05[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r06 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r06 \\+ 4" "gimple" } } *//* FIXME. */ + #pragma omp parallel for reduction(+:r06[1:2]) + for (int i = 0; i < 64; i++) + r06[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r07 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r07 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r07 \\+ 4" "gimple" } } */ + #pragma omp parallel for simd reduction(+:r07[1:2]) + for (int i = 0; i < 64; i++) + r07[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r08\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r08 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r08 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp parallel loop reduction(+:r08[1:2]) + for (int i = 0; i < 64; i++) + r08[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r09 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r09 \\+ 4" "gimple" } } */ + #pragma omp parallel master reduction(+:r09[1:2]) + r09[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r10\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r10 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r10 \\+ 4" "gimple" } } */ + #pragma omp parallel master taskloop reduction(+:r10[1:2]) + for (int i = 0; i < 64; i++) + r10[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r11\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r11 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r11 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r11 \\+ 4" "gimple" } } */ + #pragma omp parallel master taskloop simd reduction(+:r11[1:2]) + for (int i = 0; i < 64; i++) + r11[1]++; + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r12 \\+ 4" "gimple" } } *//* FIXME: This should be on sections instead. */ + /* { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r12 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump-not "omp section \[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r12 \\+ 4" "gimple" } } */ + #pragma omp parallel sections reduction(+:r12[1:2]) + { + r12[1]++; + #pragma omp section + r12[1]++; + } + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r13\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r13\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r13 \\+ 4" "gimple" } } */ + #pragma omp target parallel reduction(+:r13[1:2]) + r13[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r14\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r14" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r14 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r14 \\+ 4" "gimple" } } *//* FIXME. */ + #pragma omp target parallel for reduction(+:r14[1:2]) + for (int i = 0; i < 64; i++) + r14[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r15\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r15\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r15 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r15 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r15 \\+ 4" "gimple" } } */ + #pragma omp target parallel for simd reduction(+:r15[1:2]) + for (int i = 0; i < 64; i++) + r15[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r16\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { 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\\(\\+:MEM\[^\n\r]*&r16 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r16 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp target parallel loop reduction(+:r16[1:2]) + for (int i = 0; i < 64; i++) + r16[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r17\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r17\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r17 \\+ 4" "gimple" } } */ + #pragma omp target teams reduction(+:r17[1:2]) + r17[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r18\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r18\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r18 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r18 \\+ 4" "gimple" } } */ + #pragma omp target teams distribute reduction(+:r18[1:2]) + for (int i = 0; i < 64; i++) + r18[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r19\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r19\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r19 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r19 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r19 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r19 \\+ 4" "gimple" } } *//* FIXME. */ + #pragma omp target teams distribute parallel for reduction(+:r19[1:2]) + for (int i = 0; i < 64; i++) + r19[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r20\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r20\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r20 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r20 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r20 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r20 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r20 \\+ 4" "gimple" } } */ + #pragma omp target teams distribute parallel for simd reduction(+:r20[1:2]) + for (int i = 0; i < 64; i++) + r20[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r21\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r21\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r21 \\+ 4" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r21 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r21 \\+ 4" "gimple" } } */ + #pragma omp target teams distribute simd reduction(+:r21[1:2]) + for (int i = 0; i < 64; i++) + r21[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r22\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { 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\\(\\+:MEM\[^\n\r]*&r22 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r22\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r22 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r22 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp target teams loop reduction(+:r22[1:2]) + for (int i = 0; i < 64; i++) + r22[1]++; + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r23\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r23\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r23 \\+ 4" "gimple" } } */ + #pragma omp target simd reduction(+:r23[1:2]) + for (int i = 0; i < 64; i++) + r23[1]++; + /* { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r24 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r24 \\+ 4" "gimple" } } */ + #pragma omp taskloop simd reduction(+:r24[1:2]) + for (int i = 0; i < 64; i++) + r24[1]++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r25 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r25 \\+ 4" "gimple" } } */ + #pragma omp teams distribute reduction(+:r25[1:2]) + for (int i = 0; i < 64; i++) + r25[1]++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r26 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r26 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r26 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r26 \\+ 4" "gimple" } } *//* FIXME. */ + #pragma omp teams distribute parallel for reduction(+:r26[1:2]) + for (int i = 0; i < 64; i++) + r26[1]++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r27 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r27 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r27 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ + /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r27 \\+ 4" "gimple" } } *//* FIXME. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r27 \\+ 4" "gimple" } } */ + #pragma omp teams distribute parallel for simd reduction(+:r27[1:2]) + for (int i = 0; i < 64; i++) + r27[1]++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r28 \\+ 4" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r28 \\+ 4" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r28 \\+ 4" "gimple" } } */ + #pragma omp teams distribute simd reduction(+:r28[1:2]) + for (int i = 0; i < 64; i++) + r28[1]++; + /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(r29\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r29 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r29\\)" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r29 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r29 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ + #pragma omp teams loop reduction(+:r29[1:2]) + for (int i = 0; i < 64; i++) + r29[1]++; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/friend7.C b/gcc/testsuite/g++.dg/cpp0x/friend7.C new file mode 100644 index 0000000..734b367 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/friend7.C @@ -0,0 +1,40 @@ +// PR c++/99032 +// { dg-do compile { target c++11 } } + +class X { }; +template<typename T1, typename T2> +void foo (T1, T2); + +struct S { + [[deprecated]] friend void f(); // { dg-error "attribute appertains" } + [[deprecated]] friend void f2() { } + __attribute__((deprecated)) friend void f3(); // { dg-error "attribute appertains" } + friend void f3 [[deprecated]] (); // { dg-error "attribute appertains" } + friend void f4 [[deprecated]] () { } + [[deprecated]] friend void; // { dg-error "attribute appertains" } + __attribute__((deprecated)) friend int; // { dg-error "attribute appertains" } + friend __attribute__((deprecated)) int; // { dg-error "attribute appertains" } + friend int __attribute__((deprecated)); // { dg-error "attribute appertains" } + [[deprecated]] friend X; // { dg-error "attribute appertains" } + [[deprecated]] friend class N; // { dg-warning "attribute ignored" } + friend class [[deprecated]] N2; // { dg-error "attribute appertains" } + friend class __attribute__((deprecated)) N3; // { dg-error "attribute appertains" } + [[deprecated]] friend void foo<>(int, int); // { dg-error "attribute appertains" } + [[deprecated]] friend void ::foo(int, int); // { dg-error "attribute appertains" } + // { dg-bogus "should have" "PR100339" { xfail *-*-* } .-1 } +}; + +template<typename T> +class node { }; + +template<typename T> +struct A { + [[deprecated]] friend T; // { dg-error "attribute appertains" } + [[deprecated]] friend class node<T>; // { dg-warning "attribute ignored" } + template<typename> + [[deprecated]] friend class A; // { dg-warning "attribute ignored" } + template<typename> + [[deprecated]] friend void bar () { } + template<typename> + [[deprecated]] friend void baz (); // { dg-error "attribute appertains" } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-39-1.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-39-1.C index 453fc01..4010ba7 100644 --- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-39-1.C +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-39-1.C @@ -2,7 +2,8 @@ int fragile_block(void) { typedef - [[gnu::aligned (16)]] // { dg-warning "ignored" } + [[gnu::aligned (16)]] // { dg-error "standard attributes in middle of decl-specifiers" } +// { dg-warning "attribute ignored" "" { target *-*-* } .-1 } struct { int i; } XmmUint16; diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-4.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-4.C index b401c69..c120aed 100644 --- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-4.C +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-4.C @@ -13,7 +13,8 @@ int one_third [[noreturn]] [[gnu::unused]] (void); int [[gnu::unused]] one_half(); // { dg-warning "ignored" } static -[[noreturn]] // { dg-warning "ignored" } +[[noreturn]] // { dg-error "standard attributes in middle of decl-specifiers" } +// { dg-warning "attribute ignored" "" { target *-*-* } .-1 } void two [[gnu::unused]] (void) {} diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-74.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-74.C new file mode 100644 index 0000000..7e17bc8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-74.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++11 } } +// A C++11 attribute cannot appear in the middle of the decl-specifier-seq, +// only before it (in which case it appertains to the declaration) or at +// the end (in which case it appertains to the type). + +struct S { + friend [[deprecated]] void; // { dg-error "standard attributes in middle of decl-specifiers" } + friend [[deprecated]] int fn(); // { dg-error "standard attributes in middle of decl-specifiers" } + // { dg-warning "attribute ignored" "" { target *-*-* } .-1 } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/pr94616.C b/gcc/testsuite/g++.dg/cpp0x/pr94616.C new file mode 100644 index 0000000..a8fe700 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr94616.C @@ -0,0 +1,23 @@ +// PR c++/94616 +// { dg-do compile { target c++11 } } + +struct Bar { + Bar(int n) { if (n > 0) throw 2; } + ~Bar() {} +}; + +struct Foo { + Bar b1 = 0; + Bar b2 = 1; + Foo() {} + ~Foo() {} +}; + +int +main() +{ + try { + Foo f; + } catch(int) { + } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae68.C b/gcc/testsuite/g++.dg/cpp0x/sfinae68.C new file mode 100644 index 0000000..d292b68 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae68.C @@ -0,0 +1,23 @@ +// PR c++/90019 +// { dg-do compile { target c++11 } } + +template<bool, typename T = void> +struct enable_if { }; +template<typename T> +struct enable_if<true, T> { typedef T type; }; +template<bool C, typename T = void> +using __enable_if_t = typename enable_if<C, T>::type; +template<bool C, typename T = void> +using enable_if_t = typename enable_if<C, T>::type; + +template <int I, enable_if_t<I == 0, int>...> void foo() {} +template <int I, enable_if_t<I != 0, int>...> void foo() {} +template <int I, int=0, enable_if_t<I == 0, int>...> void bar() {} +template <int I, int=0, enable_if_t<I != 0, int>...> void bar() {} + +void test() +{ + bar<0>(); + bar<0,0>(); + foo<0>(); +} diff --git a/gcc/testsuite/g++.dg/cpp1y/digit-sep-paste.C b/gcc/testsuite/g++.dg/cpp1y/digit-sep-paste.C new file mode 100644 index 0000000..41fb967 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/digit-sep-paste.C @@ -0,0 +1,11 @@ +// Test token pasting with digit separators avoided for preprocessed output. +// { dg-do compile { target c++14 } } +// { dg-options "-save-temps" } + +#define ZERO 0 + +int +f () +{ + return ZERO'0'0; /* { dg-error "expected" } */ +} diff --git a/gcc/testsuite/g++.dg/cpp1y/pr88872.C b/gcc/testsuite/g++.dg/cpp1y/pr88872.C new file mode 100644 index 0000000..3719e39 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/pr88872.C @@ -0,0 +1,24 @@ +// PR c++/88872 +// { dg-do compile { target c++14 } } + +struct a { + template <typename b> constexpr a(b) : c() {} + int c; +}; +void d(); +template <char...> constexpr a operator"" _n() { return d; } +struct e; +struct f { + e operator[](int); +}; +struct g { + void h(); + f i; +}; +template <typename> struct j { + void k() { [](auto) { constexpr auto l = 2_n; }(keywords); } + int keywords; +}; +using m = j<int>; +class e : public m {}; +void g::h() { i[0].k(); } diff --git a/gcc/testsuite/g++.dg/cpp1y/pr95226.C b/gcc/testsuite/g++.dg/cpp1y/pr95226.C new file mode 100644 index 0000000..614c83c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/pr95226.C @@ -0,0 +1,17 @@ +// PR c++/95226 +// { dg-do run { target c++14 } } + +#include <vector> + +struct T { + unsigned a; + float b {8.}; +}; + +int main() +{ + T t = {1}; + std::vector<T> tt = {{1}, {2}}; + if (t.a != 1 || t.b != 8.0f || tt[0].a != 1 || tt[0].b != 8.0f || tt[1].a != 2 || tt[1].b != 8.0f) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/attrib63.C b/gcc/testsuite/g++.dg/ext/attrib63.C new file mode 100644 index 0000000..93bde1e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib63.C @@ -0,0 +1,17 @@ +// { dg-do compile } +// { dg-additional-options "-Wno-psabi" } + +#define vector __attribute__((vector_size(16))) +class A { + friend vector float f(); + __attribute__((deprecated)) friend void f2(); // { dg-error "attribute appertains" } + friend __attribute__((deprecated, vector_size(16))) float f3(); // { dg-error "attribute appertains" } + friend __attribute__((vector_size(16), deprecated)) float f4(); // { dg-error "attribute appertains" } +}; + +vector float vf; +vector float +f () +{ + return vf; +} diff --git a/gcc/testsuite/g++.dg/pr100574.C b/gcc/testsuite/g++.dg/pr100574.C new file mode 100644 index 0000000..42ba040 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr100574.C @@ -0,0 +1,64 @@ +/* PR middle-end/100574 - ICE: in size_remaining, at builtins.c:413 with + -O3 -ftracer -fno-tree-dominator-opts -fno-tree-fre + { dg-do compile { target c++11 } } + { dg-options "-O3 -ftracer -fno-tree-dominator-opts -fno-tree-fre" } */ + +void *operator new (__SIZE_TYPE__, void *__p) { return __p; } + +template <typename> struct allocator_traits; +template <typename> class allocator {}; +template <typename _Tp> struct allocator_traits<allocator<_Tp> > +{ + using allocator_type = allocator<_Tp>; + using pointer = _Tp *; + using size_type = long; + template <typename _Up> using rebind_alloc = allocator<_Up>; + static pointer allocate(allocator_type, size_type); + template <typename _Up> static void construct(_Up __p) { new (__p) _Up(); } +}; + +struct __alloc_traits : allocator_traits<allocator<char>> { + struct rebind { + typedef rebind_alloc<char> other; + }; +}; + +struct _Vector_base { + struct : __alloc_traits::rebind::other { + } _M_impl; + long _M_allocate___n; +}; + +template <typename, typename = char> class vector : _Vector_base { + long max_size(); +public: + void push_back() { _M_realloc_insert(); } + template <typename...> void _M_realloc_insert(); +}; + +template <typename _Tp, typename _Alloc> +template <typename...> +void vector<_Tp, _Alloc>::_M_realloc_insert() { + __alloc_traits::pointer __trans_tmp_5; + long __len(__len || max_size()), __elems_before; + __trans_tmp_5 = _M_allocate___n + ? __alloc_traits::allocate(_M_impl, _M_allocate___n) + : __alloc_traits::pointer(); + __alloc_traits::construct(__trans_tmp_5 + __elems_before); +} + +enum { MIDIST_PITCHBEND }; +struct DataBlock { + vector<char> data; +}; + +char ReadTrackChunk_status; + +void ReadTrackChunk() +{ + DataBlock block; + while (!0) + switch (ReadTrackChunk_status) + case MIDIST_PITCHBEND: + block.data.push_back(); +} diff --git a/gcc/testsuite/g++.dg/tsan/pthread_cond_clockwait.C b/gcc/testsuite/g++.dg/tsan/pthread_cond_clockwait.C new file mode 100644 index 0000000..82d6a5c --- /dev/null +++ b/gcc/testsuite/g++.dg/tsan/pthread_cond_clockwait.C @@ -0,0 +1,31 @@ +// Test pthread_cond_clockwait not generating false positives with tsan +// { dg-do run { target { { *-*-linux* *-*-gnu* *-*-uclinux* } && pthread } } } +// { dg-options "-fsanitize=thread -lpthread" } + +#include <pthread.h> + +pthread_cond_t cv; +pthread_mutex_t mtx; + +void *fn(void *vp) { + pthread_mutex_lock(&mtx); + pthread_cond_signal(&cv); + pthread_mutex_unlock(&mtx); + return NULL; +} + +int main() { + pthread_mutex_lock(&mtx); + + pthread_t tid; + pthread_create(&tid, NULL, fn, NULL); + + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + ts.tv_sec += 10; + pthread_cond_clockwait(&cv, &mtx, CLOCK_MONOTONIC, &ts); + pthread_mutex_unlock(&mtx); + + pthread_join(tid, NULL); + return 0; +} diff --git a/gcc/testsuite/g++.dg/warn/Wint-in-bool-context-2.C b/gcc/testsuite/g++.dg/warn/Wint-in-bool-context-2.C new file mode 100644 index 0000000..6cb482d --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wint-in-bool-context-2.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-Wint-in-bool-context" } + +unsigned hb(unsigned i) { return ~i; } + +template<typename T> +void f(int i) +{ + auto l = [i]() { return T(2 * hb(i)); }; // { dg-bogus "in boolean context" } + (void) l; +} + +int main() +{ + f<bool>(0); +} diff --git a/gcc/testsuite/g++.dg/warn/uninit-pr93100.C b/gcc/testsuite/g++.dg/warn/uninit-pr93100.C new file mode 100644 index 0000000..56dc894 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/uninit-pr93100.C @@ -0,0 +1,60 @@ +/* PR tree-optimization/98508 - Sanitizer disable -Wall and -Wextra + { dg-do compile } + { dg-require-effective-target no_fsanitize_address } + { dg-options "-O0 -Wall -fsanitize=address" } */ + +struct S +{ + int a; +}; + +void warn_init_self_O0 () +{ + S s = S (s); // { dg-warning "\\\[-Wuninitialized" } + (void)&s; +} + + +void warn_init_self_use_O0 () +{ + S s = S (s); // { dg-warning "\\\[-Wuninitialized" } + + void sink (void*); + sink (&s); +} + + +#pragma GCC optimize ("1") + +void warn_init_self_O1 () +{ + S s = S (s); // { dg-warning "\\\[-Wuninitialized" } + (void)&s; +} + + +void warn_init_self_use_O1 () +{ + S s = S (s); // { dg-warning "\\\[-Wuninitialized" } + + void sink (void*); + sink (&s); +} + + +#pragma GCC optimize ("2") + +void warn_init_self_O2 () +{ + S s = S (s); // { dg-warning "\\\[-Wuninitialized" } + (void)&s; +} + + +void warn_init_self_use_O2 () +{ + S s = S (s); // { dg-warning "\\\[-Wuninitialized" } + + void sink (void*); + sink (&s); +} diff --git a/gcc/testsuite/g++.target/i386/pr100581.C b/gcc/testsuite/g++.target/i386/pr100581.C new file mode 100644 index 0000000..37cc9f1 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr100581.C @@ -0,0 +1,9 @@ +/* PR target/100581 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -mxop" } */ + +typedef float __attribute__((__vector_size__(8))) v64f32; + +v64f32 af, bf, ff_a, ff_b; + +v64f32 f() { return ff_a > ff_b ? af : bf; } diff --git a/gcc/testsuite/g++.target/i386/pr98218-1.C b/gcc/testsuite/g++.target/i386/pr98218-1.C new file mode 100644 index 0000000..61ea4bf --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr98218-1.C @@ -0,0 +1,20 @@ +/* PR target/98218 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -msse2" } */ + +typedef unsigned int __attribute__((__vector_size__ (8))) v64u32; +typedef int __attribute__((__vector_size__ (8))) v64s32; +typedef float __attribute__((__vector_size__ (8))) v64f32; + +v64u32 au, bu; +v64s32 as, bs; +v64f32 af, bf; + +v64u32 tu (v64f32 a, v64f32 b) { return (a > b) ? au : bu; } +v64s32 ts (v64f32 a, v64f32 b) { return (a > b) ? as : bs; } +v64f32 fu (v64u32 a, v64u32 b) { return (a > b) ? af : bf; } +v64f32 fs (v64s32 a, v64s32 b) { return (a > b) ? af : bf; } +v64f32 ff (v64f32 a, v64f32 b) { return (a > b) ? af : bf; } + +/* { dg-final { scan-assembler-times "cmpltps" 3 } } */ +/* { dg-final { scan-assembler-times "pcmpgtd" 2 } } */ diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-67.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-67.c new file mode 100644 index 0000000..7b8f3f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-67.c @@ -0,0 +1,92 @@ +/* PR middle-end/100571 - bogus -Wstringop-overflow with VLA of elements + larger than byte + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +__attribute__ ((access (read_only, 1, 2))) void fro (int *, int); +__attribute__ ((access (write_only, 1, 2))) void fwo (int *, int); +__attribute__ ((access (read_write, 1, 2))) void frw (int *, int); + +extern __SIZE_TYPE__ n; + +void alloca_ro (void) +{ + int *a = __builtin_alloca (n * sizeof *a); + a[0] = 0; + fro (a, n); +} + +void alloca_wo (void) +{ + int *a = __builtin_alloca (n * sizeof *a); + fwo (a, n); +} + +void alloca_rw (void) +{ + int *a = __builtin_alloca (n * sizeof *a); + a[0] = 0; + frw (a, n); +} + + +void calloc_ro (void) +{ + int *a = __builtin_calloc (n, sizeof *a); + fro (a, n); +} + +void calloc_wo (void) +{ + int *a = __builtin_calloc (n, sizeof *a); + fwo (a, n); +} + +void calloc_rw (void) +{ + int *a = __builtin_calloc (n, sizeof *a); + a[0] = 0; + frw (a, n); +} + + +void malloc_ro (void) +{ + int *a = __builtin_malloc (n * sizeof *a); + a[0] = 0; + fro (a, n); +} + +void malloc_wo (void) +{ + int *a = __builtin_malloc (n * sizeof *a); + fwo (a, n); +} + +void malloc_rw (void) +{ + int *a = __builtin_malloc (n * sizeof *a); + a[0] = 0; + frw (a, n); +} + + +void vla_ro (void) +{ + int a[n]; + a[0] = 0; + fro (a, n); +} + +void vla_wo (void) +{ + int a[n]; + fwo (a, n); +} + +void vla_rw (void) +{ + int a[n]; + a[0] = 0; + frw (a, n); +} diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-9.c b/gcc/testsuite/gcc.dg/Wvla-parameter-9.c new file mode 100644 index 0000000..6c8987a --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wvla-parameter-9.c @@ -0,0 +1,30 @@ +/* PR c/100550 - ICE: in fold_convert_loc with function call VLA argument + { dg-do compile } + { dg-options "-Wall" } */ + +struct S { int i; }; + +extern void v; +extern void *pv; +extern struct S s; +void vf (void); + +/* Verify that a function redeclaration with an invalid VLA doesn't ICE. */ + +void f0 (int[]); +void f0 (int[undeclared]); // { dg-error "undeclared" } + +void f1 (int[]); +void f1 (int[-1]); // { dg-error "size" } + +void f2 (int[]); +void f2 (int[v]); // { dg-error "size" } + +void f3 (int[]); +void f3 (int b[s]); // { dg-error "size" } + +void f4 (int[]); +void f4 (int c[pv]); // { dg-error "size" } + +void f5 (int[]); +void f5 (int d[vf ()]); // { dg-error "size" } diff --git a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-2.c b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-2.c index 9ee56b6..3e75096 100644 --- a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-2.c +++ b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-2.c @@ -2,6 +2,7 @@ assignment. */ /* { dg-do run } */ /* { dg-options "-std=c11 -pedantic-errors" } */ +/* { dg-prune-output "warning: using serial compilation" } */ extern void abort (void); extern void exit (int); diff --git a/gcc/testsuite/gcc.dg/c2x-digit-separators-3.c b/gcc/testsuite/gcc.dg/c2x-digit-separators-3.c new file mode 100644 index 0000000..cddb88f --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-digit-separators-3.c @@ -0,0 +1,12 @@ +/* Test C2x digit separators. Test token pasting avoided for preprocessed + output. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -save-temps" } */ + +#define ZERO 0 + +int +f (void) +{ + return ZERO'0'0; /* { dg-error "expected" } */ +} diff --git a/gcc/testsuite/gcc.dg/cpp/c11-elifdef-1.c b/gcc/testsuite/gcc.dg/cpp/c11-elifdef-1.c new file mode 100644 index 0000000..2d5809a --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c11-elifdef-1.c @@ -0,0 +1,16 @@ +/* Test #elifdef and #elifndef not in C11. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#define A +#undef B + +#if 0 +#elifdef A +#error "#elifdef A applied" +#endif + +#if 0 +#elifndef B +#error "#elifndef B applied" +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-1.c b/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-1.c new file mode 100644 index 0000000..b23e311 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-1.c @@ -0,0 +1,57 @@ +/* Test #elifdef and #elifndef in C2x. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +#define A +#undef B + +#if 0 +#elifdef A +#define M1 1 +#endif + +#if M1 != 1 +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifdef B +#error "#elifdef B applied" +#endif + +#if 0 +#elifndef A +#error "#elifndef A applied" +#endif + +#if 0 +#elifndef B +#define M2 2 +#endif + +#if M2 != 2 +#error "#elifndef B did not apply" +#endif + +#if 0 +#elifdef A +#else +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifndef B +#else +#error "#elifndef B did not apply" +#endif + +/* As with #elif, the syntax of the new directives is relaxed after a + non-skipped group. */ + +#if 1 +#elifdef x * y +#endif + +#if 1 +#elifndef ! +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-2.c b/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-2.c new file mode 100644 index 0000000..9132832 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-2.c @@ -0,0 +1,63 @@ +/* Test #elifdef and #elifndef in C2x: erroneous usages. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +#define A +#undef B + +#elifdef A /* { dg-error "#elifdef without #if" } */ +#elifdef B /* { dg-error "#elifdef without #if" } */ +#elifndef A /* { dg-error "#elifndef without #if" } */ +#elifndef B /* { dg-error "#elifndef without #if" } */ + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifdef A /* { dg-error "#elifdef after #else" } */ +#endif + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifdef B /* { dg-error "#elifdef after #else" } */ +#endif + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifndef A /* { dg-error "#elifndef after #else" } */ +#endif + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifndef B /* { dg-error "#elifndef after #else" } */ +#endif + +#if 0 +#elifdef A = /* { dg-error "extra tokens at end of #elifdef directive" } */ +#endif + +#if 0 +#elifdef B = /* { dg-error "extra tokens at end of #elifdef directive" } */ +#endif + +#if 0 +#elifndef A = /* { dg-error "extra tokens at end of #elifndef directive" } */ +#endif + +#if 0 +#elifndef B = /* { dg-error "extra tokens at end of #elifndef directive" } */ +#endif + +#if 0 +#elifdef /* { dg-error "no macro name given in #elifdef directive" } */ +#endif + +#if 0 +#elifndef /* { dg-error "no macro name given in #elifndef directive" } */ +#endif + +#if 0 +#elifdef , /* { dg-error "macro names must be identifiers" } */ +#endif + +#if 0 +#elifndef , /* { dg-error "macro names must be identifiers" } */ +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/pr100392.c b/gcc/testsuite/gcc.dg/cpp/pr100392.c new file mode 100644 index 0000000..670ad2b --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr100392.c @@ -0,0 +1,5 @@ +/* PR preprocessor/100392 */ +/* { dg-do compile } */ +/* { dg-options "-save-temps -fdirectives-only" } */ + +#include "pr100392.h" diff --git a/gcc/testsuite/gcc.dg/cpp/pr100392.h b/gcc/testsuite/gcc.dg/cpp/pr100392.h new file mode 100644 index 0000000..340bc92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr100392.h @@ -0,0 +1,4 @@ +/* PR preprocessor/100392 */ + +/* No newline after ; below. */ +int i = 1;
\ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c new file mode 100644 index 0000000..17f6463 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c @@ -0,0 +1,20 @@ +/* PR debug/100515 */ +/* { dg-do compile } */ +/* { dg-require-effective-target fopenmp } */ +/* { dg-options "-g -O2 -fopenmp" } */ + +void +foo (int x) +{ +#pragma omp taskloop + for (int i = 0; i < x; i++) + ; +} + +void +bar (int x) +{ +#pragma omp taskloop + for (int i = 0; i < x; i++) + ; +} diff --git a/gcc/testsuite/gcc.dg/gomp/pr100508.c b/gcc/testsuite/gcc.dg/gomp/pr100508.c new file mode 100644 index 0000000..c3fa2fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/pr100508.c @@ -0,0 +1,14 @@ +/* PR middle-end/100508 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g -fopenmp-simd" } */ + +typedef int __attribute__((__vector_size__(32))) V; +V j; + +#pragma omp declare simd +int +foo (void) +{ + V m = j; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/guality/pr43077-1.c b/gcc/testsuite/gcc.dg/guality/pr43077-1.c index 39bd26a..2d93762 100644 --- a/gcc/testsuite/gcc.dg/guality/pr43077-1.c +++ b/gcc/testsuite/gcc.dg/guality/pr43077-1.c @@ -24,7 +24,7 @@ int __attribute__((noinline)) foo (unsigned long *p, unsigned long *q) { int ret; - asm volatile ("" : "=r" (ret), "=r" (*p), "=r" (*q) : "0" (1), "1" (2), "2" (3)); + asm volatile ("" : "=r" (ret), "=r" (*p), "=r" (*q) : "0" (1), "1" (2l), "2" (3l)); return ret; } diff --git a/gcc/testsuite/gcc.dg/pr100521.c b/gcc/testsuite/gcc.dg/pr100521.c new file mode 100644 index 0000000..fd9f0db --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100521.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +__builtin_clz (int a) +{ + return __builtin_clz(a); +} diff --git a/gcc/testsuite/gcc.dg/pr100563.c b/gcc/testsuite/gcc.dg/pr100563.c new file mode 100644 index 0000000..f6a5fcd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100563.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-Og -Wno-pointer-to-int-cast" } */ +unsigned long long e(void); +void f(int); +void a() { + short b = -1, c = (int)&b; + unsigned long long d = e(); + f(b >= d); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr100519.c b/gcc/testsuite/gcc.dg/torture/pr100519.c new file mode 100644 index 0000000..faf6e24 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100519.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-additional-options "--param tree-reassoc-width=2" } */ + +unsigned int foo_a1, foo_a2; + +unsigned int foo() +{ + unsigned int v0, x; + asm goto("" : "=r"(x) : : : lab); +lab: + v0 += x + x; + return v0 + x + foo_a1 + foo_a2; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr100566.c b/gcc/testsuite/gcc.dg/torture/pr100566.c new file mode 100644 index 0000000..ed85691 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100566.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ + +volatile int s, c; + +__attribute__((noipa)) void +foo (void) +{ + if (c++ > 1) + __builtin_abort (); +} + +__attribute__((noipa)) int +bar (void) +{ + int i = 0, j = s; + if (j == 0) + goto lab; + for (i = 0; i < j; i++) + { + lab: + foo (); + if (!j) + goto lab; + } + return 0; +} + +int +main () +{ + s = 1; + bar (); + if (c != 1) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr94947-1.c b/gcc/testsuite/gcc.dg/torture/pr94947-1.c index ab8b488..832e40d 100644 --- a/gcc/testsuite/gcc.dg/torture/pr94947-1.c +++ b/gcc/testsuite/gcc.dg/torture/pr94947-1.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-additional-sources "pr94947-2.c" } */ /* { dg-additional-options "-fipa-pta -flto-partition=1to1" } */ +/* { dg-prune-output "warning: using serial compilation" } */ extern void abort (); extern void baz (); diff --git a/gcc/testsuite/gcc.dg/torture/vshuf-4.inc b/gcc/testsuite/gcc.dg/torture/vshuf-4.inc index d041b33..fb35df8 100644 --- a/gcc/testsuite/gcc.dg/torture/vshuf-4.inc +++ b/gcc/testsuite/gcc.dg/torture/vshuf-4.inc @@ -25,7 +25,9 @@ T (21, 2, 6, 3, 7) \ T (22, 1, 2, 3, 0) \ T (23, 2, 1, 0, 3) \ T (24, 2, 5, 6, 3) \ -T (25, 0, 1, 4, 5) +T (25, 0, 1, 4, 5) \ +T (26, 1, 5, 3, 7) \ +T (27, 0, 5, 2, 7) #define EXPTESTS \ T (116, 1, 2, 4, 3) \ T (117, 7, 3, 3, 0) \ diff --git a/gcc/testsuite/gcc.dg/torture/vshuf-8.inc b/gcc/testsuite/gcc.dg/torture/vshuf-8.inc index de358f3..d628039 100644 --- a/gcc/testsuite/gcc.dg/torture/vshuf-8.inc +++ b/gcc/testsuite/gcc.dg/torture/vshuf-8.inc @@ -27,7 +27,9 @@ T (23, 6, 5, 4, 3, 2, 1, 0, 7) \ T (24, 0, 1, 2, 3, 8, 9, 10, 11) \ T (25, 0, 1, 2, 3, 12, 13, 14, 15) \ T (26, 0, 1, 8, 9, 10, 11, 12, 13) \ -T (27, 0, 8, 9, 10, 11, 12, 13, 14) +T (27, 0, 8, 9, 10, 11, 12, 13, 14) \ +T (28, 1, 9, 3, 11, 5, 13, 7, 15) \ +T (29, 0, 9, 2, 11, 4, 13, 6, 15) #define EXPTESTS \ T (116, 9, 3, 9, 4, 7, 0, 0, 6) \ T (117, 4, 14, 12, 8, 9, 6, 0, 10) \ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94589-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94589-1.c new file mode 100644 index 0000000..7e1aaaa --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94589-1.c @@ -0,0 +1,21 @@ +/* PR tree-optimization/94589 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int +foo (int x) +{ + return (x & 23) == x; +/* { dg-final { scan-tree-dump " & -24;" "optimized" } } */ +/* { dg-final { scan-tree-dump-not " & 23;" "optimized" } } */ +/* { dg-final { scan-tree-dump " == 0" "optimized" } } */ +} + +int +bar (int x) +{ + return (x | 137) != 137; +/* { dg-final { scan-tree-dump " & -138;" "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \\| 137;" "optimized" } } */ +/* { dg-final { scan-tree-dump " != 0" "optimized" } } */ +} diff --git a/gcc/testsuite/gcc.dg/uninit-pr93100.c b/gcc/testsuite/gcc.dg/uninit-pr93100.c new file mode 100644 index 0000000..61b7e43 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr93100.c @@ -0,0 +1,74 @@ +/* PR tree-optimization/93100 - gcc -fsanitize=address inhibits -Wuninitialized + { dg-do compile } + { dg-options "-Wall -fsanitize=address" } */ + +struct A +{ + _Bool b; + int i; +}; + +void warn_A_b_O0 (void) +{ + struct A a; + + if (a.b) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} + +void warn_A_i_O0 (void) +{ + struct A a; + + if (a.i) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} + +#pragma GCC optimize ("1") + +void warn_A_b_O1 (void) +{ + struct A a; + + if (a.b) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} + +void warn_A_i_O1 (void) +{ + struct A a; + + if (a.i) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} + + +#pragma GCC optimize ("2") + +void warn_A_b_O2 (void) +{ + struct A a; + + if (a.b) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} + +void warn_A_i_O2 (void) +{ + struct A a; + + if (a.i) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} diff --git a/gcc/testsuite/gcc.dg/uninit-pr98583.c b/gcc/testsuite/gcc.dg/uninit-pr98583.c new file mode 100644 index 0000000..638b029 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr98583.c @@ -0,0 +1,31 @@ +/* PR middle-end/98583 - missing -Wuninitialized reading from a second VLA + in its own block + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +void f (int*); +void g (int); + +void h1 (int n) +{ + int a[n]; + f (a); + + int b[n]; + g (b[1]); // { dg-warning "\\\[-Wuninitialized" } +} + +void h2 (int n, int i, int j) +{ + if (i) + { + int a[n]; + f (a); + } + + if (j) + { + int b[n]; + g (b[1]); // { dg-warning "\\\[-Wmaybe-uninitialized" } + } +} diff --git a/gcc/testsuite/gcc.target/arm/acle/saturation.c b/gcc/testsuite/gcc.target/arm/acle/saturation.c index 0b3fe51..a9f99e5 100644 --- a/gcc/testsuite/gcc.target/arm/acle/saturation.c +++ b/gcc/testsuite/gcc.target/arm/acle/saturation.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-require-effective-target arm_qbit_ok } */ -/* { dg-add-options arm_qbit } */ +/* { dg-require-effective-target arm_sat_ok } */ +/* { dg-add-options arm_sat } */ #include <arm_acle.h> diff --git a/gcc/testsuite/gcc.target/arm/armv8_2-fp16-arith-1.c b/gcc/testsuite/gcc.target/arm/armv8_2-fp16-arith-1.c index 921d26e..52b8737 100644 --- a/gcc/testsuite/gcc.target/arm/armv8_2-fp16-arith-1.c +++ b/gcc/testsuite/gcc.target/arm/armv8_2-fp16-arith-1.c @@ -104,8 +104,20 @@ TEST_CMP (greaterthanqual, >=, int16x8_t, float16x8_t) /* { dg-final { scan-assembler-times {vmul\.f16\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */ /* { dg-final { scan-assembler-times {vdiv\.f16\ts[0-9]+, s[0-9]+, s[0-9]+} 13 } } */ -/* { dg-final { scan-assembler-times {vcmp\.f32\ts[0-9]+, s[0-9]+} 26 } } */ -/* { dg-final { scan-assembler-times {vcmpe\.f32\ts[0-9]+, s[0-9]+} 52 } } */ + +/* For float16_t. */ +/* { dg-final { scan-assembler-times {vcmp\.f32\ts[0-9]+, s[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {vcmpe\.f32\ts[0-9]+, s[0-9]+} 4 } } */ + +/* For float16x4_t. */ +/* { dg-final { scan-assembler-times {vceq\.f16\td[0-9]+, d[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {vcge\.f16\td[0-9]+, d[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {vcgt\.f16\td[0-9]+, d[0-9]+} 2 } } */ + +/* For float16x8_t. */ +/* { dg-final { scan-assembler-times {vceq\.f16\tq[0-9]+, q[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {vcge\.f16\tq[0-9]+, q[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {vcgt\.f16\tq[0-9]+, q[0-9]+} 2 } } */ /* { dg-final { scan-assembler-not {vadd\.f32} } } */ /* { dg-final { scan-assembler-not {vsub\.f32} } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-compare-1.c b/gcc/testsuite/gcc.target/arm/simd/mve-compare-1.c new file mode 100644 index 0000000..029c931 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-compare-1.c @@ -0,0 +1,80 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ +/* { dg-additional-options "-O3" } */ + +/* Integer tests. */ + +#define COMPARE_REG(NAME, OP, TYPE) \ + TYPE \ + cmp_##NAME##_##TYPE##_reg (TYPE a, TYPE b) \ + { \ + return a OP b; \ + } + +#define COMPARE_REG_AND_ZERO(NAME, OP, TYPE) \ + COMPARE_REG (NAME, OP, TYPE) \ + \ + TYPE \ + cmp_##NAME##_##TYPE##_zero (TYPE a) \ + { \ + return a OP (TYPE) {}; \ + } + +#define COMPARE_TYPE(TYPE, COMPARE_ORDERED) \ + COMPARE_REG_AND_ZERO (eq, ==, TYPE) \ + COMPARE_REG_AND_ZERO (ne, !=, TYPE) \ + COMPARE_ORDERED (lt, <, TYPE) \ + COMPARE_ORDERED (le, <=, TYPE) \ + COMPARE_ORDERED (gt, >, TYPE) \ + COMPARE_ORDERED (ge, >=, TYPE) + +#define TEST_TYPE(NAME, ELEM, COMPARE_ORDERED, SIZE) \ + typedef ELEM NAME##SIZE __attribute__((vector_size(SIZE))); \ + COMPARE_TYPE (NAME##SIZE, COMPARE_ORDERED) + +/* 64-bits vectors, not vectorized. */ +TEST_TYPE (vs8, __INT8_TYPE__, COMPARE_REG_AND_ZERO, 8) +TEST_TYPE (vu8, __UINT8_TYPE__, COMPARE_REG, 8) +TEST_TYPE (vs16, __INT16_TYPE__, COMPARE_REG_AND_ZERO, 8) +TEST_TYPE (vu16, __UINT16_TYPE__, COMPARE_REG, 8) +TEST_TYPE (vs32, __INT32_TYPE__, COMPARE_REG_AND_ZERO, 8) +TEST_TYPE (vu32, __UINT32_TYPE__, COMPARE_REG, 8) + +/* 128-bits vectors. */ +TEST_TYPE (vs8, __INT8_TYPE__, COMPARE_REG_AND_ZERO, 16) +TEST_TYPE (vu8, __UINT8_TYPE__, COMPARE_REG, 16) +TEST_TYPE (vs16, __INT16_TYPE__, COMPARE_REG_AND_ZERO, 16) +TEST_TYPE (vu16, __UINT16_TYPE__, COMPARE_REG, 16) +TEST_TYPE (vs32, __INT32_TYPE__, COMPARE_REG_AND_ZERO, 16) +TEST_TYPE (vu32, __UINT32_TYPE__, COMPARE_REG, 16) + +/* { 8 bits } x { eq, ne, lt, le, gt, ge, hi, cs }. +/* { dg-final { scan-assembler-times {\tvcmp.i8 eq, q[0-9]+, q[0-9]+\n} 4 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.i8 ne, q[0-9]+, q[0-9]+\n} 4 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s8 lt, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s8 le, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s8 gt, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s8 ge, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u8 hi, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u8 cs, q[0-9]+, q[0-9]+\n} 2 } } */ + +/* { 16 bits } x { eq, ne, lt, le, gt, ge, hi, cs }. +/* { dg-final { scan-assembler-times {\tvcmp.i16 eq, q[0-9]+, q[0-9]+\n} 4 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.i16 ne, q[0-9]+, q[0-9]+\n} 4 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s16 lt, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s16 le, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s16 gt, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s16 ge, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u16 hi, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u16 cs, q[0-9]+, q[0-9]+\n} 2 } } */ + +/* { 32 bits } x { eq, ne, lt, le, gt, ge, hi, cs }. +/* { dg-final { scan-assembler-times {\tvcmp.i32 eq, q[0-9]+, q[0-9]+\n} 4 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.i32 ne, q[0-9]+, q[0-9]+\n} 4 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s32 lt, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s32 le, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s32 gt, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s32 ge, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u32 hi, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u32 cs, q[0-9]+, q[0-9]+\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-compare-2.c b/gcc/testsuite/gcc.target/arm/simd/mve-compare-2.c new file mode 100644 index 0000000..8515195 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-compare-2.c @@ -0,0 +1,38 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ +/* { dg-add-options arm_v8_1m_mve_fp } */ +/* { dg-additional-options "-O3 -funsafe-math-optimizations" } */ + +/* float 32 tests. */ + +#ifndef ELEM_TYPE +#define ELEM_TYPE float +#endif +#ifndef INT_ELEM_TYPE +#define INT_ELEM_TYPE __INT32_TYPE__ +#endif + +#define COMPARE(NAME, OP) \ + int_vec \ + cmp_##NAME##_reg (vec a, vec b) \ + { \ + return a OP b; \ + } + +typedef INT_ELEM_TYPE int_vec __attribute__((vector_size(16))); +typedef ELEM_TYPE vec __attribute__((vector_size(16))); + +COMPARE (eq, ==) +COMPARE (ne, !=) +COMPARE (lt, <) +COMPARE (le, <=) +COMPARE (gt, >) +COMPARE (ge, >=) + +/* eq, ne, lt, le, gt, ge. +/* { dg-final { scan-assembler-times {\tvcmp.f32\teq, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f32\tne, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f32\tlt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f32\tle, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f32\tgt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f32\tge, q[0-9]+, q[0-9]+\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-compare-3.c b/gcc/testsuite/gcc.target/arm/simd/mve-compare-3.c new file mode 100644 index 0000000..76f81e8 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-compare-3.c @@ -0,0 +1,38 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ +/* { dg-add-options arm_v8_1m_mve_fp } */ +/* { dg-additional-options "-O3 -funsafe-math-optimizations" } */ + +/* float 16 tests. */ + +#ifndef ELEM_TYPE +#define ELEM_TYPE __fp16 +#endif +#ifndef INT_ELEM_TYPE +#define INT_ELEM_TYPE __INT16_TYPE__ +#endif + +#define COMPARE(NAME, OP) \ + int_vec \ + cmp_##NAME##_reg (vec a, vec b) \ + { \ + return a OP b; \ + } + +typedef INT_ELEM_TYPE int_vec __attribute__((vector_size(16))); +typedef ELEM_TYPE vec __attribute__((vector_size(16))); + +COMPARE (eq, ==) +COMPARE (ne, !=) +COMPARE (lt, <) +COMPARE (le, <=) +COMPARE (gt, >) +COMPARE (ge, >=) + +/* eq, ne, lt, le, gt, ge. +/* { dg-final { scan-assembler-times {\tvcmp.f16\teq, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f16\tne, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f16\tlt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f16\tle, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f16\tgt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f16\tge, q[0-9]+, q[0-9]+\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-compare-scalar-1.c b/gcc/testsuite/gcc.target/arm/simd/mve-compare-scalar-1.c new file mode 100644 index 0000000..7774972 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-compare-scalar-1.c @@ -0,0 +1,69 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ +/* { dg-additional-options "-O3" } */ + +#define COMPARE_REG(NAME, OP, TYPE, SCALAR) \ + TYPE \ + cmp_##NAME##_##TYPE##_scalar (TYPE a, SCALAR b) \ + { \ + return a OP b; \ + } + +#define COMPARE_TYPE(SCALAR, TYPE) \ + COMPARE_REG (eq, ==, TYPE, SCALAR) \ + COMPARE_REG (ne, !=, TYPE, SCALAR) \ + COMPARE_REG (lt, <, TYPE, SCALAR) \ + COMPARE_REG (le, <=, TYPE, SCALAR) \ + COMPARE_REG (gt, >, TYPE, SCALAR) \ + COMPARE_REG (ge, >=, TYPE, SCALAR) + +#define TEST_TYPE(NAME, ELEM, SIZE) \ + typedef ELEM NAME##SIZE __attribute__((vector_size(SIZE))); \ + COMPARE_TYPE (ELEM, NAME##SIZE) + +/* 64-bits vectors, not vectorized. */ +TEST_TYPE (vs8, __INT8_TYPE__, 8) +TEST_TYPE (vu8, __UINT8_TYPE__, 8) +TEST_TYPE (vs16, __INT16_TYPE__, 8) +TEST_TYPE (vu16, __UINT16_TYPE__, 8) +TEST_TYPE (vs32, __INT32_TYPE__, 8) +TEST_TYPE (vu32, __UINT32_TYPE__, 8) + +/* 128-bits vectors. */ +TEST_TYPE (vs8, __INT8_TYPE__, 16) +TEST_TYPE (vu8, __UINT8_TYPE__, 16) +TEST_TYPE (vs16, __INT16_TYPE__, 16) +TEST_TYPE (vu16, __UINT16_TYPE__, 16) +TEST_TYPE (vs32, __INT32_TYPE__, 16) +TEST_TYPE (vu32, __UINT32_TYPE__, 16) + +/* { 8 bits } x { eq, ne, lt, le, gt, ge, hi, cs }. +/* { dg-final { scan-assembler-times {\tvcmp.i8 eq, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.i8 ne, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s8 lt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s8 le, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s8 gt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s8 ge, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u8 hi, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u8 cs, q[0-9]+, q[0-9]+\n} 2 } } */ + +/* { 16 bits } x { eq, ne, lt, le, gt, ge, hi, cs }. +/* { dg-final { scan-assembler-times {\tvcmp.i16 eq, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.i16 ne, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s16 lt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s16 le, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s16 gt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s16 ge, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u16 hi, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u16 cs, q[0-9]+, q[0-9]+\n} 2 } } */ + +/* { 32 bits } x { eq, ne, lt, le, gt, ge, hi, cs }. +/* { dg-final { scan-assembler-times {\tvcmp.i32 eq, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.i32 ne, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s32 lt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s32 le, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s32 gt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s32 ge, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u32 hi, q[0-9]+, q[0-9]+\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u32 cs, q[0-9]+, q[0-9]+\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vadd-1.c b/gcc/testsuite/gcc.target/arm/simd/mve-vadd-1.c new file mode 100644 index 0000000..15a9daa --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vadd-1.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ +/* { dg-add-options arm_v8_1m_mve_fp } */ +/* { dg-additional-options "-O3" } */ + +#include <stdint.h> + +#define FUNC(SIGN, TYPE, BITS, NB, OP, NAME) \ + void test_ ## NAME ##_ ## SIGN ## BITS ## x ## NB (TYPE##BITS##_t * __restrict__ dest, \ + TYPE##BITS##_t *a, TYPE##BITS##_t *b) { \ + int i; \ + for (i=0; i<NB; i++) { \ + dest[i] = a[i] OP b[i]; \ + } \ +} + +/* 128-bit vectors. */ +FUNC(s, int, 32, 4, +, vadd) +FUNC(u, uint, 32, 4, +, vadd) +FUNC(s, int, 16, 8, +, vadd) +FUNC(u, uint, 16, 8, +, vadd) +FUNC(s, int, 8, 16, +, vadd) +FUNC(u, uint, 8, 16, +, vadd) + +/* { dg-final { scan-assembler-times {vadd\.i32 q[0-9]+, q[0-9]+, q[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {vadd\.i16 q[0-9]+, q[0-9]+, q[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {vadd\.i8 q[0-9]+, q[0-9]+, q[0-9]+} 2 } } */ + +void test_vadd_f32 (float * dest, float * a, float * b) { + int i; + for (i=0; i<4; i++) { + dest[i] = a[i] + b[i]; + } +} +/* { dg-final { scan-assembler-times {vadd\.f32 q[0-9]+, q[0-9]+, q[0-9]+} 1 } } */ + +void test_vadd_f16 (__fp16 * dest, __fp16 * a, __fp16 * b) { + int i; + for (i=0; i<8; i++) { + dest[i] = a[i] + b[i]; + } +} +/* { dg-final { scan-assembler-times {vadd\.f16 q[0-9]+, q[0-9]+, q[0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vadd-scalar-1.c b/gcc/testsuite/gcc.target/arm/simd/mve-vadd-scalar-1.c new file mode 100644 index 0000000..bbf70e1 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vadd-scalar-1.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ +/* { dg-add-options arm_v8_1m_mve_fp } */ +/* { dg-additional-options "-O3" } */ + +#include <stdint.h> + +#define FUNC_IMM(SIGN, TYPE, BITS, NB, OP, NAME) \ + void test_ ## NAME ##_ ## SIGN ## BITS ## x ## NB (TYPE##BITS##_t * __restrict__ dest, \ + TYPE##BITS##_t *a) { \ + int i; \ + for (i=0; i<NB; i++) { \ + dest[i] = a[i] OP 1; \ + } \ +} + +/* 128-bit vectors. */ +FUNC_IMM(s, int, 32, 4, +, vaddimm) +FUNC_IMM(u, uint, 32, 4, +, vaddimm) +FUNC_IMM(s, int, 16, 8, +, vaddimm) +FUNC_IMM(u, uint, 16, 8, +, vaddimm) +FUNC_IMM(s, int, 8, 16, +, vaddimm) +FUNC_IMM(u, uint, 8, 16, +, vaddimm) + +/* For the moment we do not select the T2 vadd variant operating on a scalar + final argument. */ +/* { dg-final { scan-assembler-times {vadd\.i32 q[0-9]+, q[0-9]+, r[0-9]+} 2 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {vadd\.i16 q[0-9]+, q[0-9]+, r[0-9]+} 2 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {vadd\.i8 q[0-9]+, q[0-9]+, r[0-9]+} 2 { xfail *-*-* } } } */ + +void test_vaddimm_f32 (float * dest, float * a) { + int i; + for (i=0; i<4; i++) { + dest[i] = a[i] + 5.0; + } +} +/* { dg-final { scan-assembler-times {vadd\.f32 q[0-9]+, q[0-9]+, r[0-9]+} 1 { xfail *-*-* } } } */ + +/* Note that dest[i] = a[i] + 5.0f16 is not vectorized. */ +void test_vaddimm_f16 (__fp16 * dest, __fp16 * a) { + int i; + __fp16 b = 5.0f16; + for (i=0; i<8; i++) { + dest[i] = a[i] + b; + } +} +/* { dg-final { scan-assembler-times {vadd\.f16 q[0-9]+, q[0-9]+, r[0-9]+} 1 { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f16.c b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f16.c new file mode 100644 index 0000000..dbae2d1 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f16.c @@ -0,0 +1,30 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ +/* { dg-add-options arm_v8_1m_mve_fp } */ +/* { dg-additional-options "-O3 -funsafe-math-optimizations" } */ + +#include <stdint.h> + +#define NB 8 + +#define FUNC(OP, NAME) \ + void test_ ## NAME ##_f (__fp16 * __restrict__ dest, __fp16 *a, __fp16 *b) { \ + int i; \ + for (i=0; i<NB; i++) { \ + dest[i] = a[i] OP b[i]; \ + } \ + } + +FUNC(==, vcmpeq) +FUNC(!=, vcmpne) +FUNC(<, vcmplt) +FUNC(<=, vcmple) +FUNC(>, vcmpgt) +FUNC(>=, vcmpge) + +/* { dg-final { scan-assembler-times {\tvcmp.f16\teq, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f16\tne, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f16\tlt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f16\tle, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f16\tgt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f16\tge, q[0-9]+, q[0-9]+\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f32.c b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f32.c new file mode 100644 index 0000000..4ed449e --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f32.c @@ -0,0 +1,30 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ +/* { dg-add-options arm_v8_1m_mve_fp } */ +/* { dg-additional-options "-O3 -funsafe-math-optimizations" } */ + +#include <stdint.h> + +#define NB 4 + +#define FUNC(OP, NAME) \ + void test_ ## NAME ##_f (float * __restrict__ dest, float *a, float *b) { \ + int i; \ + for (i=0; i<NB; i++) { \ + dest[i] = a[i] OP b[i]; \ + } \ + } + +FUNC(==, vcmpeq) +FUNC(!=, vcmpne) +FUNC(<, vcmplt) +FUNC(<=, vcmple) +FUNC(>, vcmpgt) +FUNC(>=, vcmpge) + +/* { dg-final { scan-assembler-times {\tvcmp.f32\teq, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f32\tne, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f32\tlt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f32\tle, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f32\tgt, q[0-9]+, q[0-9]+\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.f32\tge, q[0-9]+, q[0-9]+\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c new file mode 100644 index 0000000..8da15e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c @@ -0,0 +1,50 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ +/* { dg-additional-options "-O3" } */ + +#include <stdint.h> + +#define FUNC(SIGN, TYPE, BITS, NB, OP, NAME) \ + void test_ ## NAME ##_ ## SIGN ## BITS ## x ## NB (TYPE##BITS##_t * __restrict__ dest, TYPE##BITS##_t *a, TYPE##BITS##_t *b) { \ + int i; \ + for (i=0; i<NB; i++) { \ + dest[i] = a[i] OP b[i]; \ + } \ +} + +#define ALL_FUNCS(OP, NAME) \ + FUNC(s, int, 32, 2, OP, NAME) \ + FUNC(u, uint, 32, 2, OP, NAME) \ + FUNC(s, int, 16, 4, OP, NAME) \ + FUNC(u, uint, 16, 4, OP, NAME) \ + FUNC(s, int, 8, 8, OP, NAME) \ + FUNC(u, uint, 8, 8, OP, NAME) \ + FUNC(s, int, 32, 4, OP, NAME) \ + FUNC(u, uint, 32, 4, OP, NAME) \ + FUNC(s, int, 16, 8, OP, NAME) \ + FUNC(u, uint, 16, 8, OP, NAME) \ + FUNC(s, int, 8, 16, OP, NAME) \ + FUNC(u, uint, 8, 16, OP, NAME) + +ALL_FUNCS(==, vcmpeq) +ALL_FUNCS(!=, vcmpne) +ALL_FUNCS(<, vcmplt) +ALL_FUNCS(<=, vcmple) +ALL_FUNCS(>, vcmpgt) +ALL_FUNCS(>=, vcmpge) + +/* MVE has only 128-bit vectors, so we can vectorize only half of the + functions above. */ +/* { dg-final { scan-assembler-times {\tvcmp.i[0-9]+ eq, q[0-9]+, q[0-9]+\n} 6 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.i[0-9]+ ne, q[0-9]+, q[0-9]+\n} 6 } } */ + +/* lt, le, gt, ge apply to signed types, cs and hi to unsigned types. */ +/* lt and le with unsigned types are replaced with the opposite condition, hence + the double number of matches for cs and hi. */ +/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ lt, q[0-9]+, q[0-9]+\n} 3 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ le, q[0-9]+, q[0-9]+\n} 3 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ gt, q[0-9]+, q[0-9]+\n} 3 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ ge, q[0-9]+, q[0-9]+\n} 3 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u[0-9]+ cs, q[0-9]+, q[0-9]+\n} 6 } } */ +/* { dg-final { scan-assembler-times {\tvcmp.u[0-9]+ hi, q[0-9]+, q[0-9]+\n} 6 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vshr.c b/gcc/testsuite/gcc.target/arm/simd/mve-vshr.c index d4e658c..d4258e9 100644 --- a/gcc/testsuite/gcc.target/arm/simd/mve-vshr.c +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vshr.c @@ -55,5 +55,12 @@ FUNC_IMM(u, uint, 8, 16, >>, vshrimm) /* MVE has only 128-bit vectors, so we can vectorize only half of the functions above. */ +/* Vector right shifts use vneg and left shifts. */ +/* { dg-final { scan-assembler-times {vshl.s[0-9]+\tq[0-9]+, q[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {vshl.u[0-9]+\tq[0-9]+, q[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {vneg.s[0-9]+ q[0-9]+, q[0-9]+} 6 } } */ + + +/* Shift by immediate. */ /* { dg-final { scan-assembler-times {vshr.s[0-9]+\tq[0-9]+, q[0-9]+} 3 } } */ /* { dg-final { scan-assembler-times {vshr.u[0-9]+\tq[0-9]+, q[0-9]+} 3 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vsub_1.c b/gcc/testsuite/gcc.target/arm/simd/mve-vsub_1.c index 842e5c6..5a6c345 100644 --- a/gcc/testsuite/gcc.target/arm/simd/mve-vsub_1.c +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vsub_1.c @@ -5,60 +5,42 @@ #include <stdint.h> -void test_vsub_i32 (int32_t * dest, int32_t * a, int32_t * b) { - int i; - for (i=0; i<4; i++) { - dest[i] = a[i] - b[i]; - } +#define FUNC(SIGN, TYPE, BITS, NB, OP, NAME) \ + void test_ ## NAME ##_ ## SIGN ## BITS ## x ## NB (TYPE##BITS##_t * __restrict__ dest, \ + TYPE##BITS##_t *a, TYPE##BITS##_t *b) { \ + int i; \ + for (i=0; i<NB; i++) { \ + dest[i] = a[i] OP b[i]; \ + } \ } -void test_vsub_i32_u (uint32_t * dest, uint32_t * a, uint32_t * b) { - int i; - for (i=0; i<4; i++) { - dest[i] = a[i] - b[i]; - } -} +/* 128-bit vectors. */ +FUNC(s, int, 32, 4, -, vsub) +FUNC(u, uint, 32, 4, -, vsub) +FUNC(s, int, 16, 8, -, vsub) +FUNC(u, uint, 16, 8, -, vsub) +FUNC(s, int, 8, 16, -, vsub) +FUNC(u, uint, 8, 16, -, vsub) /* { dg-final { scan-assembler-times {vsub\.i32\tq[0-9]+, q[0-9]+, q[0-9]+} 2 } } */ - -void test_vsub_i16 (int16_t * dest, int16_t * a, int16_t * b) { - int i; - for (i=0; i<8; i++) { - dest[i] = a[i] - b[i]; - } -} - -void test_vsub_i16_u (uint16_t * dest, uint16_t * a, uint16_t * b) { - int i; - for (i=0; i<8; i++) { - dest[i] = a[i] - b[i]; - } -} - /* { dg-final { scan-assembler-times {vsub\.i16\tq[0-9]+, q[0-9]+, q[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {vsub\.i8\tq[0-9]+, q[0-9]+, q[0-9]+} 2 } } */ -void test_vsub_i8 (int8_t * dest, int8_t * a, int8_t * b) { - int i; - for (i=0; i<16; i++) { - dest[i] = a[i] - b[i]; - } -} - -void test_vsub_i8_u (uint8_t * dest, uint8_t * a, uint8_t * b) { +void test_vsub_f32 (float * dest, float * a, float * b) { int i; - for (i=0; i<16; i++) { + for (i=0; i<4; i++) { dest[i] = a[i] - b[i]; } } +/* { dg-final { scan-assembler-times {vsub\.f32\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */ -/* { dg-final { scan-assembler-times {vsub\.i8\tq[0-9]+, q[0-9]+, q[0-9]+} 2 } } */ -void test_vsub_f32 (float * dest, float * a, float * b) { +void test_vsub_f16 (__fp16 * dest, __fp16 * a, __fp16 * b) { int i; - for (i=0; i<4; i++) { + for (i=0; i<8; i++) { dest[i] = a[i] - b[i]; } } -/* { dg-final { scan-assembler-times {vsub\.f32\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vsub\.f16\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/unsigned-float.c b/gcc/testsuite/gcc.target/arm/unsigned-float.c index ad589d9..ea3abc7 100644 --- a/gcc/testsuite/gcc.target/arm/unsigned-float.c +++ b/gcc/testsuite/gcc.target/arm/unsigned-float.c @@ -1,8 +1,8 @@ /* { dg-do compile } */ -/* { dg-require-effective-target arm_fp_ok } */ -/* { dg-skip-if "need fp instructions" { *-*-* } { "-mfloat-abi=soft" } { "" } } */ /* { dg-skip-if "-mpure-code supports M-profile only" { *-*-* } { "-mpure-code" } } */ -/* { dg-options "-march=armv7-a -O1" } */ +/* { dg-options "-march=armv7-a+fp -mfpu=auto -O1" } */ +/* Do not require arm_ok effective target to avoid skipping on arm-eabi with + default configure options. */ /* { dg-add-options arm_fp } */ diff --git a/gcc/testsuite/gcc.target/i386/avx-pr82370.c b/gcc/testsuite/gcc.target/i386/avx-pr82370.c index 4dc8a5b..dc12dbf 100644 --- a/gcc/testsuite/gcc.target/i386/avx-pr82370.c +++ b/gcc/testsuite/gcc.target/i386/avx-pr82370.c @@ -4,7 +4,7 @@ /* { dg-final { scan-assembler-times "vpslld\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 3 } } */ /* { dg-final { scan-assembler-times "vpsllq\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 3 } } */ /* { dg-final { scan-assembler-times "vpsllw\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 3 } } */ -/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 3 } } */ +/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 6 } } */ /* { dg-final { scan-assembler-times "vpsraq\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 0 } } */ /* { dg-final { scan-assembler-times "vpsraw\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 3 } } */ /* { dg-final { scan-assembler-times "vpsrld\[ \t]\+\\\$5, %xmm\[0-9]\+, %xmm\[0-9]\+" 3 } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx-pr94680.c b/gcc/testsuite/gcc.target/i386/avx-pr94680.c new file mode 100644 index 0000000..cb5041b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-pr94680.c @@ -0,0 +1,107 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx -mno-avx512f -O2" } */ +/* { dg-final { scan-assembler-times {(?n)vmov[a-z0-9]*[ \t]*%xmm[0-9]} 12 } } */ +/* { dg-final { scan-assembler-not "pxor" } } */ + +typedef float v8sf __attribute__((vector_size(32))); +typedef double v4df __attribute__ ((vector_size (32))); +typedef long long v4di __attribute__((vector_size(32))); +typedef int v8si __attribute__((vector_size(32))); +typedef short v16hi __attribute__ ((vector_size (32))); +typedef char v32qi __attribute__ ((vector_size (32))); + +v4df +foo_v4df (v4df x) +{ + return __builtin_shuffle (x, (v4df) { 0, 0, 0, 0 }, (v4di) { 0, 1, 4, 5 }); +} + +v4df +foo_v4df_l (v4df x) +{ + return __builtin_shuffle ((v4df) { 0, 0, 0, 0 }, x, (v4di) { 4, 5, 1, 2 }); +} + +v4di +foo_v4di (v4di x) +{ + return __builtin_shuffle (x, (v4di) { 0, 0, 0, 0 }, (v4di) { 0, 1, 4, 7 }); +} + +v4di +foo_v4di_l (v4di x) +{ + return __builtin_shuffle ((v4di) { 0, 0, 0, 0 }, x, (v4di) { 4, 5, 3, 1 }); +} + +v8sf +foo_v8sf (v8sf x) +{ + return __builtin_shuffle ((v8sf) { 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v8si) { 8, 9, 10, 11, 0, 1, 2, 3 }); +} + +v8sf +foo_v8sf_l (v8sf x) +{ + return __builtin_shuffle (x, (v8sf) { 0, 0, 0, 0, 0, 0, 0, 0 }, + (v8si) { 0, 1, 2, 3, 8, 9, 10, 11 }); +} + +v8si +foo_v8si (v8si x) +{ + return __builtin_shuffle (x, (v8si) { 0, 0, 0, 0, 0, 0, 0, 0 }, + (v8si) { 0, 1, 2, 3, 13, 12, 11, 15 }); +} + +v8si +foo_v8si_l (v8si x) +{ + return __builtin_shuffle ((v8si) { 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v8si) { 8, 9, 10, 11, 7, 6, 5, 4 }); +} + +v16hi +foo_v16hi (v16hi x) +{ + return __builtin_shuffle (x, (v16hi) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + (v16hi) { 0, 1, 2, 3, 4, 5, 6, 7, + 24, 17, 26, 19, 28, 21, 30, 23 }); +} + +v16hi +foo_v16hi_l (v16hi x) +{ + return __builtin_shuffle ((v16hi) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v16hi) { 16, 17, 18, 19, 20, 21, 22, 23, + 15, 0, 13, 2, 11, 4, 9, 6 }); +} + +v32qi +foo_v32qi (v32qi x) +{ + return __builtin_shuffle (x, (v32qi) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + (v32qi) { 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 32, 49, 34, 58, 36, 53, 38, 39, + 40, 60, 42, 43, 63, 45, 46, 47 }); +} + +v32qi +foo_v32qi_l (v32qi x) +{ + return __builtin_shuffle ((v32qi) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v32qi) { 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 31, 0, 29, 2, 27, 4, 25, 6, + 23, 8, 21, 10, 19, 12, 17, 14 }); +} diff --git a/gcc/testsuite/gcc.target/i386/avx-psraq-1.c b/gcc/testsuite/gcc.target/i386/avx-psraq-1.c new file mode 100644 index 0000000..2722088 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-psraq-1.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavx -mno-avx2" } */ +/* { dg-require-effective-target avx } */ + +#ifndef CHECK_H +#define CHECK_H "avx-check.h" +#endif + +#ifndef TEST +#define TEST avx_test +#endif + +#include "sse2-psraq-1.c" diff --git a/gcc/testsuite/gcc.target/i386/avx2-pr82370.c b/gcc/testsuite/gcc.target/i386/avx2-pr82370.c index 6609ebb..df3dfd8 100644 --- a/gcc/testsuite/gcc.target/i386/avx2-pr82370.c +++ b/gcc/testsuite/gcc.target/i386/avx2-pr82370.c @@ -4,7 +4,7 @@ /* { dg-final { scan-assembler-times "vpslld\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllq\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllw\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ -/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 2 } } */ /* { dg-final { scan-assembler-times "vpsraq\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 0 } } */ /* { dg-final { scan-assembler-times "vpsraw\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsrld\[ \t]\+\\\$5, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ @@ -13,7 +13,7 @@ /* { dg-final { scan-assembler-times "vpslld\[ \t]\+\\\$7, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllq\[ \t]\+\\\$7, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllw\[ \t]\+\\\$7, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ -/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 2 } } */ /* { dg-final { scan-assembler-times "vpsraq\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 0 } } */ /* { dg-final { scan-assembler-times "vpsraw\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsrld\[ \t]\+\\\$5, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx2-pr99908.c b/gcc/testsuite/gcc.target/i386/avx2-pr99908.c new file mode 100644 index 0000000..2775f3b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-pr99908.c @@ -0,0 +1,25 @@ +/* PR target/99908 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx2 -masm=att" } */ +/* { dg-final { scan-assembler-times "\tvpblendvb\t" 2 } } */ +/* { dg-final { scan-assembler-not "\tvpcmpeq" } } */ +/* { dg-final { scan-assembler-not "\tvpandn" } } */ + +#include <x86intrin.h> + +__m256i +f1 (__m256i a, __m256i b, __m256i mask) +{ + return _mm256_blendv_epi8(a, b, + _mm256_andnot_si256(mask, _mm256_set1_epi8(255))); +} + +__m256i +f2 (__v32qi x, __v32qi a, __v32qi b) +{ + x ^= (__v32qi) { -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 }; + return _mm256_blendv_epi8 ((__m256i) a, (__m256i) b, (__m256i) x); +} diff --git a/gcc/testsuite/gcc.target/i386/avx2-psraq-1.c b/gcc/testsuite/gcc.target/i386/avx2-psraq-1.c new file mode 100644 index 0000000..e9051bf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-psraq-1.c @@ -0,0 +1,51 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavx2 -mno-avx512f" } */ +/* { dg-require-effective-target avx2 } */ + +#ifndef CHECK_H +#define CHECK_H "avx2-check.h" +#endif + +#ifndef TEST +#define TEST avx2_test +#endif + +#include CHECK_H + +typedef long long V __attribute__((vector_size (32))); + +#define TESTN(N) \ +static V \ +__attribute__((noipa)) \ +test##N (V x) \ +{ \ + return x >> N; \ +} + +#define TESTS TESTN (63) TESTN (49) TESTN (32) TESTN (31) TESTN (18) +TESTS + +struct +{ + int n; + V (*fn) (V); +} tests[] = { +#undef TESTN +#define TESTN(N) { N, test##N }, + TESTS +}; + +static void +TEST (void) +{ + V a = (V) { 0xdeadbeefcafebabeULL, 0x123456789abcdef0ULL, + 0x173a74be8a95134cULL, 0x817bae35ac0ebf12ULL }; + int i; + for (i = 0; tests[i].n; i++) + { + V c = tests[i].fn (a); + if (c[0] != a[0] >> tests[i].n || c[1] != a[1] >> tests[i].n + || c[2] != a[2] >> tests[i].n || c[3] != a[3] >> tests[i].n) + abort (); + } +} diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pr82370.c b/gcc/testsuite/gcc.target/i386/avx512bw-pr82370.c index 174f499..12c3b27 100644 --- a/gcc/testsuite/gcc.target/i386/avx512bw-pr82370.c +++ b/gcc/testsuite/gcc.target/i386/avx512bw-pr82370.c @@ -4,7 +4,7 @@ /* { dg-final { scan-assembler-times "vpslld\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllq\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllw\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ -/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 2 } } */ /* { dg-final { scan-assembler-times "vpsraq\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 0 } } */ /* { dg-final { scan-assembler-times "vpsraw\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsrld\[ \t]\+\\\$5, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ @@ -13,7 +13,7 @@ /* { dg-final { scan-assembler-times "vpslld\[ \t]\+\\\$7, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllq\[ \t]\+\\\$7, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllw\[ \t]\+\\\$7, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ -/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 2 } } */ /* { dg-final { scan-assembler-times "vpsraq\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 0 } } */ /* { dg-final { scan-assembler-times "vpsraw\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsrld\[ \t]\+\\\$5, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx512f-pr82370.c b/gcc/testsuite/gcc.target/i386/avx512f-pr82370.c index 20ad8dc..b179f9b 100644 --- a/gcc/testsuite/gcc.target/i386/avx512f-pr82370.c +++ b/gcc/testsuite/gcc.target/i386/avx512f-pr82370.c @@ -4,7 +4,7 @@ /* { dg-final { scan-assembler-times "vpslld\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllq\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllw\[ \t]\+\\\$7, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ -/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 2 } } */ /* { dg-final { scan-assembler-times "vpsraq\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 0 } } */ /* { dg-final { scan-assembler-times "vpsraw\[ \t]\+\\\$3, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsrld\[ \t]\+\\\$5, %xmm\[0-9]\+, %xmm\[0-9]\+" 1 } } */ @@ -13,7 +13,7 @@ /* { dg-final { scan-assembler-times "vpslld\[ \t]\+\\\$7, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllq\[ \t]\+\\\$7, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ /* { dg-final { scan-assembler-times "vpsllw\[ \t]\+\\\$7, %ymm\[0-9]\+, %ymm\[0-9]\+" 3 } } */ -/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "vpsrad\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 2 } } */ /* { dg-final { scan-assembler-times "vpsraq\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 0 } } */ /* { dg-final { scan-assembler-times "vpsraw\[ \t]\+\\\$3, %ymm\[0-9]\+, %ymm\[0-9]\+" 3 } } */ /* { dg-final { scan-assembler-times "vpsrld\[ \t]\+\\\$5, %ymm\[0-9]\+, %ymm\[0-9]\+" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx512f-pr94680.c b/gcc/testsuite/gcc.target/i386/avx512f-pr94680.c new file mode 100644 index 0000000..c27431a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512f-pr94680.c @@ -0,0 +1,144 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx512bw -mavx512vbmi -O2" } */ +/* { dg-final { scan-assembler-times {(?n)vmov[a-z0-9]*[ \t]*%ymm[0-9]} 12} } */ +/* { dg-final { scan-assembler-not "pxor" } } */ + + +typedef float v16sf __attribute__((vector_size(64))); +typedef double v8df __attribute__ ((vector_size (64))); +typedef long long v8di __attribute__((vector_size(64))); +typedef int v16si __attribute__((vector_size(64))); +typedef short v32hi __attribute__ ((vector_size (64))); +typedef char v64qi __attribute__ ((vector_size (64))); + +v8df +foo_v8df (v8df x) +{ + return __builtin_shuffle (x, (v8df) { 0, 0, 0, 0, 0, 0, 0, 0 }, + (v8di) { 0, 1, 2, 3, 15, 14, 10, 11 }); +} + +v8df +foo_v8df_l (v8df x) +{ + return __builtin_shuffle ((v8df) { 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v8di) { 8, 9, 10, 11, 0, 1, 2, 3 }); +} + +v8di +foo_v8di (v8di x) +{ + return __builtin_shuffle (x, (v8di) { 0, 0, 0, 0, 0, 0, 0, 0 }, + (v8di) { 0, 1, 2, 3, 8, 9, 10, 11 }); +} + +v8di +foo_v8di_l (v8di x) +{ + return __builtin_shuffle ((v8di) { 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v8di) { 8, 9, 10, 11, 7, 6, 5, 4 }); +} + +v16sf +foo_v16sf (v16sf x) +{ + return __builtin_shuffle (x, (v16sf) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + (v16si) { 0, 1, 2, 3, 4, 5, 6, 7, + 16, 17, 18, 19, 20, 21, 22, 23 }); +} + +v16sf +foo_v16sf_l (v16sf x) +{ + return __builtin_shuffle ((v16sf) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v16si) { 16, 17, 18, 19, 20, 21, 22, 23, + 0, 15, 2, 13, 4, 11, 6, 9 }); +} + +v16si +foo_v16si (v16si x) +{ + return __builtin_shuffle (x, (v16si) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + (v16si) { 0, 1, 2, 3, 4, 5, 6, 7, + 31, 30, 29, 28, 20, 21, 22, 23 }); +} + +v16si +foo_v16si_l (v16si x) +{ + return __builtin_shuffle ((v16si) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v16si) { 16, 17, 18, 19, 20, 21, 22, 23, + 15, 0, 13, 2, 11, 4, 9, 6 }); +} + +v32hi +foo_v32hi (v32hi x) +{ + return __builtin_shuffle (x, (v32hi) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + (v32hi) { 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 63, 33, 61, 35, 59, 37, 57, 39, + 55, 41, 53, 43, 51, 45, 49, 47 }); +} + +v32hi +foo_v32hi_l (v32hi x) +{ + return __builtin_shuffle ((v32hi) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v32hi) { 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 31, 0, 29, 2, 27, 4, 25, 6, + 23, 8, 21, 10, 19, 12, 17, 14 }); +} + +v64qi +foo_v64qi (v64qi x) +{ + return __builtin_shuffle (x, (v64qi) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + (v64qi) {0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 64, 127, 66, 125, 68, 123, 70, 121, + 72, 119, 74, 117, 76, 115, 78, 113, + 80, 111, 82, 109, 84, 107, 86, 105, + 88, 103, 90, 101, 92, 99, 94, 97 }); +} + +v64qi +foo_v64qi_l (v64qi x) +{ + return __builtin_shuffle ((v64qi) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v64qi) { 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 0, 63, 2, 61, 4, 59, 6, 57, + 8, 55, 10, 53, 12, 51, 14, 49, + 16, 47, 18, 45, 20, 43, 22, 41, + 24, 39, 26, 37, 28, 35, 30, 33 }); +} diff --git a/gcc/testsuite/gcc.target/i386/pr100342.c b/gcc/testsuite/gcc.target/i386/pr100342.c new file mode 100644 index 0000000..8e2ec82 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr100342.c @@ -0,0 +1,70 @@ +/* PR rtl-optimization/100342 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-O2 -fno-dse -fno-forward-propagate -Wno-psabi -mno-sse2" } */ + +#define SHL(x, y) ((x) << ((y) & (sizeof(x) * 8 - 1))) +#define SHR(x, y) ((x) >> ((y) & (sizeof(x) * 8 - 1))) +#define ROR(x, y) (SHR(x, y)) | (SHL(x, (sizeof(x) * 8 - (y)))) +#define SHLV(x, y) ((x) << ((y) & (sizeof((x)[0]) * 8 - 1))) +#define SHLSV(x, y) ((x) << ((y) & (sizeof((y)[0]) * 8 - 1))) +typedef unsigned char A; +typedef unsigned char __attribute__((__vector_size__ (8))) B; +typedef unsigned char __attribute__((__vector_size__ (16))) C; +typedef unsigned char __attribute__((__vector_size__ (32))) D; +typedef unsigned char __attribute__((__vector_size__ (64))) E; +typedef unsigned short F; +typedef unsigned short __attribute__((__vector_size__ (16))) G; +typedef unsigned int H; +typedef unsigned int __attribute__((__vector_size__ (32))) I; +typedef unsigned long long J; +typedef unsigned long long __attribute__((__vector_size__ (8))) K; +typedef unsigned long long __attribute__((__vector_size__ (32))) L; +typedef unsigned long long __attribute__((__vector_size__ (64))) M; +typedef unsigned __int128 N; +typedef unsigned __int128 __attribute__((__vector_size__ (16))) O; +typedef unsigned __int128 __attribute__((__vector_size__ (32))) P; +typedef unsigned __int128 __attribute__((__vector_size__ (64))) Q; +B v1; +D v2; +L v3; +K v4; +I v5; +O v6; + +B +foo (A a, C b, E c, F d, G e, H f, J g, M h, N i, P j, Q k) +{ + b &= (A) f; + k += a; + G l = e; + D m = v2 >= (A) (J) v1; + J r = a + g; + L n = v3 <= f; + k -= i / f; + l -= (A) g; + c |= (A) d; + b -= (A) i; + J o = ROR (__builtin_clz (r), a); + K p = v4 | f, q = v4 <= f; + P s = SHLV (SHLSV (__builtin_bswap64 (i), (P) (0 < j)) <= 0, j); + n += a <= r; + M t = (M) (a / SHLV (c, 0)) != __builtin_bswap64 (i); + I u = f - v5; + E v = (E) h + (E) t + (E) k; + D w = (union { D b[2]; }) { }.b[0] + ((union { E b; }) v).b[1] + m + (D) u + (D) n + (D) s; + C x = ((union { D b; }) w).b[1] + b + (C) l + (C) v6; + B y = ((union { C a; B b; }) x).b + ((union { C a; B b[2]; }) x).b[1] + (B) p + (B) q; + J z = i + o; + F z2 = z; + A z3 = z2; + return y + z3; +} + +int +main () +{ + B x = foo (0, (C) { }, (E) { }, 10, (G) { }, 4, 2, (M) { }, 123842323652213865LL, (P) { 1 }, (Q) { }); + if ((J) x != 0x2e2c2e2c2e2c2e30ULL) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr100504.c b/gcc/testsuite/gcc.target/i386/pr100504.c new file mode 100644 index 0000000..2910dfb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr100504.c @@ -0,0 +1,7 @@ +/* PR middle-end/100504 */ +/* { dg-do compile } */ + +__attribute__((target_clones(0))) +foo() +{ /* { dg-error ".target_clones. attribute argument not a string constant" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/pr100549.c b/gcc/testsuite/gcc.target/i386/pr100549.c new file mode 100644 index 0000000..83bba3c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr100549.c @@ -0,0 +1,108 @@ +/* PR target/100549 */ +/* { dg-do compile } */ +/* { dg-options "-O -mavx2" } */ + +typedef char v16qi __attribute__ ((vector_size (16))); +typedef char v32qi __attribute__ ((vector_size (32))); +typedef short v8hi __attribute__ ((vector_size (16))); +typedef short v16hi __attribute__ ((vector_size (32))); +typedef int v4si __attribute__ ((vector_size (16))); +typedef int v8si __attribute__ ((vector_size (32))); +typedef long long v2di __attribute__ ((vector_size (16))); +typedef long long v4di __attribute__ ((vector_size (32))); + +v16qi +f1 (v16qi a) +{ + return __builtin_ia32_pcmpeqb128 (a, a); +} + +v8hi +f2 (v8hi a) +{ + return __builtin_ia32_pcmpeqw128 (a, a); +} + +v4si +f3 (v4si a) +{ + return __builtin_ia32_pcmpeqd128 (a, a); +} + +v2di +f4 (v2di a) +{ + return __builtin_ia32_pcmpeqq (a, a); +} + +v16qi +f5 (v16qi a) +{ + return __builtin_ia32_pcmpgtb128 (a, a); +} + +v8hi +f6 (v8hi a) +{ + return __builtin_ia32_pcmpgtw128 (a, a); +} + +v4si +f7 (v4si a) +{ + return __builtin_ia32_pcmpgtd128 (a, a); +} + +v2di +f8 (v2di a) +{ + return __builtin_ia32_pcmpgtq (a, a); +} + +v32qi +f9 (v32qi a) +{ + return __builtin_ia32_pcmpeqb256 (a, a); +} + +v16hi +f10 (v16hi a) +{ + return __builtin_ia32_pcmpeqw256 (a, a); +} + +v8si +f11 (v8si a) +{ + return __builtin_ia32_pcmpeqd256 (a, a); +} + +v4di +f12 (v4di a) +{ + return __builtin_ia32_pcmpeqq256 (a, a); +} + +v32qi +f13 (v32qi a) +{ + return __builtin_ia32_pcmpgtb256 (a, a); +} + +v16hi +f14 (v16hi a) +{ + return __builtin_ia32_pcmpgtw256 (a, a); +} + +v8si +f15 (v8si a) +{ + return __builtin_ia32_pcmpgtd256 (a, a); +} + +v4di +f16 (v4di a) +{ + return __builtin_ia32_pcmpgtq256 (a, a); +} diff --git a/gcc/testsuite/gcc.target/i386/pr100582.c b/gcc/testsuite/gcc.target/i386/pr100582.c new file mode 100644 index 0000000..9520fe7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr100582.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mavx2" } */ + +typedef unsigned char v32qi __attribute__((vector_size(32))); + +v32qi +f2 (v32qi x, v32qi a, v32qi b) +{ + v32qi e; + for (int i = 0; i != 32; i++) + e[i] = x[i] ? a[i] : b[i]; + + return e; +} + +/* { dg-final { scan-assembler-times "pblendvb" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr98218-1.c b/gcc/testsuite/gcc.target/i386/pr98218-1.c index 48407da..9d6602c 100644 --- a/gcc/testsuite/gcc.target/i386/pr98218-1.c +++ b/gcc/testsuite/gcc.target/i386/pr98218-1.c @@ -1,4 +1,4 @@ -/* PR target/98522 */ +/* PR target/98218 */ /* { dg-do compile { target { ! ia32 } } } */ /* { dg-options "-O2 -msse2" } */ diff --git a/gcc/testsuite/gcc.target/i386/pr98218-1a.c b/gcc/testsuite/gcc.target/i386/pr98218-1a.c index 3470c87..2610438 100644 --- a/gcc/testsuite/gcc.target/i386/pr98218-1a.c +++ b/gcc/testsuite/gcc.target/i386/pr98218-1a.c @@ -1,4 +1,4 @@ -/* PR target/98522 */ +/* PR target/98218 */ /* { dg-do compile { target { ! ia32 } } } */ /* { dg-options "-O2 -ftree-vectorize -msse2" } */ diff --git a/gcc/testsuite/gcc.target/i386/pr98218-2.c b/gcc/testsuite/gcc.target/i386/pr98218-2.c index 0b71612..948bf4f 100644 --- a/gcc/testsuite/gcc.target/i386/pr98218-2.c +++ b/gcc/testsuite/gcc.target/i386/pr98218-2.c @@ -1,4 +1,4 @@ -/* PR target/98522 */ +/* PR target/98218 */ /* { dg-do compile { target { ! ia32 } } } */ /* { dg-options "-O2 -msse2" } */ diff --git a/gcc/testsuite/gcc.target/i386/pr98218-2a.c b/gcc/testsuite/gcc.target/i386/pr98218-2a.c index 6afd0a4..73c7226 100644 --- a/gcc/testsuite/gcc.target/i386/pr98218-2a.c +++ b/gcc/testsuite/gcc.target/i386/pr98218-2a.c @@ -1,4 +1,4 @@ -/* PR target/98522 */ +/* PR target/98218 */ /* { dg-do compile { target { ! ia32 } } } */ /* { dg-options "-O2 -ftree-vectorize -msse2" } */ diff --git a/gcc/testsuite/gcc.target/i386/pr98218-3.c b/gcc/testsuite/gcc.target/i386/pr98218-3.c index 83a8c29..1b40d0ce 100644 --- a/gcc/testsuite/gcc.target/i386/pr98218-3.c +++ b/gcc/testsuite/gcc.target/i386/pr98218-3.c @@ -1,4 +1,4 @@ -/* PR target/98522 */ +/* PR target/98218 */ /* { dg-do compile { target { ! ia32 } } } */ /* { dg-options "-O2 -msse2" } */ diff --git a/gcc/testsuite/gcc.target/i386/pr98218-3a.c b/gcc/testsuite/gcc.target/i386/pr98218-3a.c index 272d54e..cf1d497 100644 --- a/gcc/testsuite/gcc.target/i386/pr98218-3a.c +++ b/gcc/testsuite/gcc.target/i386/pr98218-3a.c @@ -1,4 +1,4 @@ -/* PR target/98522 */ +/* PR target/98218 */ /* { dg-do compile { target { ! ia32 } } } */ /* { dg-options "-O2 -ftree-vectorize -msse2" } */ diff --git a/gcc/testsuite/gcc.target/i386/pr98218-4.c b/gcc/testsuite/gcc.target/i386/pr98218-4.c new file mode 100644 index 0000000..647bdb1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr98218-4.c @@ -0,0 +1,16 @@ +/* PR target/98218 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -msse2" } */ + +typedef unsigned int __attribute__((__vector_size__ (8))) v64u32; +typedef int __attribute__((__vector_size__ (8))) v64s32; +typedef float __attribute__((__vector_size__ (8))) v64f32; + +v64u32 tu (v64f32 a, v64f32 b) { return a > b; } +v64s32 ts (v64f32 a, v64f32 b) { return a > b; } +v64f32 fu (v64u32 a, v64u32 b) { return a > b; } +v64f32 fs (v64s32 a, v64s32 b) { return a > b; } +v64f32 ff (v64f32 a, v64f32 b) { return a > b; } + +/* { dg-final { scan-assembler-times "cmpltps" 3 } } */ +/* { dg-final { scan-assembler-times "pcmpgtd" 2 } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse2-pr94680.c b/gcc/testsuite/gcc.target/i386/sse2-pr94680.c new file mode 100644 index 0000000..7e0ff9f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-pr94680.c @@ -0,0 +1,91 @@ +/* { dg-do compile } */ +/* { dg-options "-msse2 -mno-sse4.1 -O2" } */ +/* { dg-final { scan-assembler-times {(?n)(?:mov|psrldq).*%xmm[0-9]} 12 } } */ +/* { dg-final { scan-assembler-not "pxor" } } */ + +typedef float v4sf __attribute__((vector_size(16))); +typedef double v2df __attribute__ ((vector_size (16))); +typedef long long v2di __attribute__((vector_size(16))); +typedef int v4si __attribute__((vector_size(16))); +typedef short v8hi __attribute__ ((vector_size (16))); +typedef char v16qi __attribute__ ((vector_size (16))); + +v2df +foo_v2df (v2df x) +{ + return __builtin_shuffle (x, (v2df) { 0, 0 }, (v2di) {0, 2}); +} + +v2df +foo_v2df_l (v2df x) +{ + return __builtin_shuffle ((v2df) { 0, 0 }, x, (v2di) {3, 1}); +} + +v2di +foo_v2di (v2di x) +{ + return __builtin_shuffle (x, (v2di) { 0, 0 }, (v2di) {0, 3}); +} + +v2di +foo_v2di_l (v2di x) +{ + return __builtin_shuffle ((v2di) { 0, 0 }, x, (v2di) {3, 0}); +} + +v4sf +foo_v4sf (v4sf x) +{ + return __builtin_shuffle (x, (v4sf) { 0, 0, 0, 0 }, (v4si) {0, 1, 4, 5}); +} + +v4sf +foo_v4sf_l (v4sf x) +{ + return __builtin_shuffle ((v4sf) { 0, 0, 0, 0 }, x, (v4si) {4, 5, 3, 1}); +} + +v4si +foo_v4si (v4si x) +{ + return __builtin_shuffle (x, (v4si) { 0, 0, 0, 0 }, (v4si) {0, 1, 6, 7}); +} + +v4si +foo_v4si_l (v4si x) +{ + return __builtin_shuffle ((v4si) { 0, 0, 0, 0 }, x, (v4si) {4, 5, 1, 2}); +} + +v8hi +foo_v8hi (v8hi x) +{ + return __builtin_shuffle (x, (v8hi) { 0, 0, 0, 0, 0, 0, 0, 0 }, + (v8hi) { 0, 1, 2, 3, 8, 12, 10, 13 }); +} + +v8hi +foo_v8hi_l (v8hi x) +{ + return __builtin_shuffle ((v8hi) { 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v8hi) { 8, 9, 10, 11, 7, 6, 5, 4 }); +} + +v16qi +foo_v16qi (v16qi x) +{ + return __builtin_shuffle (x, (v16qi) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + (v16qi) {0, 1, 2, 3, 4, 5, 6, 7, + 16, 24, 18, 26, 20, 28, 22, 30 }); +} + +v16qi +foo_v16qi_l (v16qi x) +{ + return __builtin_shuffle ((v16qi) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, x, + (v16qi) { 16, 17, 18, 19, 20, 21, 22, 23, + 15, 0, 13, 2, 11, 4, 9, 6 }); +} diff --git a/gcc/testsuite/gcc.target/i386/sse2-psraq-1.c b/gcc/testsuite/gcc.target/i386/sse2-psraq-1.c new file mode 100644 index 0000000..9a08ee4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-psraq-1.c @@ -0,0 +1,53 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msse2 -mno-sse3" } */ +/* { dg-require-effective-target sse2 } */ + +#ifndef CHECK_H +#define CHECK_H "sse2-check.h" +#endif + +#ifndef TEST +#define TEST sse2_test +#endif + +#include CHECK_H + +typedef long long V __attribute__((vector_size (16))); + +#define TESTN(N) \ +static V \ +__attribute__((noipa)) \ +test##N (V x) \ +{ \ + return x >> N; \ +} + +#define TESTS TESTN (63) TESTN (49) TESTN (32) TESTN (31) TESTN (18) +TESTS + +struct +{ + int n; + V (*fn) (V); +} tests[] = { +#undef TESTN +#define TESTN(N) { N, test##N }, + TESTS +}; + +static void +TEST (void) +{ + V a = (V) { 0xdeadbeefcafebabeULL, 0x123456789abcdef0ULL }; + V b = (V) { 0x173a74be8a95134cULL, 0x817bae35ac0ebf12ULL }; + int i; + for (i = 0; tests[i].n; i++) + { + V c = tests[i].fn (a); + if (c[0] != a[0] >> tests[i].n || c[1] != a[1] >> tests[i].n) + abort (); + c = tests[i].fn (b); + if (c[0] != b[0] >> tests[i].n || c[1] != b[1] >> tests[i].n) + abort (); + } +} diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-pr99908.c b/gcc/testsuite/gcc.target/i386/sse4_1-pr99908.c new file mode 100644 index 0000000..c13e730 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-pr99908.c @@ -0,0 +1,23 @@ +/* PR target/99908 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse4.1 -mno-avx -masm=att" } */ +/* { dg-final { scan-assembler-times "\tpblendvb\t" 2 } } */ +/* { dg-final { scan-assembler-not "\tpcmpeq" } } */ +/* { dg-final { scan-assembler-not "\tpandn" } } */ + +#include <x86intrin.h> + +__m128i +f1 (__m128i a, __m128i b, __m128i mask) +{ + return _mm_blendv_epi8(a, b, + _mm_andnot_si128(mask, _mm_set1_epi8(255))); +} + +__m128i +f2 (__v16qi x, __v16qi a, __v16qi b) +{ + x ^= (__v16qi) { -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 }; + return _mm_blendv_epi8 ((__m128i) a, (__m128i) b, (__m128i) x); +} diff --git a/gcc/testsuite/gcc.target/i386/sse4_2-psraq-1.c b/gcc/testsuite/gcc.target/i386/sse4_2-psraq-1.c new file mode 100644 index 0000000..947b623 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_2-psraq-1.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msse4.2 -mno-avx" } */ +/* { dg-require-effective-target sse4 } */ + +#ifndef CHECK_H +#define CHECK_H "sse4_2-check.h" +#endif + +#ifndef TEST +#define TEST sse4_2_test +#endif + +#include "sse2-psraq-1.c" diff --git a/gcc/testsuite/gcc.target/powerpc/rop-1.c b/gcc/testsuite/gcc.target/powerpc/rop-1.c new file mode 100644 index 0000000..8cedcb6 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/rop-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mdejagnu-cpu=power10 -mrop-protect" } */ +/* { dg-require-effective-target powerpc_elfv2 } */ + +/* Verify that ROP-protect instructions are inserted when a + call is present. */ + +extern void foo (void); + +int bar () +{ + foo (); + return 5; +} + +/* { dg-final { scan-assembler-times {\mhashst\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mhashchk\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/rop-2.c b/gcc/testsuite/gcc.target/powerpc/rop-2.c new file mode 100644 index 0000000..c556952 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/rop-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mdejagnu-cpu=power10 -mrop-protect -mprivileged" } */ +/* { dg-require-effective-target powerpc_elfv2 } */ + +/* Verify that privileged ROP-protect instructions are inserted when a + call is present. */ + +extern void foo (void); + +int bar () +{ + foo (); + return 5; +} + +/* { dg-final { scan-assembler-times {\mhashstp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mhashchkp\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/rop-3.c b/gcc/testsuite/gcc.target/powerpc/rop-3.c new file mode 100644 index 0000000..8d03792 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/rop-3.c @@ -0,0 +1,18 @@ +/* { dg-do run { target { power10_hw } } } */ +/* { dg-require-effective-target powerpc_elfv2 } */ +/* { dg-options "-O2 -mdejagnu-cpu=power10 -mrop-protect" } */ + +/* Verify that ROP-protect instructions execute correctly when a + call is present. */ + +void __attribute__((noipa)) foo () +{ + asm (""); +} + +int main () +{ + foo (); + return 0; +} + diff --git a/gcc/testsuite/gcc.target/powerpc/rop-4.c b/gcc/testsuite/gcc.target/powerpc/rop-4.c new file mode 100644 index 0000000..dcf47c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/rop-4.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mdejagnu-cpu=power10 -mrop-protect" } */ +/* { dg-require-effective-target powerpc_elfv2 } */ + +/* Verify that no ROP-protect instructions are inserted when no + call is present. */ + + +int bar () +{ + return 5; +} + +/* { dg-final { scan-assembler-not {\mhashst\M} } } */ +/* { dg-final { scan-assembler-not {\mhashchk\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/rop-5.c b/gcc/testsuite/gcc.target/powerpc/rop-5.c new file mode 100644 index 0000000..cf04ea9 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/rop-5.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mdejagnu-cpu=power10 -mrop-protect" } */ + +/* Verify that __ROP_PROTECT__ is predefined for -mrop-protect. */ + +int foo () +{ +#ifndef __ROP_PROTECT__ + __ROP_PROTECT__ macro is not defined when it should be +#endif + return 0; +} + diff --git a/gcc/testsuite/gfortran.dg/gomp/implicit-save.f90 b/gcc/testsuite/gfortran.dg/gomp/implicit-save.f90 new file mode 100644 index 0000000..2af9647 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/implicit-save.f90 @@ -0,0 +1,11 @@ +subroutine foo + integer :: n = 5, m = 7 + !$omp declare target to(n) + !$omp threadprivate (m) +end + +program main + integer :: i, j + !$omp declare target to(i) + !$omp threadprivate (j) +end diff --git a/gcc/testsuite/gfortran.dg/gomp/parallel-master-1.f90 b/gcc/testsuite/gfortran.dg/gomp/parallel-master-1.f90 new file mode 100644 index 0000000..2ccc18f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/parallel-master-1.f90 @@ -0,0 +1,23 @@ +! { dg-additional-options "-fdump-tree-original" } + implicit none + integer :: k, p, s, r, nth, t, f + logical(kind=2) l2 + !$omp threadprivate (t) + + external bar + !$omp parallel master default(none) private (k) + call bar (k) + !$omp end parallel master + + !$omp parallel master private (p) firstprivate (f) if (parallel: l2) default(shared) & + !$omp& shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) copyin(t) + ! + !$omp end parallel master +end + +! { dg-final { scan-tree-dump "omp parallel private\\(k\\) default\\(none\\)" "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp master" 1 "original" } } +! { dg-final { scan-tree-dump "D.\[0-9\]+ = l2;" "original" } } +! { dg-final { scan-tree-dump "D.\[0-9\]+ = nth;" "original" } } +! { dg-final { scan-tree-dump "#pragma omp parallel private\\(p\\) firstprivate\\(f\\) shared\\(s\\) copyin\\(t\\) reduction\\(\\+:r\\) if\\(parallel:D.\[0-9\]+\\) num_threads\\(D.\[0-9\]+\\) default\\(shared\\) proc_bind\\(spread\\)" "original" } } + diff --git a/gcc/testsuite/gfortran.dg/gomp/parallel-master-2.f90 b/gcc/testsuite/gfortran.dg/gomp/parallel-master-2.f90 new file mode 100644 index 0000000..2e12de6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/parallel-master-2.f90 @@ -0,0 +1,9 @@ + use iso_c_binding, only: c_intptr_t + implicit none (external, type) + integer, parameter :: omp_event_handle_kind = c_intptr_t + integer (kind=omp_event_handle_kind) :: x + !$omp parallel master default (none) ! { dg-message "enclosing 'parallel'" } + !$omp task detach (x) ! { dg-error "'x' not specified in enclosing 'parallel'" } + !$omp end task + !$omp end parallel master +end diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-59.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-59.f90 new file mode 100644 index 0000000..65d04c2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-59.f90 @@ -0,0 +1,26 @@ +! PR fortran/100633 + +module defined_assign + interface assignment(=) + module procedure work_assign + end interface + + contains + subroutine work_assign(a,b) + integer, intent(out) :: a + logical, intent(in) :: b(:) + end subroutine work_assign +end module defined_assign + +program omp_workshare + use defined_assign + + integer :: a + logical :: l(10) + l = .TRUE. + + !$omp workshare + a = l ! { dg-error "Expected intrinsic assignment in OMP WORKSHARE" } + !$omp end workshare + +end program omp_workshare diff --git a/gcc/testsuite/gnat.dg/lto21.adb b/gcc/testsuite/gnat.dg/lto21.adb index fe6fb273..f626697 100644 --- a/gcc/testsuite/gnat.dg/lto21.adb +++ b/gcc/testsuite/gnat.dg/lto21.adb @@ -1,5 +1,6 @@ -- { dg-do run } -- { dg-options "-O3 -flto" { target lto } } +-- { dg-prune-output "warning: using serial compilation" } with Lto21_Pkg1; with Lto21_Pkg2; use Lto21_Pkg2; diff --git a/gcc/testsuite/lib/lto.exp b/gcc/testsuite/lib/lto.exp index 94a81ff..77919e8 100644 --- a/gcc/testsuite/lib/lto.exp +++ b/gcc/testsuite/lib/lto.exp @@ -159,6 +159,9 @@ proc lto_prune_warns { text } { regsub -all "(^|\n)\[ \t\]*\[\(\]file \[^\n\]* value=\[^\n\]*; file \[^\n\]* value=\[^\n\]*\[)\];" $text "" text regsub -all "(^|\n)\[ \t\]*\[^\n\]* definition taken" $text "" text + # Ignore missing jobserver for tests that do more than 1 LTRANS unit + regsub -all "(^|\n)\[^\n\]*: warning: using serial compilation of \[^\n\]*" $text "" text + # Ignore informational notes. regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 5700c23..8192da5 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -4180,24 +4180,24 @@ proc add_options_for_arm_simd32 { flags } { return "$flags $et_arm_simd32_flags" } -# Return 1 if this is an ARM target supporting the saturation intrinsics -# from arm_acle.h. Some multilibs may be incompatible with these options. -# Also set et_arm_qbit_flags to the best options to add. -# arm_acle.h includes stdint.h which can cause trouble with incompatible -# -mfloat-abi= options. - -proc check_effective_target_arm_qbit_ok_nocache { } { - global et_arm_qbit_flags - set et_arm_qbit_flags "" - foreach flags {"" "-march=armv5te" "-march=armv5te -mfloat-abi=softfp" "-march=armv5te -mfloat-abi=hard"} { - if { [check_no_compiler_messages_nocache et_arm_qbit_flags object { +# Return 1 if this is an ARM target supporting the __ssat and __usat +# saturation intrinsics from arm_acle.h. Some multilibs may be +# incompatible with these options. Also set et_arm_sat_flags to the +# best options to add. arm_acle.h includes stdint.h which can cause +# trouble with incompatible -mfloat-abi= options. + +proc check_effective_target_arm_sat_ok_nocache { } { + global et_arm_sat_flags + set et_arm_sat_flags "" + foreach flags {"" "-march=armv6" "-march=armv6 -mfloat-abi=softfp" "-march=armv6 -mfloat-abi=hard -mfpu=vfp"} { + if { [check_no_compiler_messages_nocache et_arm_sat_flags object { #include <arm_acle.h> int dummy; - #ifndef __ARM_FEATURE_QBIT - #error not QBIT + #ifndef __ARM_FEATURE_SAT + #error not SAT #endif } "$flags"] } { - set et_arm_qbit_flags $flags + set et_arm_sat_flags $flags return 1 } } @@ -4205,17 +4205,17 @@ proc check_effective_target_arm_qbit_ok_nocache { } { return 0 } -proc check_effective_target_arm_qbit_ok { } { - return [check_cached_effective_target et_arm_qbit_flags \ - check_effective_target_arm_qbit_ok_nocache] +proc check_effective_target_arm_sat_ok { } { + return [check_cached_effective_target et_arm_sat_flags \ + check_effective_target_arm_sat_ok_nocache] } -proc add_options_for_arm_qbit { flags } { - if { ! [check_effective_target_arm_qbit_ok] } { +proc add_options_for_arm_sat { flags } { + if { ! [check_effective_target_arm_sat_ok] } { return "$flags" } - global et_arm_qbit_flags - return "$flags $et_arm_qbit_flags" + global et_arm_sat_flags + return "$flags $et_arm_sat_flags" } # Return 1 if this is an ARM target supporting the DSP intrinsics from diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 11b86b2..075b1cc 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -649,7 +649,6 @@ private: void test_for_singularity (gimple *, avail_exprs_stack *); - dom_jump_threader_simplifier *m_simplifier; jump_threader *m_threader; evrp_range_analyzer *m_evrp_range_analyzer; }; diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 359367c..32e1632 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -593,6 +593,36 @@ add_repeat_to_ops_vec (vec<operand_entry *> *ops, tree op, reassociate_stats.pows_encountered++; } +/* Returns true if we can associate the SSA def OP. */ + +static bool +can_reassociate_op_p (tree op) +{ + if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op)) + return false; + /* Make sure asm goto outputs do not participate in reassociation since + we have no way to find an insertion place after asm goto. */ + if (TREE_CODE (op) == SSA_NAME + && gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_ASM + && gimple_asm_nlabels (as_a <gasm *> (SSA_NAME_DEF_STMT (op))) != 0) + return false; + return true; +} + +/* Returns true if we can reassociate operations of TYPE. + That is for integral or non-saturating fixed-point types, and for + floating point type when associative-math is enabled. */ + +static bool +can_reassociate_type_p (tree type) +{ + if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type)) + || NON_SAT_FIXED_POINT_TYPE_P (type) + || (flag_associative_math && FLOAT_TYPE_P (type))) + return true; + return false; +} + /* Return true if STMT is reassociable operation containing a binary operation with tree code CODE, and is inside LOOP. */ @@ -613,12 +643,8 @@ is_reassociable_op (gimple *stmt, enum tree_code code, class loop *loop) { tree rhs1 = gimple_assign_rhs1 (stmt); tree rhs2 = gimple_assign_rhs2 (stmt); - if (TREE_CODE (rhs1) == SSA_NAME - && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)) - return false; - if (rhs2 - && TREE_CODE (rhs2) == SSA_NAME - && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2)) + if (!can_reassociate_op_p (rhs1) + || (rhs2 && !can_reassociate_op_p (rhs2))) return false; return true; } @@ -5887,29 +5913,6 @@ repropagate_negates (void) } } -/* Returns true if OP is of a type for which we can do reassociation. - That is for integral or non-saturating fixed-point types, and for - floating point type when associative-math is enabled. */ - -static bool -can_reassociate_p (tree op) -{ - tree type = TREE_TYPE (op); - if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op)) - return false; - /* Make sure asm goto outputs do not participate in reassociation since - we have no way to find an insertion place after asm goto. */ - if (TREE_CODE (op) == SSA_NAME - && gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_ASM - && gimple_asm_nlabels (as_a <gasm *> (SSA_NAME_DEF_STMT (op))) != 0) - return false; - if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type)) - || NON_SAT_FIXED_POINT_TYPE_P (type) - || (flag_associative_math && FLOAT_TYPE_P (type))) - return true; - return false; -} - /* Break up subtract operations in block BB. We do this top down because we don't know whether the subtract is @@ -5942,14 +5945,15 @@ break_up_subtract_bb (basic_block bb) gimple_set_uid (stmt, uid++); if (!is_gimple_assign (stmt) - || !can_reassociate_p (gimple_assign_lhs (stmt))) + || !can_reassociate_type_p (TREE_TYPE (gimple_assign_lhs (stmt))) + || !can_reassociate_op_p (gimple_assign_lhs (stmt))) continue; /* Look for simple gimple subtract operations. */ if (gimple_assign_rhs_code (stmt) == MINUS_EXPR) { - if (!can_reassociate_p (gimple_assign_rhs1 (stmt)) - || !can_reassociate_p (gimple_assign_rhs2 (stmt))) + if (!can_reassociate_op_p (gimple_assign_rhs1 (stmt)) + || !can_reassociate_op_p (gimple_assign_rhs2 (stmt))) continue; /* Check for a subtract used only in an addition. If this @@ -5960,7 +5964,7 @@ break_up_subtract_bb (basic_block bb) break_up_subtract (stmt, &gsi); } else if (gimple_assign_rhs_code (stmt) == NEGATE_EXPR - && can_reassociate_p (gimple_assign_rhs1 (stmt))) + && can_reassociate_op_p (gimple_assign_rhs1 (stmt))) plus_negates.safe_push (gimple_assign_lhs (stmt)); } for (son = first_dom_son (CDI_DOMINATORS, bb); @@ -6553,14 +6557,14 @@ reassociate_bb (basic_block bb) /* For non-bit or min/max operations we can't associate all types. Verify that here. */ - if (rhs_code != BIT_IOR_EXPR - && rhs_code != BIT_AND_EXPR - && rhs_code != BIT_XOR_EXPR - && rhs_code != MIN_EXPR - && rhs_code != MAX_EXPR - && (!can_reassociate_p (lhs) - || !can_reassociate_p (rhs1) - || !can_reassociate_p (rhs2))) + if ((rhs_code != BIT_IOR_EXPR + && rhs_code != BIT_AND_EXPR + && rhs_code != BIT_XOR_EXPR + && rhs_code != MIN_EXPR + && rhs_code != MAX_EXPR + && !can_reassociate_type_p (TREE_TYPE (lhs))) + || !can_reassociate_op_p (rhs1) + || !can_reassociate_op_p (rhs2)) continue; if (associative_tree_code (rhs_code)) diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index e54a0c9..e876121 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -4529,7 +4529,8 @@ dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back) /* Iterate to the single executable bb2 successor. */ edge succe = NULL; FOR_EACH_EDGE (e, ei, bb2->succs) - if (e->flags & EDGE_EXECUTABLE) + if ((e->flags & EDGE_EXECUTABLE) + || (!allow_back && (e->flags & EDGE_DFS_BACK))) { if (succe) { @@ -4547,7 +4548,8 @@ dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back) { FOR_EACH_EDGE (e, ei, succe->dest->preds) if (e != succe - && (e->flags & EDGE_EXECUTABLE)) + && ((e->flags & EDGE_EXECUTABLE) + || (!allow_back && (e->flags & EDGE_DFS_BACK)))) { succe = NULL; break; diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index 0800f59..f55ce19 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -209,6 +209,16 @@ check_defs (ao_ref *ref, tree vdef, void *data_) { check_defs_data *data = (check_defs_data *)data_; gimple *def_stmt = SSA_NAME_DEF_STMT (vdef); + + /* The ASAN_MARK intrinsic doesn't modify the variable. */ + if (is_gimple_call (def_stmt) + && gimple_call_internal_p (def_stmt, IFN_ASAN_MARK)) + return false; + + /* End of VLA scope is not a kill. */ + if (gimple_call_builtin_p (def_stmt, BUILT_IN_STACK_RESTORE)) + return false; + /* If this is a clobber then if it is not a kill walk past it. */ if (gimple_clobber_p (def_stmt)) { @@ -216,6 +226,7 @@ check_defs (ao_ref *ref, tree vdef, void *data_) return true; return false; } + /* Found a may-def on this path. */ data->found_may_defs = true; return true; @@ -12550,13 +12550,11 @@ array_at_struct_end_p (tree ref) || ! TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) return true; - if (TREE_CODE (ref) == MEM_REF - && TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR) - ref = TREE_OPERAND (TREE_OPERAND (ref, 0), 0); - /* If the reference is based on a declared entity, the size of the array is constrained by its given domain. (Do not trust commons PR/69368). */ - if (DECL_P (ref) + ref = get_base_address (ref); + if (ref + && DECL_P (ref) && !(flag_unconstrained_commons && VAR_P (ref) && DECL_COMMON (ref)) && DECL_SIZE_UNIT (ref) |