diff options
author | Christophe Lyon <christophe.lyon@linaro.org> | 2015-05-13 12:09:07 +0000 |
---|---|---|
committer | Christophe Lyon <christophe.lyon@linaro.org> | 2015-05-13 12:09:07 +0000 |
commit | f435d8639e05eab0c7cf272fe87996ca797d31ca (patch) | |
tree | 85041b1041801bc88e8f6764f1613e4cdd7e7aeb | |
parent | d7d8485f6cc7e2ec462f761f77fc043c7343cf13 (diff) | |
parent | 4b7a6db96158f20a0ff42098cdfdbb2f20b5d0e1 (diff) |
Merge branches/gcc-4_8-branch rev 222653
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_8-branch@223153 138bc75d-0d04-0410-961f-82ee72b054a4
256 files changed, 6139 insertions, 1100 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1b3ced8e2ba..287013afc87 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,590 @@ +2015-04-30 Marek Polacek <polacek@redhat.com> + + Backported from mainline + 2014-12-03 Martin Jambor <mjambor@suse.cz> + + PR ipa/64153 + * ipa-inline-analysis.c (evaluate_conditions_for_known_args): Check + type sizes before view_converting. + + 2014-12-01 Martin Jambor <mjambor@suse.cz> + + PR ipa/63551 + * ipa-inline-analysis.c (evaluate_conditions_for_known_args): Convert + value of the argument to the type of the value in the condition. + +2015-04-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport from mainline r222385 + 2015-04-23 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + * config/rs6000/altivec.md (*altivec_lvx_<mode>_internal): Remove + asterisk from name so this can be generated directly. + (*altivec_stvx_<mode>_internal): Likewise. + * config/rs6000/rs6000.c (rs6000_emit_le_vsx_store): Add assert + that this is never called during or after reload/lra. + (rs6000_frame_related): Remove split_reg + argument and logic that references it. + (emit_frame_save): Remove last parameter from call to + rs6000_frame_related. + (rs6000_emit_prologue): Remove last parameter from eight calls to + rs6000_frame_related. Force generation of stvx instruction for + Altivec register saves. Remove split_reg handling, which is no + longer needed. + (rs6000_emit_epilogue): Force generation of lvx instruction for + Altivec register restores. + +2015-04-24 Michael Meissner <meissner@linux.vnet.ibm.com> + + Backport from mainline + 2015-04-24 Michael Meissner <meissner@linux.vnet.ibm.com> + + PR target/65849 + * config/rs6000/rs6000.opt (-mvsx-align-128): Make options that + save to independent variables use the Save attribute. This will + allow these options to be modified with the #pragma/attribute + target support. + (-mallow-movmisalign): Likewise. + (-mallow-df-permute): Likewise. + (-msched-groups): Likewise. + (-malways-hint): Likewise. + (-malign-branch-targets): Likewise. + (-mvectorize-builtins): Likewise. + (-msave-toc-indirect): Likewise. + + * config/rs6000/rs6000.c (rs6000_opt_masks): Add more options that + can be set via the #pragma/attribute target support. + (rs6000_opt_vars): Likewise. + (rs6000_inner_target_options): If VSX was set, also set + -mno-avoid-indexed-addresses. + +2015-04-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport from mainline r222362 + 2015-04-23 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + * config/rs6000/crypto.md (crypto_vpmsum<CR_char>): Change + TARGET_CRYPTO to TARGET_P8_VECTOR> + (crypto_vpermxor_<mode>): Likewise. + * config/rs6000/rs6000-builtin.def (BU_CRYPTO_2A): New #define. + (BU_CRYPTO_3A): Likewise. + (BU_CRYPTO_OVERLOAD_2A): Rename from BU_CRYPTO_OVERLOAD_2. + (BU_CRYPTO_OVERLOAD_3A): New #define. + (VPMSUMB): Change from BU_CRYPTO_2 to BU_CRYPTO_2A. + (VPMSUMH): Likewise. + (VPMSUMW): Likewise. + (VPMSUMD): Likewise. + (VPERMXOR_V2DI): Change from BU_CRYPTO_3 to BU_CRYPTO_3A. + (VPERMXOR_V4SI): Likewise. + (VPERMXOR_V8HI): Likewise. + (VPERMXOR_V16QI): Likewise. + (VPMSUM): Change from BU_CRYPTO_OVERLOAD_2 to + BU_CRYPTO_OVERLOAD_2A. + (VPERMXOR): Change from BU_CRYPTO_OVERLOAD3 to + BU_CRYPTO_OVERLOAD_3A. + * config/rs6000/rs6000.opt (mcrypto): Change description of + option. + + Backport from mainline r222362 + 2015-04-23 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + * config/rs6000/rs6000.opt (mcrypto): Change option description to + match category changes in ISA 2.07B. + +2015-04-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport from mainline r222351 + 2015-04-22 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + * config/rs6000/rs6000.c (rtx_is_swappable_p): Commentary + adjustments. + (insn_is_swappable_p): Return 1 for a convert from double to + single precision when all of its uses are splats of BE element + zero. + +2015-04-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport from mainline r222349 + 2015-04-22 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + PR target/65456 + * config/rs6000/rs6000.c (rs6000_option_override_internal): For + VSX + POWER8, enable TARGET_ALLOW_MOVMISALIGN and + TARGET_EFFICIENT_UNALIGNED_VSX if not selected by command line + option. + (rs6000_builtin_mask_for_load): Return 0 for targets with + efficient unaligned VSX accesses so that the vectorizer will use + direct unaligned loads. + (rs6000_builtin_support_vector_misalignment): Always return true + for targets with efficient unaligned VSX accesses. + (rs6000_builtin_vectorization_cost): Cost of unaligned loads and + stores on targets with efficient unaligned VSX accesses is almost + always the same as the cost of an aligned load or store, so model + it that way. + * config/rs6000/rs6000.h (SLOW_UNALIGNED_ACCESS): Return 0 for + unaligned vectors if we have efficient unaligned VSX accesses. + * config/rs6000/rs6000.opt (mefficient-unaligned-vector): New + undocumented option. + +2015-04-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + Jakub Jelinek <jakub@redhat.com> + + Backport from mainline r222205 + 2015-04-17 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + Jakub Jelinek <jakub@redhat.com> + + PR target/65787 + * config/rs6000/rs6000.c (rtx_is_swappable_p): Ensure that a + subsequent SH_NONE operand does not overwrite an existing *special + value. + (adjust_extract): Handle case where a vec_extract operation is + wrapped in a PARALLEL. + +2015-04-02 John David Anglin <danglin@gcc.gnu.org> + + * config/pa/pa.c (pa_output_move_double): Directly handle register + indexed memory operand. Simplify handling of scaled register indexed + memory operands. + +2015-03-31 Dominik Vogt <vogt@linux.vnet.ibm.com> + + * config/s390/s390.c (s390_function_num_hotpatch_hw): Allow hotpatching + nested functions. + (s390_reorg): Adapt to new signature of s390_function_num_hotpatch_hw. + (s390_asm_output_function_label): Adapt to new signature of + s390_function_num_hotpatch_hw + Optimise the code generating assembler output. + Add comments to assembler file. + +2015-03-31 Dominik Vogt <vogt@linux.vnet.ibm.com> + + * config/s390/s390.c (s390_function_num_hotpatch_hw): Remove special + cases for not hotpatching main () and artificial functions. + +2015-03-26 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport of r214242, r214254, and bug fix patches from mainline + * config/rs6000/rs6000.c (tree-pass.h): New #include. + (rs6000_analyze_swaps): New declaration. + (gate_analyze_swaps): New function. + (execute_analyze_swaps): Likewise. + (pass_analyze_swaps): New struct rtl_opt_pass. + (rs6000_option_override): Register swap-optimization pass. + (swap_web_entry): New class. + (special_handling_values): New enum. + (union_defs): New function. + (union_uses): Likewise. + (insn_is_load_p): Likewise. + (insn_is_store_p): Likewise. + (insn_is_swap_p): Likewise. + (rtx_is_swappable_p): Likewise. + (insn_is_swappable_p): Likewise. + (chain_purpose): New enum. + (chain_contains_only_swaps): New function. + (mark_swaps_for_removal): Likewise. + (swap_const_vector_halves): Likewise. + (adjust_subreg_index): Likewise. + (permute_load): Likewise. + (permute_store): Likewise. + (adjust_extract): Likewise. + (adjust_splat): Likewise. + (handle_special_swappables): Likewise. + (replace_swap_with_copy): Likewise. + (dump_swap_insn_table): Likewise. + (rs6000_analyze_swaps): Likewise. + * config/rs6000/rs6000.opt (moptimize-swaps): New option. + * df.h (web_entry_base): New class, replacing struct web_entry. + (web_entry_base::pred): New method. + (web_entry_base::set_pred): Likewise. + (web_entry_base::unionfind_root): Likewise. + (web_entry_base::unionfind_union): Likewise. + (unionfind_root): Delete external reference. + (unionfind_union): Likewise. + (union_defs): Likewise. + * web.c (web_entry_base::unionfind_root): Convert to method. + (web_entry_base::unionfind_union): Likewise. + (web_entry): New class. + (union_match_dups): Convert to use class structure. + (union_defs): Likewise. + (entry_register): Likewise. + (web_main): Likewise. + +2015-03-26 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + * config/rs6000/vsx.md (*vsx_extract_<mode>_zero): Remove + endianness requirement. + (*vsx_extract_<mode>_one_le): Remove define_insn. + +2015-03-26 Oleg Endo <olegendo@gcc.gnu.org> + + Backport from mainline + 2015-03-26 Oleg Endo <olegendo@gcc.gnu.org> + + * config/sh/t-sh (MULTILIB_EXCEPTIONS): Handle default endian. + +2015-03-16 Eric Botcazou <ebotcazou@adacore.com> + + PR middle-end/65409 + * expr.c (store_field): Do not do a direct block copy if the source is + a PARALLEL with BLKmode. + +2015-03-12 Dominik Vogt <vogt@linux.vnet.ibm.com> + + * config/s390/s390.c (s390_reorg): Move code to output nops after label + to s390_reorg (). + (s390_asm_output_function_label): Likewise. + * config/s390/s390.c (s390_asm_output_function_label): + Fix function label alignment with -mhtopatch. + * config/s390/s390.md ("unspecv"): New values UNSPECV_NOP_2_BYTE, + UNSPECV_NOP_4_BYTE and UNSPECV_NOP_6_BYTE + ("nop_2_byte"): New define_insn. + ("nop_4_byte"): Likewise. + ("nop_6_byte"): Likewise. + * doc/extend.texi (hotpatch): hotpatch attribute doc fixes. + * doc/invoke.texi (-mhotpatch): -mhotpatch doc fixes. + +2015-03-12 Marek Polacek <polacek@redhat.com> + + Backport from mainline + 2015-03-11 Marek Polacek <polacek@redhat.com> + + PR tree-optimization/65388 + * tree-ssa-tail-merge.c (same_succ_def::equal): Fix typo in comparison. + +2015-03-10 Jakub Jelinek <jakub@redhat.com> + + PR target/65286 + * config/rs6000/t-linux: For powerpc64* target set + MULTILIB_OSDIRNAMES instead of MULTIARCH_DIRNAME. + +2015-03-10 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/53988 + * config/sh/sh.md (*tst<mode>_t_zero): Remove insns. + +2015-03-10 Alan Modra <amodra@gmail.com> + + PR target/65286 + * config.gcc (powerpc*-*-linux*): Arrange for powerpc64le-linux + to be single-arch by default. Set cpu_is_64bit for powerpc64 + given --with-cpu=native. + * config/rs6000/t-fprules: Do not set default MULTILIB vars. + * config/rs6000/t-linux (MULTIARCH_DIRNAME): Support powerpc64 + and powerpc64le. + * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Test + rs6000_isa_flags rather than TARGET_64BIT. + +2015-03-05 Michael Meissner <meissner@linux.vnet.ibm.com> + + Backport from trunk + 2015-03-03 Michael Meissner <meissner@linux.vnet.ibm.com> + + PR 65138/target + * config/rs6000/rs6000-cpus.def (powerpc64le): Add new generic + processor type for 64-bit little endian PowerPC. + + * config/rs6000/rs6000.c (rs6000_option_override_internal): If + -mdebug=reg, print TARGET_DEFAULT. Fix logic to use + TARGET_DEFAULT if there is no default cpu. Fix -mdebug=reg + printing built-in mask so it does not pass NULL pointers. + + * config/rs6000/rs6000-tables.opt: Regenerate. + + * doc/invoke.texi (IBM RS/6000 and PowerPC options): Document + -mcpu=powerpc64le. + + Backport from trunk + 2015-01-19 David Edelsohn <dje.gcc@gmail.com> + + * config/rs6000/default64.h: Include rs6000-cpus.def. + (TARGET_DEFAULT) [LITTLE_ENDIAN]: Use ISA 2.7 (POWER8). + (TARGET_DEFAULT) [BIG_ENDIAN]: Use POWER4. + * config/rs6000/driver-rs6000.c (detect_processor_aix): Add POWER7 + and POWER8. + * config/rs6000/linux64.h (PROCESSOR_DEFAULT64): Always default to + POWER8. + * config/rs6000/rs6000.c (rs6000_file_start): Emit .machine + pseudo-op to specify assembler dialect. + +2015-03-04 Thomas Preud'homme <thomas.preudhomme@arm.com> + + Backport from mainline + 2014-11-27 Thomas Preud'homme <thomas.preudhomme@arm.com> + + PR target/59593 + * config/arm/arm.c (dump_minipool): dispatch to consttable pattern + based on mode size. + * config/arm/arm.md (consttable_1): Make it TARGET_EITHER. + (consttable_2): Make it TARGET_EITHER and move HFmode handling from + consttable_4 to it. + (consttable_4): Move HFmode handling to consttable_2 pattern. + +2015-03-04 Thomas Preud'homme <thomas.preudhomme@arm.com> + + Backport from mainline + 2015-01-14 Thomas Preud'homme <thomas.preudhomme@arm.com> + + PR target/64453 + * config/arm/arm.c (callee_saved_reg_p): Define. + (arm_compute_save_reg0_reg12_mask): Use callee_saved_reg_p to check if + register is callee saved instead of !call_used_regs[reg]. + (thumb1_compute_save_reg_mask): Likewise. + +2015-02-27 Richard Biener <rguenther@suse.de> + + PR lto/65193 + Backport from mainline + 2014-07-24 Jan Hubicka <hubicka@ucw.cz> + + * lto-streamer-out.c (tree_is_indexable): Consider IMPORTED_DECL + as non-indexable. + +2015-02-26 Peter Bergner <bergner@vnet.ibm.com> + + Backport from mainline + 2015-02-25 Adhemerval Zanella <azanella@linux.vnet.ibm.com> + + * config/rs6000/htm.md (tcheck): Fix assembly encoding. + +2015-02-26 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2014-11-27 Richard Biener <rguenther@suse.de> + + PR tree-optimization/61634 + * tree-vect-slp.c: (vect_detect_hybrid_slp_stmts): Rewrite to + propagate hybrid down the SLP tree for one scalar statement. + (vect_detect_hybrid_slp_1): New walker function. + (vect_detect_hybrid_slp_2): Likewise. + (vect_detect_hybrid_slp): Properly handle pattern statements + in a pre-scan over all loop stmts. + +2015-02-25 Georg-Johann Lay <avr@gjlay.de> + + PR target/65196 + * config/avr/avr.c (avr_adjust_insn_length): Call recog_memoized + only with NONDEBUG_INSN_P. + +2015-02-25 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2015-02-16 Richard Biener <rguenther@suse.de> + + PR tree-optimization/63593 + * tree-predcom.c (execute_pred_commoning_chain): Delay removing + stmts and releasing SSA names until... + (execute_pred_commoning): ... after processing all chains. + + 2015-02-18 Richard Biener <rguenther@suse.de> + + PR tree-optimization/65063 + * tree-predcom.c (determine_unroll_factor): Return 1 if we + have replaced looparound PHIs. + +2015-02-24 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2014-11-19 Richard Biener <rguenther@suse.de> + + PR tree-optimization/63844 + * omp-low.c (fixup_child_record_type): Use a restrict qualified + referece type for the receiver parameter. + +2015-02-24 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2014-12-09 Richard Biener <rguenther@suse.de> + + PR middle-end/64199 + * fold-const.c (fold_binary_loc): Use TREE_OVERFLOW_P. + + 2015-01-14 Richard Biener <rguenther@suse.de> + + PR tree-optimization/64493 + PR tree-optimization/64495 + * tree-vect-loop.c (vect_finalize_reduction): For double-reductions + assign the proper vectorized PHI to the inner loop exit PHIs. + +2015-02-24 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2015-01-27 Richard Biener <rguenther@suse.de> + + PR tree-optimization/56273 + PR tree-optimization/59124 + PR tree-optimization/64277 + * tree-vrp.c (vrp_finalize): Emit array-bound warnings only + from the first VRP pass. + +2015-02-24 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2015-02-11 Richard Biener <rguenther@suse.de> + + PR lto/65015 + * dwarf2out.c (gen_producer_string): Drop -fltrans-output-list + and -fresolution. + + 2015-02-13 Richard Biener <rguenther@suse.de> + + PR lto/65015 + * dwarf2out.c (dwarf2out_finish): Use <artificial> as DW_AT_name + for LTO produced CUs. + + 2015-02-16 Richard Biener <rguenther@suse.de> + + PR lto/65015 + * varasm.c (default_file_start): For LTO produced units + emit <artificial> as file directive. + + 2015-01-17 Jan Kratochvil <jan.kratochvil@redhat.com> + + * dwarf2out.c (gen_producer_string): Ignore also OPT_fpreprocessed. + +2015-02-23 Oleg Endo <olegendo@gcc.gnu.org> + + Backport from mainline + 2015-02-23 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/65163 + * config/sh/sh.md (swapbsi2, related peephole2): Use const_int -65536 + instead of const_int 4294901760. + +2015-02-23 Dominik Vogt <vogt@linux.vnet.ibm.com> + + Backport from mainline + 2015-01-27 Dominik Vogt <vogt@linux.vnet.ibm.com> + + * doc/extend.texi: s/390: Update documentation of hotpatch attribute. + * doc/invoke.texi (-mhotpatch): s/390: Update documentation of + -mhotpatch= option. + * config/s390/s390.opt (mhotpatch): s/390: Remove -mhotpatch and + -mno-hotpatch options. Change syntax of -mhotpatch= option. + * config/s390/s390.c (s390_hotpatch_trampoline_halfwords_default): + Renamed. + (s390_hotpatch_trampoline_halfwords_max): Renamed. + (s390_hotpatch_hw_max): New name. + (s390_hotpatch_trampoline_halfwords): Renamed. + (s390_hotpatch_hw_before_label): New name. + (get_hotpatch_attribute): Removed. + (s390_hotpatch_hw_after_label): New name. + (s390_handle_hotpatch_attribute): Add second parameter to hotpatch + attribute. + (s390_attribute_table): Ditto. + (s390_function_num_hotpatch_trampoline_halfwords): Renamed. + (s390_function_num_hotpatch_hw): New name. + Remove special handling of inline functions and hotpatching. + Return number of nops before and after the function label. + (s390_can_inline_p): Removed. + (s390_asm_output_function_label): Emit a configurable number of nops + after the function label. + (s390_option_override): Update -mhotpatch= syntax and remove -mhotpatch. + (TARGET_CAN_INLINE_P) Removed. + (TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P): New. + +2015-02-22 Uros Bizjak <ubizjak@gmail.com> + + Backport from mainline + 2014-12-02 Uros Bizjak <ubizjak@gmail.com> + + PR target/64113 + * config/alpha/alpha.md (call_value_osf_tlsgd): Do not split insn + using post-reload splitter. Use peephole2 pass instead. + (call_value_osf_tlsldm): Ditto. + (TLS_CALL): New int iterator. + (tls): New int attribute. + (call_value_osf_<tls>): Merge insn pattern from call_value_osf_tlsgd + and call_value_tlsldm using TLS_CALL int iterator. + +2015-02-20 Uros Bizjak <ubizjak@gmail.com> + + Backport from mainline + 2015-01-22 Wei Mi <wmi@google.com> + + PR rtl-optimization/64557 + * dse.c (record_store): Call get_addr for mem_addr. + (check_mem_read_rtx): Likewise. + + Backport from mainline + 2014-10-20 Uros Bizjak <ubizjak@gmail.com> + + * varasm.c (const_alias_set): Remove. + (init_varasm_once): Remove initialization of const_alias_set. + (build_constant_desc): Do not set alias set to const_alias_set. + + Backport from mainline + 2014-10-14 Uros Bizjak <ubizjak@gmail.com> + + PR rtl-optimization/63475 + * alias.c (true_dependence_1): Always use get_addr to extract + true address operands from x_addr and mem_addr. Use extracted + address operands to check for references with alignment ANDs. + Use extracted address operands with find_base_term and + base_alias_check. For noncanonicalized operands call canon_rtx with + extracted address operand. + (write_dependence_1): Ditto. + (may_alias_p): Ditto. Remove unused calls to canon_rtx. + + Backport from mainline + 2014-10-10 Uros Bizjak <ubizjak@gmail.com> + + PR rtl-optimization/63483 + * alias.c (true_dependence_1): Do not exit early for MEM_READONLY_P + references when alignment ANDs are involved. + (write_dependence_p): Ditto. + (may_alias_p): Ditto. + + Backport from mainline + 2013-03-26 Richard Biener <rguenther@suse.de> + + * alias.c (find_base_term): Avoid redundant and not used recursion. + (base_alias_check): Get the initial base term from the caller. + (true_dependence_1): Compute and pass base terms to base_alias_check. + (write_dependence_p): Likewise. + (may_alias_p): Likewise. + +2015-02-20 Georg-Johann Lay <avr@gjlay.de> + + Backport from 2015-02-20 trunk r220847. + + PR target/64452 + * config/avr/avr.md (pushhi_insn): New insn. + (push<mode>1): Push virtual regs in one chunk using pushhi1_insn. + +2015-02-20 Uros Bizjak <ubizjak@gmail.com> + + Backport from mainline + 2013-09-08 Richard Sandiford <rdsandiford@googlemail.com> + + * ira.c (update_equiv_regs): Only call set_paradoxical_subreg + for non-debug insns. + * lra.c (new_insn_reg): Take the containing insn as a parameter. + Only modify lra_reg_info[].biggest_mode if it's non-debug insn. + (collect_non_operand_hard_regs, add_regs_to_insn_regno_info): Update + accordingly. + +2015-02-17 Ilya Tocar <ilya.tocar@intel.com> + + Backported from mainline + 2015-01-14 Ilya Tocar <ilya.tocar@intel.com> + + PR target/64387 + * config/i386/sse.md (vec_unpacks_hi_v8sf): Fix predicate. + +2015-02-12 Jakub Jelinek <jakub@redhat.com> + + Backported from mainline + 2015-02-09 Jakub Jelinek <jakub@redhat.com> + + PR target/64979 + * tree-stdarg.c (pass_stdarg::execute): Scan phi node args for + va_list escapes. + +2015-02-11 Uros Bizjak <ubizjak@gmail.com> + + * config/alpha/alpha.md (reload_out<mode>_aligned): Make operands 2 + and 3 earlyclobber operands. + 2015-02-05 Segher Boessenkool <segher@kernel.crashing.org> PR target/64580 @@ -13,7 +600,7 @@ Backport from mainline 2015-01-31 Uros Bizjak <ubizjak@gmail.com> - PR target/64882 + PR target/64882 * config/i386/predicates.md (address_no_seg_operand): Reject non-CONST_INT_P operands in invalid mode. @@ -196,7 +783,7 @@ 2014-12-10 Bill Schmidt <wschmidt@linux.vnet.ibm.com> Backport from mainline - 2014-09-02 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + 2014-09-02 Bill Schmidt <wschmidt@linux.vnet.ibm.com> * config/rs6000/rs6000-builtin.def (XVCVSXDDP_SCALE): New built-in definition. @@ -231,7 +818,7 @@ (vec_mul): Likewise. Backport from mainline - 2014-08-28 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + 2014-08-28 Bill Schmidt <wschmidt@linux.vnet.ibm.com> * config/rs6000/altivec.h (vec_xl): New #define. (vec_xst): Likewise. @@ -254,7 +841,7 @@ (vsx_xxspltd_<mode>): New insn. Backport from mainline - 2014-08-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + 2014-08-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com> * config/rs6000/altivec.h (vec_cpsgn): New #define. (vec_mergee): Likewise. @@ -272,7 +859,7 @@ vec_any_ne, vec_mergee, vec_mergeo, vec_packsu, and vec_cntlz. Backport from mainline - 2014-07-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + 2014-07-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com> * config/rs6000/altivec.md (unspec enum): Fix typo in UNSPEC_VSLDOI. (altivec_vsldoi_<mode>): Likewise. @@ -356,7 +943,7 @@ for immediate. 2014-11-19 Felix Yang <felix.yang@huawei.com> - Shanyao Chen <chenshanyao@huawei.com> + Shanyao Chen <chenshanyao@huawei.com> PR target/59593 * config/arm/arm.md (define_attr "arch"): Add v6t2. @@ -1264,7 +1851,7 @@ Backport from mainline 2014-06-20 Julian Brown <julian@codesourcery.com> - Chung-Lin Tang <cltang@codesourcery.com> + Chung-Lin Tang <cltang@codesourcery.com> * config/arm/arm.c (arm_output_mi_thunk): Fix offset for TARGET_THUMB1_ONLY. Add comments. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index badd154f9f4..bea7eaec8f1 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20150209 +20150430 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 0050ae5f636..03a5c83f6c7 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2015-03-16 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/utils2.c (gnat_invariant_expr): Return null if the type + of the expression ends up being composite. + 2014-12-19 Release Manager * GCC 4.8.4 released. diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index 71dd8e56513..c4272473429 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -2740,6 +2740,12 @@ gnat_invariant_expr (tree expr) && DECL_INITIAL (expr)) expr = remove_conversions (DECL_INITIAL (expr), false); + /* We are only interested in scalar types at the moment and, even if we may + have gone through padding types in the above loop, we must be back to a + scalar value at this point. */ + if (AGGREGATE_TYPE_P (TREE_TYPE (expr))) + return NULL_TREE; + if (TREE_CONSTANT (expr)) return fold_convert (type, expr); diff --git a/gcc/alias.c b/gcc/alias.c index 5240982795c..7917d8137e7 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -148,7 +148,7 @@ typedef struct alias_set_entry_d *alias_set_entry; static int rtx_equal_for_memref_p (const_rtx, const_rtx); static int memrefs_conflict_p (int, rtx, int, rtx, HOST_WIDE_INT); static void record_set (rtx, const_rtx, void *); -static int base_alias_check (rtx, rtx, enum machine_mode, +static int base_alias_check (rtx, rtx, rtx, rtx, enum machine_mode, enum machine_mode); static rtx find_base_value (rtx); static int mems_in_disjoint_alias_sets_p (const_rtx, const_rtx); @@ -1666,34 +1666,30 @@ find_base_term (rtx x) if (tmp1 == pic_offset_table_rtx && CONSTANT_P (tmp2)) return find_base_term (tmp2); - /* If either operand is known to be a pointer, then use it + /* If either operand is known to be a pointer, then prefer it to determine the base term. */ if (REG_P (tmp1) && REG_POINTER (tmp1)) + ; + else if (REG_P (tmp2) && REG_POINTER (tmp2)) { - rtx base = find_base_term (tmp1); - if (base) - return base; + rtx tem = tmp1; + tmp1 = tmp2; + tmp2 = tem; } - if (REG_P (tmp2) && REG_POINTER (tmp2)) - { - rtx base = find_base_term (tmp2); - if (base) - return base; - } - - /* Neither operand was known to be a pointer. Go ahead and find the - base term for both operands. */ - tmp1 = find_base_term (tmp1); - tmp2 = find_base_term (tmp2); - - /* If either base term is named object or a special address + /* Go ahead and find the base term for both operands. If either base + term is from a pointer or is a named object or a special address (like an argument or stack reference), then use it for the base term. */ - if (tmp1 != 0 && known_base_value_p (tmp1)) + tmp1 = find_base_term (tmp1); + if (tmp1 != NULL_RTX + && ((REG_P (tmp1) && REG_POINTER (tmp1)) + || known_base_value_p (tmp1))) return tmp1; - - if (tmp2 != 0 && known_base_value_p (tmp2)) + tmp2 = find_base_term (tmp2); + if (tmp2 != NULL_RTX + && ((REG_P (tmp2) && REG_POINTER (tmp2)) + || known_base_value_p (tmp2))) return tmp2; /* We could not determine which of the two operands was the @@ -1730,12 +1726,9 @@ may_be_sp_based_p (rtx x) objects, 1 if they might be pointers to the same object. */ static int -base_alias_check (rtx x, rtx y, enum machine_mode x_mode, - enum machine_mode y_mode) +base_alias_check (rtx x, rtx x_base, rtx y, rtx y_base, + enum machine_mode x_mode, enum machine_mode y_mode) { - rtx x_base = find_base_term (x); - rtx y_base = find_base_term (y); - /* If the address itself has no known base see if a known equivalent value has one. If either address still has no known base, nothing is known about aliasing. */ @@ -2445,6 +2438,7 @@ static int true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, const_rtx x, rtx x_addr, bool mem_canonicalized) { + rtx true_mem_addr; rtx base; int ret; @@ -2464,17 +2458,9 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) return 1; - /* Read-only memory is by definition never modified, and therefore can't - conflict with anything. We don't expect to find read-only set on MEM, - but stupid user tricks can produce them, so don't die. */ - if (MEM_READONLY_P (x)) - return 0; - - /* If we have MEMs referring to different address spaces (which can - potentially overlap), we cannot easily tell from the addresses - whether the references overlap. */ - if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) - return 1; + if (! x_addr) + x_addr = XEXP (x, 0); + x_addr = get_addr (x_addr); if (! mem_addr) { @@ -2482,22 +2468,23 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, if (mem_mode == VOIDmode) mem_mode = GET_MODE (mem); } + true_mem_addr = get_addr (mem_addr); - if (! x_addr) - { - x_addr = XEXP (x, 0); - if (!((GET_CODE (x_addr) == VALUE - && GET_CODE (mem_addr) != VALUE - && reg_mentioned_p (x_addr, mem_addr)) - || (GET_CODE (x_addr) != VALUE - && GET_CODE (mem_addr) == VALUE - && reg_mentioned_p (mem_addr, x_addr)))) - { - x_addr = get_addr (x_addr); - if (! mem_canonicalized) - mem_addr = get_addr (mem_addr); - } - } + /* Read-only memory is by definition never modified, and therefore can't + conflict with anything. However, don't assume anything when AND + addresses are involved and leave to the code below to determine + dependence. We don't expect to find read-only set on MEM, but + stupid user tricks can produce them, so don't die. */ + if (MEM_READONLY_P (x) + && GET_CODE (x_addr) != AND + && GET_CODE (true_mem_addr) != AND) + return 0; + + /* If we have MEMs referring to different address spaces (which can + potentially overlap), we cannot easily tell from the addresses + whether the references overlap. */ + if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) + return 1; base = find_base_term (x_addr); if (base && (GET_CODE (base) == LABEL_REF @@ -2505,12 +2492,14 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, && CONSTANT_POOL_ADDRESS_P (base)))) return 0; - if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode)) + rtx mem_base = find_base_term (true_mem_addr); + if (! base_alias_check (x_addr, base, true_mem_addr, mem_base, + GET_MODE (x), mem_mode)) return 0; x_addr = canon_rtx (x_addr); if (!mem_canonicalized) - mem_addr = canon_rtx (mem_addr); + mem_addr = canon_rtx (true_mem_addr); if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, SIZE_FOR_MODE (x), x_addr, 0)) != -1) @@ -2563,6 +2552,7 @@ write_dependence_p (const_rtx mem, bool mem_canonicalized, bool x_canonicalized, bool writep) { rtx mem_addr; + rtx true_mem_addr, true_x_addr; rtx base; int ret; @@ -2583,8 +2573,20 @@ write_dependence_p (const_rtx mem, || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) return 1; - /* A read from read-only memory can't conflict with read-write memory. */ - if (!writep && MEM_READONLY_P (mem)) + if (!x_addr) + x_addr = XEXP (x, 0); + true_x_addr = get_addr (x_addr); + + mem_addr = XEXP (mem, 0); + true_mem_addr = get_addr (mem_addr); + + /* A read from read-only memory can't conflict with read-write memory. + Don't assume anything when AND addresses are involved and leave to + the code below to determine dependence. */ + if (!writep + && MEM_READONLY_P (mem) + && GET_CODE (true_x_addr) != AND + && GET_CODE (true_mem_addr) != AND) return 0; /* If we have MEMs referring to different address spaces (which can @@ -2593,43 +2595,26 @@ write_dependence_p (const_rtx mem, if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) return 1; - mem_addr = XEXP (mem, 0); - if (!x_addr) - { - x_addr = XEXP (x, 0); - if (!((GET_CODE (x_addr) == VALUE - && GET_CODE (mem_addr) != VALUE - && reg_mentioned_p (x_addr, mem_addr)) - || (GET_CODE (x_addr) != VALUE - && GET_CODE (mem_addr) == VALUE - && reg_mentioned_p (mem_addr, x_addr)))) - { - x_addr = get_addr (x_addr); - if (!mem_canonicalized) - mem_addr = get_addr (mem_addr); - } - } - - if (! writep) - { - base = find_base_term (mem_addr); - if (base && (GET_CODE (base) == LABEL_REF - || (GET_CODE (base) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (base)))) - return 0; - } + base = find_base_term (true_mem_addr); + if (! writep + && base + && (GET_CODE (base) == LABEL_REF + || (GET_CODE (base) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (base)))) + return 0; - if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), - GET_MODE (mem))) + rtx x_base = find_base_term (true_x_addr); + if (! base_alias_check (true_x_addr, x_base, true_mem_addr, base, + GET_MODE (x), GET_MODE (mem))) return 0; if (!x_canonicalized) { - x_addr = canon_rtx (x_addr); + x_addr = canon_rtx (true_x_addr); x_mode = GET_MODE (x); } if (!mem_canonicalized) - mem_addr = canon_rtx (mem_addr); + mem_addr = canon_rtx (true_mem_addr); if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, GET_MODE_SIZE (x_mode), x_addr, 0)) != -1) @@ -2697,10 +2682,20 @@ may_alias_p (const_rtx mem, const_rtx x) || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) return 1; + x_addr = XEXP (x, 0); + x_addr = get_addr (x_addr); + + mem_addr = XEXP (mem, 0); + mem_addr = get_addr (mem_addr); + /* Read-only memory is by definition never modified, and therefore can't - conflict with anything. We don't expect to find read-only set on MEM, - but stupid user tricks can produce them, so don't die. */ - if (MEM_READONLY_P (x)) + conflict with anything. However, don't assume anything when AND + addresses are involved and leave to the code below to determine + dependence. We don't expect to find read-only set on MEM, but + stupid user tricks can produce them, so don't die. */ + if (MEM_READONLY_P (x) + && GET_CODE (x_addr) != AND + && GET_CODE (mem_addr) != AND) return 0; /* If we have MEMs referring to different address spaces (which can @@ -2709,25 +2704,12 @@ may_alias_p (const_rtx mem, const_rtx x) if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) return 1; - x_addr = XEXP (x, 0); - mem_addr = XEXP (mem, 0); - if (!((GET_CODE (x_addr) == VALUE - && GET_CODE (mem_addr) != VALUE - && reg_mentioned_p (x_addr, mem_addr)) - || (GET_CODE (x_addr) != VALUE - && GET_CODE (mem_addr) == VALUE - && reg_mentioned_p (mem_addr, x_addr)))) - { - x_addr = get_addr (x_addr); - mem_addr = get_addr (mem_addr); - } - - if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), GET_MODE (mem_addr))) + rtx x_base = find_base_term (x_addr); + rtx mem_base = find_base_term (mem_addr); + if (! base_alias_check (x_addr, x_base, mem_addr, mem_base, + GET_MODE (x), GET_MODE (mem_addr))) return 0; - x_addr = canon_rtx (x_addr); - mem_addr = canon_rtx (mem_addr); - if (nonoverlapping_memrefs_p (mem, x, true)) return 0; diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index b230bc4a303..35cc0478a51 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2015-02-11 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2014-07-24 Marek Polacek <polacek@redhat.com> + + PR c/57653 + * c-opts.c (c_finish_options): If -imacros is in effect, return. + 2015-01-20 Marek Polacek <polacek@redhat.com> Backport from mainline diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 5ee7024efa9..30de1e113be 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -1347,6 +1347,12 @@ c_finish_options (void) static void push_command_line_include (void) { + /* This can happen if disabled by -imacros for example. + Punt so that we don't set "<command-line>" as the filename for + the header. */ + if (include_cursor > deferred_count) + return; + if (!done_preinclude) { done_preinclude = true; diff --git a/gcc/config.gcc b/gcc/config.gcc index 7b698ca9be6..5bb20cfa8fa 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -2075,27 +2075,31 @@ powerpc-*-rtems*) powerpc*-*-linux*) tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h" extra_options="${extra_options} rs6000/sysv4.opt" - tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm" + tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-ppccomm" case ${target} in powerpc*le-*-*) tm_file="${tm_file} rs6000/sysv4le.h" ;; esac - maybe_biarch=yes + case ${target}:${with_cpu} in + powerpc64*: | powerpc64*:native) cpu_is_64bit=yes ;; + esac + maybe_biarch=${cpu_is_64bit} + case ${enable_targets} in + *powerpc64*) maybe_biarch=yes ;; + esac case ${target} in powerpc64*-*-linux*spe* | powerpc64*-*-linux*paired*) - echo "*** Configuration ${target} not supported" 1>&2 + echo "*** Configuration ${target} not supported" 1>&2 exit 1 ;; powerpc*-*-linux*spe* | powerpc*-*-linux*paired*) maybe_biarch= ;; - powerpc64*-*-linux*) - test x$with_cpu != x || cpu_is_64bit=yes - maybe_biarch=always - ;; esac - case ${maybe_biarch}:${enable_targets}:${cpu_is_64bit} in - always:* | yes:*powerpc64* | yes:all:* | yes:*:yes) + case ${target}:${enable_targets}:${maybe_biarch} in + powerpc64-* | powerpc-*:*:yes | *:*powerpc64-*:yes | *:all:yes \ + | powerpc64le*:*powerpcle* | powerpc64le*:*powerpc-* \ + | powerpcle-*:*powerpc64le*:yes) if test x$cpu_is_64bit = xyes; then tm_file="${tm_file} rs6000/default64.h" fi @@ -2116,9 +2120,14 @@ powerpc*-*-linux*) esac extra_options="${extra_options} rs6000/linux64.opt" ;; + powerpc64*) + tm_file="${tm_file} rs6000/default64.h rs6000/linux64.h glibc-stdint.h" + extra_options="${extra_options} rs6000/linux64.opt" + tmake_file="${tmake_file} rs6000/t-linux" + ;; *) tm_file="${tm_file} rs6000/linux.h glibc-stdint.h" - tmake_file="$tmake_file rs6000/t-linux" + tmake_file="${tmake_file} rs6000/t-ppcos rs6000/t-linux" ;; esac case ${target} in diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index b020b457df2..a3b185c4cb6 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -4496,8 +4496,8 @@ (define_insn_and_split "reload_out<mode>_aligned" [(set (match_operand:I12MODE 0 "memory_operand" "=m") (match_operand:I12MODE 1 "register_operand" "r")) - (clobber (match_operand:SI 2 "register_operand" "=r")) - (clobber (match_operand:SI 3 "register_operand" "=r"))] + (clobber (match_operand:SI 2 "register_operand" "=&r")) + (clobber (match_operand:SI 3 "register_operand" "=&r"))] "!TARGET_BWX && (reload_in_progress || reload_completed)" "#" "!TARGET_BWX && reload_completed" @@ -5984,16 +5984,38 @@ [(set_attr "type" "jsr") (set_attr "length" "*,*,8")]) -(define_insn_and_split "call_value_osf_tlsgd" +(define_int_iterator TLS_CALL + [UNSPEC_TLSGD_CALL + UNSPEC_TLSLDM_CALL]) + +(define_int_attr tls + [(UNSPEC_TLSGD_CALL "tlsgd") + (UNSPEC_TLSLDM_CALL "tlsldm")]) + +(define_insn "call_value_osf_<tls>" [(set (match_operand 0) (call (mem:DI (match_operand:DI 1 "symbolic_operand")) (const_int 0))) - (unspec [(match_operand:DI 2 "const_int_operand")] UNSPEC_TLSGD_CALL) + (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL) (use (reg:DI 29)) (clobber (reg:DI 26))] "HAVE_AS_TLS" - "#" - "&& reload_completed" + "ldq $27,%1($29)\t\t!literal!%2\;jsr $26,($27),%1\t\t!lituse_<tls>!%2\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*" + [(set_attr "type" "jsr") + (set_attr "length" "16")]) + +;; We must use peep2 instead of a split because we need accurate life +;; information for $gp. +(define_peephole2 + [(parallel + [(set (match_operand 0) + (call (mem:DI (match_operand:DI 1 "symbolic_operand")) + (const_int 0))) + (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL) + (use (reg:DI 29)) + (clobber (reg:DI 26))])] + "HAVE_AS_TLS && reload_completed + && peep2_regno_dead_p (1, 29)" [(set (match_dup 3) (unspec:DI [(match_dup 5) (match_dup 1) @@ -6001,10 +6023,9 @@ (parallel [(set (match_dup 0) (call (mem:DI (match_dup 3)) (const_int 0))) - (set (match_dup 5) - (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1)) + (use (match_dup 5)) (use (match_dup 1)) - (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL)) + (use (unspec [(match_dup 2)] TLS_CALL)) (clobber (reg:DI 26))]) (set (match_dup 5) (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))] @@ -6012,19 +6033,18 @@ operands[3] = gen_rtx_REG (Pmode, 27); operands[4] = GEN_INT (alpha_next_sequence_number++); operands[5] = pic_offset_table_rtx; -} - [(set_attr "type" "multi")]) +}) -(define_insn_and_split "call_value_osf_tlsldm" - [(set (match_operand 0) - (call (mem:DI (match_operand:DI 1 "symbolic_operand")) - (const_int 0))) - (unspec [(match_operand:DI 2 "const_int_operand")] UNSPEC_TLSLDM_CALL) - (use (reg:DI 29)) - (clobber (reg:DI 26))] - "HAVE_AS_TLS" - "#" - "&& reload_completed" +(define_peephole2 + [(parallel + [(set (match_operand 0) + (call (mem:DI (match_operand:DI 1 "symbolic_operand")) + (const_int 0))) + (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL) + (use (reg:DI 29)) + (clobber (reg:DI 26))])] + "HAVE_AS_TLS && reload_completed + && !peep2_regno_dead_p (1, 29)" [(set (match_dup 3) (unspec:DI [(match_dup 5) (match_dup 1) @@ -6035,7 +6055,7 @@ (set (match_dup 5) (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1)) (use (match_dup 1)) - (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL)) + (use (unspec [(match_dup 2)] TLS_CALL)) (clobber (reg:DI 26))]) (set (match_dup 5) (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))] @@ -6043,8 +6063,7 @@ operands[3] = gen_rtx_REG (Pmode, 27); operands[4] = GEN_INT (alpha_next_sequence_number++); operands[5] = pic_offset_table_rtx; -} - [(set_attr "type" "multi")]) +}) (define_insn "*call_value_osf_1" [(set (match_operand 0) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 80891343bdd..6af24721be5 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -13862,7 +13862,7 @@ dump_minipool (rtx scan) fputc ('\n', dump_file); } - switch (mp->fix_size) + switch (GET_MODE_SIZE (mp->mode)) { #ifdef HAVE_consttable_1 case 1: @@ -16162,6 +16162,14 @@ output_ascii_pseudo_op (FILE *stream, const unsigned char *p, int len) fputs ("\"\n", stream); } +/* Whether a register is callee saved or not. This is necessary because high + registers are marked as caller saved when optimizing for size on Thumb-1 + targets despite being callee saved in order to avoid using them. */ +#define callee_saved_reg_p(reg) \ + (!call_used_regs[reg] \ + || (TARGET_THUMB1 && optimize_size \ + && reg >= FIRST_HI_REGNUM && reg <= LAST_HI_REGNUM)) + /* Compute the register save mask for registers 0 through 12 inclusive. This code is used by arm_compute_save_reg_mask. */ @@ -16222,7 +16230,7 @@ arm_compute_save_reg0_reg12_mask (void) /* In the normal case we only need to save those registers which are call saved and which are used by this function. */ for (reg = 0; reg <= 11; reg++) - if (df_regs_ever_live_p (reg) && ! call_used_regs[reg]) + if (df_regs_ever_live_p (reg) && callee_saved_reg_p (reg)) save_reg_mask |= (1 << reg); /* Handle the frame pointer as a special case. */ @@ -16376,7 +16384,7 @@ thumb1_compute_save_reg_mask (void) mask = 0; for (reg = 0; reg < 12; reg ++) - if (df_regs_ever_live_p (reg) && !call_used_regs[reg]) + if (df_regs_ever_live_p (reg) && callee_saved_reg_p (reg)) mask |= 1 << reg; if (flag_pic @@ -16409,7 +16417,7 @@ thumb1_compute_save_reg_mask (void) if (reg * UNITS_PER_WORD <= (unsigned) arm_size_return_regs ()) reg = LAST_LO_REGNUM; - if (! call_used_regs[reg]) + if (callee_saved_reg_p (reg)) mask |= 1 << reg; } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 8fbd4a9c44b..0f714b77717 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -12114,7 +12114,7 @@ (define_insn "consttable_1" [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)] - "TARGET_THUMB1" + "TARGET_EITHER" "* making_const_table = TRUE; assemble_integer (operands[0], 1, BITS_PER_WORD, 1); @@ -12127,14 +12127,23 @@ (define_insn "consttable_2" [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)] - "TARGET_THUMB1" + "TARGET_EITHER" "* - making_const_table = TRUE; - gcc_assert (GET_MODE_CLASS (GET_MODE (operands[0])) != MODE_FLOAT); - assemble_integer (operands[0], 2, BITS_PER_WORD, 1); - assemble_zeros (2); - return \"\"; - " + { + rtx x = operands[0]; + making_const_table = TRUE; + switch (GET_MODE_CLASS (GET_MODE (x))) + { + case MODE_FLOAT: + arm_emit_fp16_const (x); + break; + default: + assemble_integer (operands[0], 2, BITS_PER_WORD, 1); + assemble_zeros (2); + break; + } + return \"\"; + }" [(set_attr "length" "4") (set_attr "type" "no_insn")] ) @@ -12149,15 +12158,12 @@ switch (GET_MODE_CLASS (GET_MODE (x))) { case MODE_FLOAT: - if (GET_MODE (x) == HFmode) - arm_emit_fp16_const (x); - else - { - REAL_VALUE_TYPE r; - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - assemble_real (r, GET_MODE (x), BITS_PER_WORD); - } - break; + { + REAL_VALUE_TYPE r; + REAL_VALUE_FROM_CONST_DOUBLE (r, x); + assemble_real (r, GET_MODE (x), BITS_PER_WORD); + break; + } default: /* XXX: Sometimes gcc does something really dumb and ends up with a HIGH in a constant pool entry, usually because it's trying to diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 86c46e9c4a2..597adc55147 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -7578,7 +7578,8 @@ avr_adjust_insn_length (rtx insn, int len) It is easier to state this in an insn attribute "adjust_len" than to clutter up code here... */ - if (-1 == recog_memoized (insn)) + if (!NONDEBUG_INSN_P (insn) + || -1 == recog_memoized (insn)) { return len; } diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index f56008bf436..5a38e798886 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -351,6 +351,13 @@ push __zero_reg__" [(set_attr "length" "1,1")]) +(define_insn "pushhi1_insn" + [(set (mem:HI (post_dec:HI (reg:HI REG_SP))) + (match_operand:HI 0 "register_operand" "r"))] + "" + "push %B0\;push %A0" + [(set_attr "length" "2")]) + ;; All modes for a multi-byte push. We must include complex modes here too, ;; lest emit_single_push_insn "helpfully" create the auto-inc itself. (define_mode_iterator MPUSH @@ -366,17 +373,42 @@ [(match_operand:MPUSH 0 "" "")] "" { - int i; - - // Avoid (subreg (mem)) for non-generic address spaces below. Because - // of the poor addressing capabilities of these spaces it's better to - // load them in one chunk. And it avoids PR61443. - if (MEM_P (operands[0]) && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0]))) - operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]); + { + // Avoid (subreg (mem)) for non-generic address spaces. Because + // of the poor addressing capabilities of these spaces it's better to + // load them in one chunk. And it avoids PR61443. + + operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]); + } + else if (REG_P (operands[0]) + && IN_RANGE (REGNO (operands[0]), FIRST_VIRTUAL_REGISTER, + LAST_VIRTUAL_REGISTER)) + { + // Byte-wise pushing of virtual regs might result in something like + // + // (set (mem:QI (post_dec:HI (reg:HI 32 SP))) + // (subreg:QI (plus:HI (reg:HI 28) + // (const_int 17)) 0)) + // + // after elimination. This cannot be handled by reload, cf. PR64452. + // Reload virtuals in one chunk. That way it's possible to reload + // above situation and finally + // + // (set (reg:HI **) + // (const_int 17)) + // (set (reg:HI **) + // (plus:HI (reg:HI **) + // (reg:HI 28))) + // (set (mem:HI (post_dec:HI (reg:HI 32 SP)) + // (reg:HI **))) + + emit_insn (gen_pushhi1_insn (operands[0])); + DONE; + } - for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i) + for (int i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i) { rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i); if (part != const0_rtx) diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index bc47bb4067a..89ead074781 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -3117,7 +3117,7 @@ (define_expand "vec_unpacks_hi_v8sf" [(set (match_dup 2) (vec_select:V4SF - (match_operand:V8SF 1 "nonimmediate_operand") + (match_operand:V8SF 1 "register_operand") (parallel [(const_int 4) (const_int 5) (const_int 6) (const_int 7)]))) (set (match_operand:V4DF 0 "register_operand") diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 47fd47f196d..e17451f424a 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -2585,28 +2585,29 @@ pa_output_move_double (rtx *operands) && GET_CODE (XEXP (addr, 0)) == MULT) { rtx xoperands[4]; - rtx high_reg = gen_rtx_SUBREG (SImode, operands[0], 0); - if (!reg_overlap_mentioned_p (high_reg, addr)) - { - xoperands[0] = high_reg; - xoperands[1] = XEXP (addr, 1); - xoperands[2] = XEXP (XEXP (addr, 0), 0); - xoperands[3] = XEXP (XEXP (addr, 0), 1); - output_asm_insn ("{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0}", - xoperands); - return "ldw 4(%0),%R0\n\tldw 0(%0),%0"; - } - else - { - xoperands[0] = high_reg; - xoperands[1] = XEXP (addr, 1); - xoperands[2] = XEXP (XEXP (addr, 0), 0); - xoperands[3] = XEXP (XEXP (addr, 0), 1); - output_asm_insn ("{sh%O3addl %2,%1,%R0|shladd,l %2,%O3,%1,%R0}", - xoperands); - return "ldw 0(%R0),%0\n\tldw 4(%R0),%R0"; - } + /* Load address into left half of destination register. */ + xoperands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); + xoperands[1] = XEXP (addr, 1); + xoperands[2] = XEXP (XEXP (addr, 0), 0); + xoperands[3] = XEXP (XEXP (addr, 0), 1); + output_asm_insn ("{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0}", + xoperands); + return "ldw 4(%0),%R0\n\tldw 0(%0),%0"; + } + else if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) + && REG_P (XEXP (addr, 1))) + { + rtx xoperands[3]; + + /* Load address into left half of destination register. */ + xoperands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); + xoperands[1] = XEXP (addr, 0); + xoperands[2] = XEXP (addr, 1); + output_asm_insn ("{addl|add,l} %1,%2,%0", + xoperands); + return "ldw 4(%0),%R0\n\tldw 0(%0),%0"; } } diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 697057f73f1..532c452665a 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -2453,7 +2453,7 @@ } }) -(define_insn "*altivec_lvx_<mode>_internal" +(define_insn "altivec_lvx_<mode>_internal" [(parallel [(set (match_operand:VM2 0 "register_operand" "=v") (match_operand:VM2 1 "memory_operand" "Z")) @@ -2476,7 +2476,7 @@ } }) -(define_insn "*altivec_stvx_<mode>_internal" +(define_insn "altivec_stvx_<mode>_internal" [(parallel [(set (match_operand:VM2 0 "memory_operand" "=Z") (match_operand:VM2 1 "register_operand" "v")) diff --git a/gcc/config/rs6000/crypto.md b/gcc/config/rs6000/crypto.md index 9f7e4a1b255..683a340e119 100644 --- a/gcc/config/rs6000/crypto.md +++ b/gcc/config/rs6000/crypto.md @@ -18,6 +18,15 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. +;; NOTE: Although this file contains all the instructions from +;; section 5.11 of ISA 2.07, only those in sections 5.11.1 and +;; 5.11.2 are in Category:Vector.Crypto. Those are the only +;; ones controlled by -m[no-]crypto. + +;; FIXME: The builtin names for the instructions in this file +;; are likely to be deprecated in favor of other names to be +;; agreed upon with the XL compilers and LLVM. + (define_c_enum "unspec" [UNSPEC_VCIPHER UNSPEC_VNCIPHER @@ -65,7 +74,7 @@ (unspec:CR_mode [(match_operand:CR_mode 1 "register_operand" "v") (match_operand:CR_mode 2 "register_operand" "v")] UNSPEC_VPMSUM))] - "TARGET_CRYPTO" + "TARGET_P8_VECTOR" "vpmsum<CR_char> %0,%1,%2" [(set_attr "type" "crypto")]) @@ -76,7 +85,7 @@ (match_operand:CR_mode 2 "register_operand" "v") (match_operand:CR_mode 3 "register_operand" "v")] UNSPEC_VPERMXOR))] - "TARGET_CRYPTO" + "TARGET_P8_VECTOR" "vpermxor %0,%1,%2,%3" [(set_attr "type" "crypto")]) diff --git a/gcc/config/rs6000/default64.h b/gcc/config/rs6000/default64.h index 9ecd25c2723..7a29672a1ea 100644 --- a/gcc/config/rs6000/default64.h +++ b/gcc/config/rs6000/default64.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for 64 bit powerpc linux defaulting to -m64. - Copyright (C) 2003-2013 Free Software Foundation, Inc. + Copyright (C) 2003-2015 Free Software Foundation, Inc. This file is part of GCC. @@ -18,10 +18,14 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ +#define RS6000_CPU(NAME, CPU, FLAGS) +#include "rs6000-cpus.def" +#undef RS6000_CPU + #if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) #undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_64BIT | MASK_LITTLE_ENDIAN) +#define TARGET_DEFAULT (ISA_2_7_MASKS_SERVER | MASK_POWERPC64 | MASK_64BIT | MASK_LITTLE_ENDIAN) #else #undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_64BIT) +#define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 | MASK_64BIT) #endif diff --git a/gcc/config/rs6000/driver-rs6000.c b/gcc/config/rs6000/driver-rs6000.c index 2f4d1ead8f3..82455e7e79a 100644 --- a/gcc/config/rs6000/driver-rs6000.c +++ b/gcc/config/rs6000/driver-rs6000.c @@ -1,5 +1,5 @@ /* Subroutines for the gcc driver. - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2015 Free Software Foundation, Inc. This file is part of GCC. @@ -327,6 +327,12 @@ detect_processor_aix (void) case 0x4000: return "power6"; + case 0x8000: + return "power7"; + + case 0x10000: + return "power8"; + default: return "powerpc"; } diff --git a/gcc/config/rs6000/htm.md b/gcc/config/rs6000/htm.md index 1a1e4351e5c..1b5b8bf6508 100644 --- a/gcc/config/rs6000/htm.md +++ b/gcc/config/rs6000/htm.md @@ -245,7 +245,7 @@ (unspec_volatile:CC [(match_operand 0 "u3bit_cint_operand" "n")] UNSPECV_HTM_TCHECK))] "TARGET_HTM" - "tcheck. %0" + "tcheck %0" [(set_attr "type" "htm") (set_attr "length" "4")]) diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h index 1f4e20b03f3..aa74e68393e 100644 --- a/gcc/config/rs6000/linux64.h +++ b/gcc/config/rs6000/linux64.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for 64 bit PowerPC linux. - Copyright (C) 2000-2013 Free Software Foundation, Inc. + Copyright (C) 2000-2015 Free Software Foundation, Inc. This file is part of GCC. @@ -71,11 +71,7 @@ extern int dot_symbols; #undef PROCESSOR_DEFAULT #define PROCESSOR_DEFAULT PROCESSOR_POWER7 #undef PROCESSOR_DEFAULT64 -#ifdef LINUX64_DEFAULT_ABI_ELFv2 #define PROCESSOR_DEFAULT64 PROCESSOR_POWER8 -#else -#define PROCESSOR_DEFAULT64 PROCESSOR_POWER7 -#endif /* We don't need to generate entries in .fixup, except when -mrelocatable or -mrelocatable-lib is given. */ @@ -101,7 +97,7 @@ extern int dot_symbols; { \ if (!global_options_set.x_rs6000_alignment_flags) \ rs6000_alignment_flags = MASK_ALIGN_NATURAL; \ - if (TARGET_64BIT) \ + if (rs6000_isa_flags & OPTION_MASK_64BIT) \ { \ if (DEFAULT_ABI != ABI_AIX) \ { \ diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 3d7ee36a6a2..dd5ac4087d7 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -392,6 +392,14 @@ | RS6000_BTC_BINARY), \ CODE_FOR_ ## ICODE) /* ICODE */ +#define BU_CRYPTO_2A(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + #define BU_CRYPTO_3(ENUM, NAME, ATTR, ICODE) \ RS6000_BUILTIN_3 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ "__builtin_crypto_" NAME, /* NAME */ \ @@ -400,6 +408,14 @@ | RS6000_BTC_TERNARY), \ CODE_FOR_ ## ICODE) /* ICODE */ +#define BU_CRYPTO_3A(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + #define BU_CRYPTO_OVERLOAD_1(ENUM, NAME) \ RS6000_BUILTIN_1 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ "__builtin_crypto_" NAME, /* NAME */ \ @@ -408,10 +424,10 @@ | RS6000_BTC_UNARY), \ CODE_FOR_nothing) /* ICODE */ -#define BU_CRYPTO_OVERLOAD_2(ENUM, NAME) \ +#define BU_CRYPTO_OVERLOAD_2A(ENUM, NAME) \ RS6000_BUILTIN_2 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ "__builtin_crypto_" NAME, /* NAME */ \ - RS6000_BTM_CRYPTO, /* MASK */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ (RS6000_BTC_OVERLOADED /* ATTR */ \ | RS6000_BTC_BINARY), \ CODE_FOR_nothing) /* ICODE */ @@ -424,6 +440,14 @@ | RS6000_BTC_TERNARY), \ CODE_FOR_nothing) /* ICODE */ +#define BU_CRYPTO_OVERLOAD_3A(ENUM, NAME) \ + RS6000_BUILTIN_3 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_nothing) /* ICODE */ + /* HTM convenience macros. */ #define BU_HTM_0(ENUM, NAME, ATTR, ICODE) \ RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \ @@ -1611,24 +1635,24 @@ BU_CRYPTO_2 (VCIPHER, "vcipher", CONST, crypto_vcipher) BU_CRYPTO_2 (VCIPHERLAST, "vcipherlast", CONST, crypto_vcipherlast) BU_CRYPTO_2 (VNCIPHER, "vncipher", CONST, crypto_vncipher) BU_CRYPTO_2 (VNCIPHERLAST, "vncipherlast", CONST, crypto_vncipherlast) -BU_CRYPTO_2 (VPMSUMB, "vpmsumb", CONST, crypto_vpmsumb) -BU_CRYPTO_2 (VPMSUMH, "vpmsumh", CONST, crypto_vpmsumh) -BU_CRYPTO_2 (VPMSUMW, "vpmsumw", CONST, crypto_vpmsumw) -BU_CRYPTO_2 (VPMSUMD, "vpmsumd", CONST, crypto_vpmsumd) +BU_CRYPTO_2A (VPMSUMB, "vpmsumb", CONST, crypto_vpmsumb) +BU_CRYPTO_2A (VPMSUMH, "vpmsumh", CONST, crypto_vpmsumh) +BU_CRYPTO_2A (VPMSUMW, "vpmsumw", CONST, crypto_vpmsumw) +BU_CRYPTO_2A (VPMSUMD, "vpmsumd", CONST, crypto_vpmsumd) /* 3 argument crypto functions. */ -BU_CRYPTO_3 (VPERMXOR_V2DI, "vpermxor_v2di", CONST, crypto_vpermxor_v2di) -BU_CRYPTO_3 (VPERMXOR_V4SI, "vpermxor_v4si", CONST, crypto_vpermxor_v4si) -BU_CRYPTO_3 (VPERMXOR_V8HI, "vpermxor_v8hi", CONST, crypto_vpermxor_v8hi) -BU_CRYPTO_3 (VPERMXOR_V16QI, "vpermxor_v16qi", CONST, crypto_vpermxor_v16qi) +BU_CRYPTO_3A (VPERMXOR_V2DI, "vpermxor_v2di", CONST, crypto_vpermxor_v2di) +BU_CRYPTO_3A (VPERMXOR_V4SI, "vpermxor_v4si", CONST, crypto_vpermxor_v4si) +BU_CRYPTO_3A (VPERMXOR_V8HI, "vpermxor_v8hi", CONST, crypto_vpermxor_v8hi) +BU_CRYPTO_3A (VPERMXOR_V16QI, "vpermxor_v16qi", CONST, crypto_vpermxor_v16qi) BU_CRYPTO_3 (VSHASIGMAW, "vshasigmaw", CONST, crypto_vshasigmaw) BU_CRYPTO_3 (VSHASIGMAD, "vshasigmad", CONST, crypto_vshasigmad) /* 2 argument crypto overloaded functions. */ -BU_CRYPTO_OVERLOAD_2 (VPMSUM, "vpmsum") +BU_CRYPTO_OVERLOAD_2A (VPMSUM, "vpmsum") /* 3 argument crypto overloaded functions. */ -BU_CRYPTO_OVERLOAD_3 (VPERMXOR, "vpermxor") +BU_CRYPTO_OVERLOAD_3A (VPERMXOR, "vpermxor") BU_CRYPTO_OVERLOAD_3 (VSHASIGMA, "vshasigma") diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def index cbb305e1c4a..abe0ce6b7ac 100644 --- a/gcc/config/rs6000/rs6000-cpus.def +++ b/gcc/config/rs6000/rs6000-cpus.def @@ -1,5 +1,5 @@ /* IBM RS/6000 CPU names.. - Copyright (C) 1991-2013 Free Software Foundation, Inc. + Copyright (C) 1991-2015 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GCC. @@ -189,4 +189,5 @@ RS6000_CPU ("power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */ RS6000_CPU ("power8", PROCESSOR_POWER8, MASK_POWERPC64 | ISA_2_7_MASKS_SERVER) RS6000_CPU ("powerpc", PROCESSOR_POWERPC, 0) RS6000_CPU ("powerpc64", PROCESSOR_POWERPC64, MASK_PPC_GFXOPT | MASK_POWERPC64) +RS6000_CPU ("powerpc64le", PROCESSOR_POWER8, MASK_POWERPC64 | ISA_2_7_MASKS_SERVER) RS6000_CPU ("rs64", PROCESSOR_RS64A, MASK_PPC_GFXOPT | MASK_POWERPC64) diff --git a/gcc/config/rs6000/rs6000-tables.opt b/gcc/config/rs6000/rs6000-tables.opt index fa87c7fb419..ab1b20fd94f 100644 --- a/gcc/config/rs6000/rs6000-tables.opt +++ b/gcc/config/rs6000/rs6000-tables.opt @@ -186,5 +186,8 @@ EnumValue Enum(rs6000_cpu_opt_value) String(powerpc64) Value(52) EnumValue -Enum(rs6000_cpu_opt_value) String(rs64) Value(53) +Enum(rs6000_cpu_opt_value) String(powerpc64le) Value(53) + +EnumValue +Enum(rs6000_cpu_opt_value) String(rs64) Value(54) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 2f9a1789f57..a6058b4b47b 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1,5 +1,5 @@ /* Subroutines used for code generation on IBM RS/6000. - Copyright (C) 1991-2014 Free Software Foundation, Inc. + Copyright (C) 1991-2015 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GCC. @@ -61,6 +61,7 @@ #include "tree-vectorizer.h" #include "dumpfile.h" #include "real.h" +#include "tree-pass.h" #if TARGET_XCOFF #include "xcoffout.h" /* get declarations of xcoff_*_section_name */ #endif @@ -1153,6 +1154,7 @@ static bool rs6000_secondary_reload_move (enum rs6000_reg_type, enum machine_mode, secondary_reload_info *, bool); +static unsigned int rs6000_analyze_swaps (function *); /* Hash table stuff for keeping track of TOC entries. */ @@ -3139,7 +3141,13 @@ rs6000_option_override_internal (bool global_init_p) } else { - const char *default_cpu = (TARGET_POWERPC64 ? "powerpc64" : "powerpc"); + /* PowerPC 64-bit LE requires at least ISA 2.07. */ + const char *default_cpu = ((!TARGET_POWERPC64) + ? "powerpc" + : ((BYTES_BIG_ENDIAN) + ? "powerpc64" + : "powerpc64le")); + rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu); have_cpu = false; } @@ -3158,15 +3166,18 @@ rs6000_option_override_internal (bool global_init_p) & set_masks); } else - rs6000_isa_flags |= (processor_target_table[cpu_index].target_enable - & ~rs6000_isa_flags_explicit); + { + /* If no -mcpu=<xxx>, inherit any default options that were cleared via + POWERPC_MASKS. Originally, TARGET_DEFAULT was used to initialize + target_flags via the TARGET_DEFAULT_TARGET_FLAGS hook. When we switched + to using rs6000_isa_flags, we need to do the initialization here. - /* If no -mcpu=<xxx>, inherit any default options that were cleared via - POWERPC_MASKS. Originally, TARGET_DEFAULT was used to initialize - target_flags via the TARGET_DEFAULT_TARGET_FLAGS hook. When we switched - to using rs6000_isa_flags, we need to do the initialization here. */ - if (!have_cpu) - rs6000_isa_flags |= (TARGET_DEFAULT & ~rs6000_isa_flags_explicit); + If there is a TARGET_DEFAULT, use that. Otherwise fall back to using + -mcpu=powerpc, -mcpu=powerpc64, or -mcpu=powerpc64le defaults. */ + HOST_WIDE_INT flags = ((TARGET_DEFAULT) ? TARGET_DEFAULT + : processor_target_table[cpu_index].target_enable); + rs6000_isa_flags |= (flags & ~rs6000_isa_flags_explicit); + } if (rs6000_tune_index >= 0) tune_index = rs6000_tune_index; @@ -4012,18 +4023,30 @@ rs6000_option_override_internal (bool global_init_p) } } + /* Determine when unaligned vector accesses are permitted, and when + they are preferred over masked Altivec loads. Note that if + TARGET_ALLOW_MOVMISALIGN has been disabled by the user, then + TARGET_EFFICIENT_UNALIGNED_VSX must be as well. The converse is + not true. */ + if (TARGET_EFFICIENT_UNALIGNED_VSX == -1) { + if (TARGET_VSX && rs6000_cpu == PROCESSOR_POWER8 + && TARGET_ALLOW_MOVMISALIGN != 0) + TARGET_EFFICIENT_UNALIGNED_VSX = 1; + else + TARGET_EFFICIENT_UNALIGNED_VSX = 0; + } + + if (TARGET_ALLOW_MOVMISALIGN == -1 && rs6000_cpu == PROCESSOR_POWER8) + TARGET_ALLOW_MOVMISALIGN = 1; + /* Set the builtin mask of the various options used that could affect which builtins were used. In the past we used target_flags, but we've run out of bits, and some options like SPE and PAIRED are no longer in target_flags. */ rs6000_builtin_mask = rs6000_builtin_mask_calculate (); if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET) - { - fprintf (stderr, - "new builtin mask = " HOST_WIDE_INT_PRINT_HEX ", ", - rs6000_builtin_mask); - rs6000_print_builtin_options (stderr, 0, NULL, rs6000_builtin_mask); - } + rs6000_print_builtin_options (stderr, 0, "builtin mask", + rs6000_builtin_mask); /* Initialize all of the registers. */ rs6000_init_hard_regno_mode_ok (global_init_p); @@ -4041,6 +4064,37 @@ rs6000_option_override_internal (bool global_init_p) return ret; } +static bool +gate_analyze_swaps (void) +{ + return (optimize > 0 && !BYTES_BIG_ENDIAN && TARGET_VSX + && rs6000_optimize_swaps); +} + +static unsigned int +execute_analyze_swaps (void) +{ + return rs6000_analyze_swaps (cfun); +} + +struct rtl_opt_pass pass_analyze_swaps = +{ + RTL_PASS, + "swaps", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + gate_analyze_swaps, /* has_gate */ + execute_analyze_swaps, /* has_execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_NONE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_df_finish, /* todo_flags_finish */ +}; + /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to define the target cpu type. */ @@ -4048,6 +4102,13 @@ static void rs6000_option_override (void) { (void) rs6000_option_override_internal (true); + + /* Register machine-specific passes. This needs to be done at start-up. + It's convenient to do it here (like i386 does). */ + static struct register_pass_info analyze_swaps_info + = { &pass_analyze_swaps.pass, "cse1", 1, PASS_POS_INSERT_BEFORE }; + + register_pass (&analyze_swaps_info); } @@ -4055,7 +4116,9 @@ rs6000_option_override (void) static tree rs6000_builtin_mask_for_load (void) { - if (TARGET_ALTIVEC || TARGET_VSX) + /* Don't use lvsl/vperm for P8 and similarly efficient machines. */ + if ((TARGET_ALTIVEC && !TARGET_VSX) + || (TARGET_VSX && !TARGET_EFFICIENT_UNALIGNED_VSX)) return altivec_builtin_mask_for_load; else return 0; @@ -4134,6 +4197,9 @@ rs6000_builtin_support_vector_misalignment (enum machine_mode mode, { if (TARGET_VSX) { + if (TARGET_EFFICIENT_UNALIGNED_VSX) + return true; + /* Return if movmisalign pattern is not supported for this mode. */ if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing) return false; @@ -4197,6 +4263,9 @@ rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, return 3; case unaligned_load: + if (TARGET_EFFICIENT_UNALIGNED_VSX) + return 1; + if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN) { elements = TYPE_VECTOR_SUBPARTS (vectype); @@ -4232,6 +4301,9 @@ rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, return 2; case unaligned_store: + if (TARGET_EFFICIENT_UNALIGNED_VSX) + return 1; + if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN) { elements = TYPE_VECTOR_SUBPARTS (vectype); @@ -4893,6 +4965,28 @@ rs6000_file_start (void) switch_to_section (toc_section); switch_to_section (text_section); } + +#ifdef USING_ELFOS_H + if (rs6000_default_cpu == 0 || rs6000_default_cpu[0] == '\0' + || !global_options_set.x_rs6000_cpu_index) + { + fputs ("\t.machine ", asm_out_file); + if ((rs6000_isa_flags & OPTION_MASK_DIRECT_MOVE) != 0) + fputs ("power8\n", asm_out_file); + else if ((rs6000_isa_flags & OPTION_MASK_POPCNTD) != 0) + fputs ("power7\n", asm_out_file); + else if ((rs6000_isa_flags & OPTION_MASK_CMPB) != 0) + fputs ("power6\n", asm_out_file); + else if ((rs6000_isa_flags & OPTION_MASK_POPCNTB) != 0) + fputs ("power5\n", asm_out_file); + else if ((rs6000_isa_flags & OPTION_MASK_MFCRF) != 0) + fputs ("power4\n", asm_out_file); + else if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) != 0) + fputs ("ppc64\n", asm_out_file); + else + fputs ("ppc\n", asm_out_file); + } +#endif } @@ -8160,6 +8254,11 @@ rs6000_emit_le_vsx_store (rtx dest, rtx source, enum machine_mode mode) { rtx tmp, permute_src, permute_tmp; + /* This should never be called during or after reload, because it does + not re-permute the source register. It is intended only for use + during expand. */ + gcc_assert (!reload_in_progress && !lra_in_progress && !reload_completed); + /* Use V2DImode to do swaps of types with 128-bit scalare parts (TImode, V1TImode). */ if (mode == TImode || mode == V1TImode) @@ -22333,7 +22432,7 @@ output_probe_stack_range (rtx reg1, rtx reg2) static rtx rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val, - rtx reg2, rtx rreg, rtx split_reg) + rtx reg2, rtx rreg) { rtx real, temp; @@ -22424,11 +22523,6 @@ rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val, } } - /* If a store insn has been split into multiple insns, the - true source register is given by split_reg. */ - if (split_reg != NULL_RTX) - real = gen_rtx_SET (VOIDmode, SET_DEST (real), split_reg); - RTX_FRAME_RELATED_P (insn) = 1; add_reg_note (insn, REG_FRAME_RELATED_EXPR, real); @@ -22536,7 +22630,7 @@ emit_frame_save (rtx frame_reg, enum machine_mode mode, reg = gen_rtx_REG (mode, regno); insn = emit_insn (gen_frame_store (reg, frame_reg, offset)); return rs6000_frame_related (insn, frame_reg, frame_reg_to_sp, - NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX, NULL_RTX); } /* Emit an offset memory reference suitable for a frame store, while @@ -23105,7 +23199,7 @@ rs6000_emit_prologue (void) insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, - treg, GEN_INT (-info->total_size), NULL_RTX); + treg, GEN_INT (-info->total_size)); sp_off = frame_off = info->total_size; } @@ -23190,7 +23284,7 @@ rs6000_emit_prologue (void) insn = emit_move_insn (mem, reg); rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, - NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX, NULL_RTX); END_USE (0); } } @@ -23246,7 +23340,7 @@ rs6000_emit_prologue (void) info->lr_save_offset, DFmode, sel); rs6000_frame_related (insn, ptr_reg, sp_off, - NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX, NULL_RTX); if (lr) END_USE (0); } @@ -23325,7 +23419,7 @@ rs6000_emit_prologue (void) SAVRES_SAVE | SAVRES_GPR); rs6000_frame_related (insn, spe_save_area_ptr, sp_off - save_off, - NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX, NULL_RTX); } /* Move the static chain pointer back. */ @@ -23375,7 +23469,7 @@ rs6000_emit_prologue (void) info->lr_save_offset + ptr_off, reg_mode, sel); rs6000_frame_related (insn, ptr_reg, sp_off - ptr_off, - NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX, NULL_RTX); if (lr) END_USE (0); } @@ -23391,7 +23485,7 @@ rs6000_emit_prologue (void) info->gp_save_offset + frame_off + reg_size * i); insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, - NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX, NULL_RTX); } else if (!WORLD_SAVE_P (info)) { @@ -23714,7 +23808,7 @@ rs6000_emit_prologue (void) info->altivec_save_offset + ptr_off, 0, V4SImode, SAVRES_SAVE | SAVRES_VR); rs6000_frame_related (insn, scratch_reg, sp_off - ptr_off, - NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX, NULL_RTX); if (REGNO (frame_reg_rtx) == REGNO (scratch_reg)) { /* The oddity mentioned above clobbered our frame reg. */ @@ -23730,7 +23824,7 @@ rs6000_emit_prologue (void) for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i) if (info->vrsave_mask & ALTIVEC_REG_BIT (i)) { - rtx areg, savereg, mem, split_reg; + rtx areg, savereg, mem; int offset; offset = (info->altivec_save_offset + frame_off @@ -23746,20 +23840,13 @@ rs6000_emit_prologue (void) mem = gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, frame_reg_rtx, areg)); - insn = emit_move_insn (mem, savereg); - - /* When we split a VSX store into two insns, we need to make - sure the DWARF info knows which register we are storing. - Pass it in to be used on the appropriate note. */ - if (!BYTES_BIG_ENDIAN - && GET_CODE (PATTERN (insn)) == SET - && GET_CODE (SET_SRC (PATTERN (insn))) == VEC_SELECT) - split_reg = savereg; - else - split_reg = NULL_RTX; + /* Rather than emitting a generic move, force use of the stvx + instruction, which we always want. In particular we don't + want xxpermdi/stxvd2x for little endian. */ + insn = emit_insn (gen_altivec_stvx_v4si_internal (mem, savereg)); rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, - areg, GEN_INT (offset), split_reg); + areg, GEN_INT (offset)); } } @@ -24401,7 +24488,10 @@ rs6000_emit_epilogue (int sibcall) mem = gen_frame_mem (V4SImode, addr); reg = gen_rtx_REG (V4SImode, i); - emit_move_insn (reg, mem); + /* Rather than emitting a generic move, force use of the + lvx instruction, which we always want. In particular + we don't want lxvd2x/xxpermdi for little endian. */ + (void) emit_insn (gen_altivec_lvx_v4si_internal (reg, mem)); } } @@ -24599,7 +24689,10 @@ rs6000_emit_epilogue (int sibcall) mem = gen_frame_mem (V4SImode, addr); reg = gen_rtx_REG (V4SImode, i); - emit_move_insn (reg, mem); + /* Rather than emitting a generic move, force use of the + lvx instruction, which we always want. In particular + we don't want lxvd2x/xxpermdi for little endian. */ + (void) emit_insn (gen_altivec_lvx_v4si_internal (reg, mem)); } } @@ -31543,10 +31636,11 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] = { "quad-memory", OPTION_MASK_QUAD_MEMORY, false, true }, { "quad-memory-atomic", OPTION_MASK_QUAD_MEMORY_ATOMIC, false, true }, { "recip-precision", OPTION_MASK_RECIP_PRECISION, false, true }, + { "save-toc-indirect", OPTION_MASK_SAVE_TOC_INDIRECT, false, true }, { "string", OPTION_MASK_STRING, false, true }, { "update", OPTION_MASK_NO_UPDATE, true , true }, - { "upper-regs-df", OPTION_MASK_UPPER_REGS_DF, false, false }, - { "upper-regs-sf", OPTION_MASK_UPPER_REGS_SF, false, false }, + { "upper-regs-df", OPTION_MASK_UPPER_REGS_DF, false, true }, + { "upper-regs-sf", OPTION_MASK_UPPER_REGS_SF, false, true }, { "vsx", OPTION_MASK_VSX, false, true }, { "vsx-timode", OPTION_MASK_VSX_TIMODE, false, true }, #ifdef OPTION_MASK_64BIT @@ -31619,6 +31713,42 @@ static struct rs6000_opt_var const rs6000_opt_vars[] = { "longcall", offsetof (struct gcc_options, x_rs6000_default_long_calls), offsetof (struct cl_target_option, x_rs6000_default_long_calls), }, + { "optimize-swaps", + offsetof (struct gcc_options, x_rs6000_optimize_swaps), + offsetof (struct cl_target_option, x_rs6000_optimize_swaps), }, + { "allow-movmisalign", + offsetof (struct gcc_options, x_TARGET_ALLOW_MOVMISALIGN), + offsetof (struct cl_target_option, x_TARGET_ALLOW_MOVMISALIGN), }, + { "allow-df-permute", + offsetof (struct gcc_options, x_TARGET_ALLOW_DF_PERMUTE), + offsetof (struct cl_target_option, x_TARGET_ALLOW_DF_PERMUTE), }, + { "sched-groups", + offsetof (struct gcc_options, x_TARGET_SCHED_GROUPS), + offsetof (struct cl_target_option, x_TARGET_SCHED_GROUPS), }, + { "always-hint", + offsetof (struct gcc_options, x_TARGET_ALWAYS_HINT), + offsetof (struct cl_target_option, x_TARGET_ALWAYS_HINT), }, + { "align-branch-targets", + offsetof (struct gcc_options, x_TARGET_ALIGN_BRANCH_TARGETS), + offsetof (struct cl_target_option, x_TARGET_ALIGN_BRANCH_TARGETS), }, + { "vectorize-builtins", + offsetof (struct gcc_options, x_TARGET_VECTORIZE_BUILTINS), + offsetof (struct cl_target_option, x_TARGET_VECTORIZE_BUILTINS), }, + { "tls-markers", + offsetof (struct gcc_options, x_tls_markers), + offsetof (struct cl_target_option, x_tls_markers), }, + { "sched-prolog", + offsetof (struct gcc_options, x_TARGET_SCHED_PROLOG), + offsetof (struct cl_target_option, x_TARGET_SCHED_PROLOG), }, + { "sched-epilog", + offsetof (struct gcc_options, x_TARGET_SCHED_PROLOG), + offsetof (struct cl_target_option, x_TARGET_SCHED_PROLOG), }, + { "gen-cell-microcode", + offsetof (struct gcc_options, x_rs6000_gen_cell_microcode), + offsetof (struct cl_target_option, x_rs6000_gen_cell_microcode), }, + { "warn-cell-microcode", + offsetof (struct gcc_options, x_rs6000_warn_cell_microcode), + offsetof (struct cl_target_option, x_rs6000_warn_cell_microcode), }, }; /* Inner function to handle attribute((target("..."))) and #pragma GCC target @@ -31692,9 +31822,15 @@ rs6000_inner_target_options (tree args, bool attr_p) rs6000_isa_flags_explicit |= mask; /* VSX needs altivec, so -mvsx automagically sets - altivec. */ - if (mask == OPTION_MASK_VSX && !invert) - mask |= OPTION_MASK_ALTIVEC; + altivec and disables -mavoid-indexed-addresses. */ + if (!invert) + { + if (mask == OPTION_MASK_VSX) + { + mask |= OPTION_MASK_ALTIVEC; + TARGET_AVOID_XFORM = 0; + } + } if (rs6000_opt_masks[i].invert) invert = !invert; @@ -31715,6 +31851,7 @@ rs6000_inner_target_options (tree args, bool attr_p) size_t j = rs6000_opt_vars[i].global_offset; *((int *) ((char *)&global_options + j)) = !invert; error_p = false; + not_valid_p = false; break; } } @@ -33183,6 +33320,1177 @@ emit_fusion_gpr_load (rtx target, rtx mem) return ""; } + +/* Analyze vector computations and remove unnecessary doubleword + swaps (xxswapdi instructions). This pass is performed only + for little-endian VSX code generation. + + For this specific case, loads and stores of 4x32 and 2x64 vectors + are inefficient. These are implemented using the lvx2dx and + stvx2dx instructions, which invert the order of doublewords in + a vector register. Thus the code generation inserts an xxswapdi + after each such load, and prior to each such store. (For spill + code after register assignment, an additional xxswapdi is inserted + following each store in order to return a hard register to its + unpermuted value.) + + The extra xxswapdi instructions reduce performance. This can be + particularly bad for vectorized code. The purpose of this pass + is to reduce the number of xxswapdi instructions required for + correctness. + + The primary insight is that much code that operates on vectors + does not care about the relative order of elements in a register, + so long as the correct memory order is preserved. If we have + a computation where all input values are provided by lvxd2x/xxswapdi + sequences, all outputs are stored using xxswapdi/stvxd2x sequences, + and all intermediate computations are pure SIMD (independent of + element order), then all the xxswapdi's associated with the loads + and stores may be removed. + + This pass uses some of the infrastructure and logical ideas from + the "web" pass in web.c. We create maximal webs of computations + fitting the description above using union-find. Each such web is + then optimized by removing its unnecessary xxswapdi instructions. + + The pass is placed prior to global optimization so that we can + perform the optimization in the safest and simplest way possible; + that is, by replacing each xxswapdi insn with a register copy insn. + Subsequent forward propagation will remove copies where possible. + + There are some operations sensitive to element order for which we + can still allow the operation, provided we modify those operations. + These include CONST_VECTORs, for which we must swap the first and + second halves of the constant vector; and SUBREGs, for which we + must adjust the byte offset to account for the swapped doublewords. + A remaining opportunity would be non-immediate-form splats, for + which we should adjust the selected lane of the input. We should + also make code generation adjustments for sum-across operations, + since this is a common vectorizer reduction. + + Because we run prior to the first split, we can see loads and stores + here that match *vsx_le_perm_{load,store}_<mode>. These are vanilla + vector loads and stores that have not yet been split into a permuting + load/store and a swap. (One way this can happen is with a builtin + call to vec_vsx_{ld,st}.) We can handle these as well, but rather + than deleting a swap, we convert the load/store into a permuting + load/store (which effectively removes the swap). */ + +/* Notes on Permutes + + We do not currently handle computations that contain permutes. There + is a general transformation that can be performed correctly, but it + may introduce more expensive code than it replaces. To handle these + would require a cost model to determine when to perform the optimization. + This commentary records how this could be done if desired. + + The most general permute is something like this (example for V16QI): + + (vec_select:V16QI (vec_concat:V32QI (op1:V16QI) (op2:V16QI)) + (parallel [(const_int a0) (const_int a1) + ... + (const_int a14) (const_int a15)])) + + where a0,...,a15 are in [0,31] and select elements from op1 and op2 + to produce in the result. + + Regardless of mode, we can convert the PARALLEL to a mask of 16 + byte-element selectors. Let's call this M, with M[i] representing + the ith byte-element selector value. Then if we swap doublewords + throughout the computation, we can get correct behavior by replacing + M with M' as follows: + + { M[i+8]+8 : i < 8, M[i+8] in [0,7] U [16,23] + M'[i] = { M[i+8]-8 : i < 8, M[i+8] in [8,15] U [24,31] + { M[i-8]+8 : i >= 8, M[i-8] in [0,7] U [16,23] + { M[i-8]-8 : i >= 8, M[i-8] in [8,15] U [24,31] + + This seems promising at first, since we are just replacing one mask + with another. But certain masks are preferable to others. If M + is a mask that matches a vmrghh pattern, for example, M' certainly + will not. Instead of a single vmrghh, we would generate a load of + M' and a vperm. So we would need to know how many xxswapd's we can + remove as a result of this transformation to determine if it's + profitable; and preferably the logic would need to be aware of all + the special preferable masks. + + Another form of permute is an UNSPEC_VPERM, in which the mask is + already in a register. In some cases, this mask may be a constant + that we can discover with ud-chains, in which case the above + transformation is ok. However, the common usage here is for the + mask to be produced by an UNSPEC_LVSL, in which case the mask + cannot be known at compile time. In such a case we would have to + generate several instructions to compute M' as above at run time, + and a cost model is needed again. */ + +/* This is based on the union-find logic in web.c. web_entry_base is + defined in df.h. */ +class swap_web_entry : public web_entry_base +{ + public: + /* Pointer to the insn. */ + rtx insn; + /* Set if insn contains a mention of a vector register. All other + fields are undefined if this field is unset. */ + unsigned int is_relevant : 1; + /* Set if insn is a load. */ + unsigned int is_load : 1; + /* Set if insn is a store. */ + unsigned int is_store : 1; + /* Set if insn is a doubleword swap. This can either be a register swap + or a permuting load or store (test is_load and is_store for this). */ + unsigned int is_swap : 1; + /* Set if the insn has a live-in use of a parameter register. */ + unsigned int is_live_in : 1; + /* Set if the insn has a live-out def of a return register. */ + unsigned int is_live_out : 1; + /* Set if the insn contains a subreg reference of a vector register. */ + unsigned int contains_subreg : 1; + /* Set if the insn contains a 128-bit integer operand. */ + unsigned int is_128_int : 1; + /* Set if this is a call-insn. */ + unsigned int is_call : 1; + /* Set if this insn does not perform a vector operation for which + element order matters, or if we know how to fix it up if it does. + Undefined if is_swap is set. */ + unsigned int is_swappable : 1; + /* A nonzero value indicates what kind of special handling for this + insn is required if doublewords are swapped. Undefined if + is_swappable is not set. */ + unsigned int special_handling : 3; + /* Set if the web represented by this entry cannot be optimized. */ + unsigned int web_not_optimizable : 1; + /* Set if this insn should be deleted. */ + unsigned int will_delete : 1; +}; + +enum special_handling_values { + SH_NONE = 0, + SH_CONST_VECTOR, + SH_SUBREG, + SH_NOSWAP_LD, + SH_NOSWAP_ST, + SH_EXTRACT, + SH_SPLAT +}; + +/* Union INSN with all insns containing definitions that reach USE. + Detect whether USE is live-in to the current function. */ +static void +union_defs (swap_web_entry *insn_entry, rtx insn, df_ref use) +{ + struct df_link *link = DF_REF_CHAIN (use); + + if (!link) + insn_entry[INSN_UID (insn)].is_live_in = 1; + + while (link) + { + if (DF_REF_IS_ARTIFICIAL (link->ref)) + insn_entry[INSN_UID (insn)].is_live_in = 1; + + if (DF_REF_INSN_INFO (link->ref)) + { + rtx def_insn = DF_REF_INSN (link->ref); + (void)unionfind_union (insn_entry + INSN_UID (insn), + insn_entry + INSN_UID (def_insn)); + } + + link = link->next; + } +} + +/* Union INSN with all insns containing uses reached from DEF. + Detect whether DEF is live-out from the current function. */ +static void +union_uses (swap_web_entry *insn_entry, rtx insn, df_ref def) +{ + struct df_link *link = DF_REF_CHAIN (def); + + if (!link) + insn_entry[INSN_UID (insn)].is_live_out = 1; + + while (link) + { + /* This could be an eh use or some other artificial use; + we treat these all the same (killing the optimization). */ + if (DF_REF_IS_ARTIFICIAL (link->ref)) + insn_entry[INSN_UID (insn)].is_live_out = 1; + + if (DF_REF_INSN_INFO (link->ref)) + { + rtx use_insn = DF_REF_INSN (link->ref); + (void)unionfind_union (insn_entry + INSN_UID (insn), + insn_entry + INSN_UID (use_insn)); + } + + link = link->next; + } +} + +/* Return 1 iff INSN is a load insn, including permuting loads that + represent an lvxd2x instruction; else return 0. */ +static unsigned int +insn_is_load_p (rtx insn) +{ + rtx body = PATTERN (insn); + + if (GET_CODE (body) == SET) + { + if (GET_CODE (SET_SRC (body)) == MEM) + return 1; + + if (GET_CODE (SET_SRC (body)) == VEC_SELECT + && GET_CODE (XEXP (SET_SRC (body), 0)) == MEM) + return 1; + + return 0; + } + + if (GET_CODE (body) != PARALLEL) + return 0; + + rtx set = XVECEXP (body, 0, 0); + + if (GET_CODE (set) == SET && GET_CODE (SET_SRC (set)) == MEM) + return 1; + + return 0; +} + +/* Return 1 iff INSN is a store insn, including permuting stores that + represent an stvxd2x instruction; else return 0. */ +static unsigned int +insn_is_store_p (rtx insn) +{ + rtx body = PATTERN (insn); + if (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == MEM) + return 1; + if (GET_CODE (body) != PARALLEL) + return 0; + rtx set = XVECEXP (body, 0, 0); + if (GET_CODE (set) == SET && GET_CODE (SET_DEST (set)) == MEM) + return 1; + return 0; +} + +/* Return 1 iff INSN swaps doublewords. This may be a reg-reg swap, + a permuting load, or a permuting store. */ +static unsigned int +insn_is_swap_p (rtx insn) +{ + rtx body = PATTERN (insn); + if (GET_CODE (body) != SET) + return 0; + rtx rhs = SET_SRC (body); + if (GET_CODE (rhs) != VEC_SELECT) + return 0; + rtx parallel = XEXP (rhs, 1); + if (GET_CODE (parallel) != PARALLEL) + return 0; + unsigned int len = XVECLEN (parallel, 0); + if (len != 2 && len != 4 && len != 8 && len != 16) + return 0; + for (unsigned int i = 0; i < len / 2; ++i) + { + rtx op = XVECEXP (parallel, 0, i); + if (GET_CODE (op) != CONST_INT || INTVAL (op) != len / 2 + i) + return 0; + } + for (unsigned int i = len / 2; i < len; ++i) + { + rtx op = XVECEXP (parallel, 0, i); + if (GET_CODE (op) != CONST_INT || INTVAL (op) != i - len / 2) + return 0; + } + return 1; +} + +/* Return 1 iff OP is an operand that will not be affected by having + vector doublewords swapped in memory. */ +static unsigned int +rtx_is_swappable_p (rtx op, unsigned int *special) +{ + enum rtx_code code = GET_CODE (op); + int i, j; + rtx parallel; + + switch (code) + { + case LABEL_REF: + case SYMBOL_REF: + case CLOBBER: + case REG: + return 1; + + case VEC_CONCAT: + case ASM_INPUT: + case ASM_OPERANDS: + return 0; + + case CONST_VECTOR: + { + *special = SH_CONST_VECTOR; + return 1; + } + + case VEC_DUPLICATE: + /* Opportunity: If XEXP (op, 0) has the same mode as the result, + and XEXP (op, 1) is a PARALLEL with a single QImode const int, + it represents a vector splat for which we can do special + handling. */ + if (GET_CODE (XEXP (op, 0)) == CONST_INT) + return 1; + else if (GET_CODE (XEXP (op, 0)) == REG + && GET_MODE_INNER (GET_MODE (op)) == GET_MODE (XEXP (op, 0))) + /* This catches V2DF and V2DI splat, at a minimum. */ + return 1; + else if (GET_CODE (XEXP (op, 0)) == VEC_SELECT) + /* If the duplicated item is from a select, defer to the select + processing to see if we can change the lane for the splat. */ + return rtx_is_swappable_p (XEXP (op, 0), special); + else + return 0; + + case VEC_SELECT: + /* A vec_extract operation is ok if we change the lane. */ + if (GET_CODE (XEXP (op, 0)) == REG + && GET_MODE_INNER (GET_MODE (XEXP (op, 0))) == GET_MODE (op) + && GET_CODE ((parallel = XEXP (op, 1))) == PARALLEL + && XVECLEN (parallel, 0) == 1 + && GET_CODE (XVECEXP (parallel, 0, 0)) == CONST_INT) + { + *special = SH_EXTRACT; + return 1; + } + else + return 0; + + case UNSPEC: + { + /* Various operations are unsafe for this optimization, at least + without significant additional work. Permutes are obviously + problematic, as both the permute control vector and the ordering + of the target values are invalidated by doubleword swapping. + Vector pack and unpack modify the number of vector lanes. + Merge-high/low will not operate correctly on swapped operands. + Vector shifts across element boundaries are clearly uncool, + as are vector select and concatenate operations. Vector + sum-across instructions define one operand with a specific + order-dependent element, so additional fixup code would be + needed to make those work. Vector set and non-immediate-form + vector splat are element-order sensitive. A few of these + cases might be workable with special handling if required. + Adding cost modeling would be appropriate in some cases. */ + int val = XINT (op, 1); + switch (val) + { + default: + break; + case UNSPEC_VMRGH_DIRECT: + case UNSPEC_VMRGL_DIRECT: + case UNSPEC_VPACK_SIGN_SIGN_SAT: + case UNSPEC_VPACK_SIGN_UNS_SAT: + case UNSPEC_VPACK_UNS_UNS_MOD: + case UNSPEC_VPACK_UNS_UNS_MOD_DIRECT: + case UNSPEC_VPACK_UNS_UNS_SAT: + case UNSPEC_VPERM: + case UNSPEC_VPERM_UNS: + case UNSPEC_VPERMHI: + case UNSPEC_VPERMSI: + case UNSPEC_VPKPX: + case UNSPEC_VSLDOI: + case UNSPEC_VSLO: + case UNSPEC_VSRO: + case UNSPEC_VSUM2SWS: + case UNSPEC_VSUM4S: + case UNSPEC_VSUM4UBS: + case UNSPEC_VSUMSWS: + case UNSPEC_VSUMSWS_DIRECT: + case UNSPEC_VSX_CONCAT: + case UNSPEC_VSX_SET: + case UNSPEC_VSX_SLDWI: + case UNSPEC_VUNPACK_HI_SIGN: + case UNSPEC_VUNPACK_HI_SIGN_DIRECT: + case UNSPEC_VUNPACK_LO_SIGN: + case UNSPEC_VUNPACK_LO_SIGN_DIRECT: + case UNSPEC_VUPKHPX: + case UNSPEC_VUPKHS_V4SF: + case UNSPEC_VUPKHU_V4SF: + case UNSPEC_VUPKLPX: + case UNSPEC_VUPKLS_V4SF: + case UNSPEC_VUPKLU_V4SF: + case UNSPEC_VSX_CVDPSPN: + case UNSPEC_VSX_CVSPDP: + case UNSPEC_VSX_CVSPDPN: + return 0; + case UNSPEC_VSPLT_DIRECT: + *special = SH_SPLAT; + return 1; + } + } + + default: + break; + } + + const char *fmt = GET_RTX_FORMAT (code); + int ok = 1; + + for (i = 0; i < GET_RTX_LENGTH (code); ++i) + if (fmt[i] == 'e' || fmt[i] == 'u') + { + unsigned int special_op = SH_NONE; + ok &= rtx_is_swappable_p (XEXP (op, i), &special_op); + if (special_op == SH_NONE) + continue; + /* Ensure we never have two kinds of special handling + for the same insn. */ + if (*special != SH_NONE && *special != special_op) + return 0; + *special = special_op; + } + else if (fmt[i] == 'E') + for (j = 0; j < XVECLEN (op, i); ++j) + { + unsigned int special_op = SH_NONE; + ok &= rtx_is_swappable_p (XVECEXP (op, i, j), &special_op); + if (special_op == SH_NONE) + continue; + /* Ensure we never have two kinds of special handling + for the same insn. */ + if (*special != SH_NONE && *special != special_op) + return 0; + *special = special_op; + } + + return ok; +} + +/* Return 1 iff INSN is an operand that will not be affected by + having vector doublewords swapped in memory (in which case + *SPECIAL is unchanged), or that can be modified to be correct + if vector doublewords are swapped in memory (in which case + *SPECIAL is changed to a value indicating how). */ +static unsigned int +insn_is_swappable_p (swap_web_entry *insn_entry, rtx insn, + unsigned int *special) +{ + /* Calls are always bad. */ + if (GET_CODE (insn) == CALL_INSN) + return 0; + + /* Loads and stores seen here are not permuting, but we can still + fix them up by converting them to permuting ones. Exceptions: + UNSPEC_LVE, UNSPEC_LVX, and UNSPEC_STVX, which have a PARALLEL + body instead of a SET; and UNSPEC_STVE, which has an UNSPEC + for the SET source. */ + rtx body = PATTERN (insn); + int i = INSN_UID (insn); + + if (insn_entry[i].is_load) + { + if (GET_CODE (body) == SET) + { + *special = SH_NOSWAP_LD; + return 1; + } + else + return 0; + } + + if (insn_entry[i].is_store) + { + if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) != UNSPEC) + { + *special = SH_NOSWAP_ST; + return 1; + } + else + return 0; + } + + /* A convert to single precision can be left as is provided that + all of its uses are in xxspltw instructions that splat BE element + zero. */ + if (GET_CODE (body) == SET + && GET_CODE (SET_SRC (body)) == UNSPEC + && XINT (SET_SRC (body), 1) == UNSPEC_VSX_CVDPSPN) + { + df_ref *def_rec; + + for (def_rec = DF_INSN_UID_DEFS (i); *def_rec; def_rec++) + { + df_ref def = *def_rec; + struct df_link *link = DF_REF_CHAIN (def); + if (!link) + return 0; + + for (; link; link = link->next) { + rtx use_insn = DF_REF_INSN (link->ref); + rtx use_body = PATTERN (use_insn); + if (GET_CODE (use_body) != SET + || GET_CODE (SET_SRC (use_body)) != UNSPEC + || XINT (SET_SRC (use_body), 1) != UNSPEC_VSX_XXSPLTW + || XEXP (XEXP (SET_SRC (use_body), 0), 1) != const0_rtx) + return 0; + } + } + + return 1; + } + + /* Otherwise check the operands for vector lane violations. */ + return rtx_is_swappable_p (body, special); +} + +enum chain_purpose { FOR_LOADS, FOR_STORES }; + +/* Return true if the UD or DU chain headed by LINK is non-empty, + and every entry on the chain references an insn that is a + register swap. Furthermore, if PURPOSE is FOR_LOADS, each such + register swap must have only permuting loads as reaching defs. + If PURPOSE is FOR_STORES, each such register swap must have only + register swaps or permuting stores as reached uses. */ +static bool +chain_contains_only_swaps (swap_web_entry *insn_entry, struct df_link *link, + enum chain_purpose purpose) +{ + if (!link) + return false; + + for (; link; link = link->next) + { + if (!VECTOR_MODE_P (GET_MODE (DF_REF_REG (link->ref)))) + continue; + + if (DF_REF_IS_ARTIFICIAL (link->ref)) + return false; + + rtx reached_insn = DF_REF_INSN (link->ref); + unsigned uid = INSN_UID (reached_insn); + + if (!insn_entry[uid].is_swap || insn_entry[uid].is_load + || insn_entry[uid].is_store) + return false; + + if (purpose == FOR_LOADS) + { + df_ref *use_rec; + for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) + { + df_ref use = *use_rec; + struct df_link *swap_link = DF_REF_CHAIN (use); + + while (swap_link) + { + if (DF_REF_IS_ARTIFICIAL (link->ref)) + return false; + + rtx swap_def_insn = DF_REF_INSN (swap_link->ref); + unsigned uid2 = INSN_UID (swap_def_insn); + + /* Only permuting loads are allowed. */ + if (!insn_entry[uid2].is_swap || !insn_entry[uid2].is_load) + return false; + + swap_link = swap_link->next; + } + } + } + else if (purpose == FOR_STORES) + { + df_ref *def_rec; + for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + { + df_ref def = *def_rec; + struct df_link *swap_link = DF_REF_CHAIN (def); + + while (swap_link) + { + if (DF_REF_IS_ARTIFICIAL (link->ref)) + return false; + + rtx swap_use_insn = DF_REF_INSN (swap_link->ref); + unsigned uid2 = INSN_UID (swap_use_insn); + + /* Permuting stores or register swaps are allowed. */ + if (!insn_entry[uid2].is_swap || insn_entry[uid2].is_load) + return false; + + swap_link = swap_link->next; + } + } + } + } + + return true; +} + +/* Mark the xxswapdi instructions associated with permuting loads and + stores for removal. Note that we only flag them for deletion here, + as there is a possibility of a swap being reached from multiple + loads, etc. */ +static void +mark_swaps_for_removal (swap_web_entry *insn_entry, unsigned int i) +{ + rtx insn = insn_entry[i].insn; + unsigned uid = INSN_UID (insn); + + if (insn_entry[i].is_load) + { + df_ref *def_rec; + for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + { + df_ref def = *def_rec; + struct df_link *link = DF_REF_CHAIN (def); + + /* We know by now that these are swaps, so we can delete + them confidently. */ + while (link) + { + rtx use_insn = DF_REF_INSN (link->ref); + insn_entry[INSN_UID (use_insn)].will_delete = 1; + link = link->next; + } + } + } + else if (insn_entry[i].is_store) + { + df_ref *use_rec; + for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) + { + df_ref use = *use_rec; + /* Ignore uses for addressability. */ + machine_mode mode = GET_MODE (DF_REF_REG (use)); + if (!VECTOR_MODE_P (mode)) + continue; + + struct df_link *link = DF_REF_CHAIN (use); + + /* We know by now that these are swaps, so we can delete + them confidently. */ + while (link) + { + rtx def_insn = DF_REF_INSN (link->ref); + insn_entry[INSN_UID (def_insn)].will_delete = 1; + link = link->next; + } + } + } +} + +/* OP is either a CONST_VECTOR or an expression containing one. + Swap the first half of the vector with the second in the first + case. Recurse to find it in the second. */ +static void +swap_const_vector_halves (rtx op) +{ + int i; + enum rtx_code code = GET_CODE (op); + if (GET_CODE (op) == CONST_VECTOR) + { + int half_units = GET_MODE_NUNITS (GET_MODE (op)) / 2; + for (i = 0; i < half_units; ++i) + { + rtx temp = CONST_VECTOR_ELT (op, i); + CONST_VECTOR_ELT (op, i) = CONST_VECTOR_ELT (op, i + half_units); + CONST_VECTOR_ELT (op, i + half_units) = temp; + } + } + else + { + int j; + const char *fmt = GET_RTX_FORMAT (code); + for (i = 0; i < GET_RTX_LENGTH (code); ++i) + if (fmt[i] == 'e' || fmt[i] == 'u') + swap_const_vector_halves (XEXP (op, i)); + else if (fmt[i] == 'E') + for (j = 0; j < XVECLEN (op, i); ++j) + swap_const_vector_halves (XVECEXP (op, i, j)); + } +} + +/* Find all subregs of a vector expression that perform a narrowing, + and adjust the subreg index to account for doubleword swapping. */ +static void +adjust_subreg_index (rtx op) +{ + enum rtx_code code = GET_CODE (op); + if (code == SUBREG + && (GET_MODE_SIZE (GET_MODE (op)) + < GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))) + { + unsigned int index = SUBREG_BYTE (op); + if (index < 8) + index += 8; + else + index -= 8; + SUBREG_BYTE (op) = index; + } + + const char *fmt = GET_RTX_FORMAT (code); + int i,j; + for (i = 0; i < GET_RTX_LENGTH (code); ++i) + if (fmt[i] == 'e' || fmt[i] == 'u') + adjust_subreg_index (XEXP (op, i)); + else if (fmt[i] == 'E') + for (j = 0; j < XVECLEN (op, i); ++j) + adjust_subreg_index (XVECEXP (op, i, j)); +} + +/* Convert the non-permuting load INSN to a permuting one. */ +static void +permute_load (rtx insn) +{ + rtx body = PATTERN (insn); + rtx mem_op = SET_SRC (body); + rtx tgt_reg = SET_DEST (body); + machine_mode mode = GET_MODE (tgt_reg); + int n_elts = GET_MODE_NUNITS (mode); + int half_elts = n_elts / 2; + rtx par = gen_rtx_PARALLEL (mode, rtvec_alloc (n_elts)); + int i, j; + for (i = 0, j = half_elts; i < half_elts; ++i, ++j) + XVECEXP (par, 0, i) = GEN_INT (j); + for (i = half_elts, j = 0; j < half_elts; ++i, ++j) + XVECEXP (par, 0, i) = GEN_INT (j); + rtx sel = gen_rtx_VEC_SELECT (mode, mem_op, par); + SET_SRC (body) = sel; + INSN_CODE (insn) = -1; /* Force re-recognition. */ + df_insn_rescan (insn); + + if (dump_file) + fprintf (dump_file, "Replacing load %d with permuted load\n", + INSN_UID (insn)); +} + +/* Convert the non-permuting store INSN to a permuting one. */ +static void +permute_store (rtx insn) +{ + rtx body = PATTERN (insn); + rtx src_reg = SET_SRC (body); + machine_mode mode = GET_MODE (src_reg); + int n_elts = GET_MODE_NUNITS (mode); + int half_elts = n_elts / 2; + rtx par = gen_rtx_PARALLEL (mode, rtvec_alloc (n_elts)); + int i, j; + for (i = 0, j = half_elts; i < half_elts; ++i, ++j) + XVECEXP (par, 0, i) = GEN_INT (j); + for (i = half_elts, j = 0; j < half_elts; ++i, ++j) + XVECEXP (par, 0, i) = GEN_INT (j); + rtx sel = gen_rtx_VEC_SELECT (mode, src_reg, par); + SET_SRC (body) = sel; + INSN_CODE (insn) = -1; /* Force re-recognition. */ + df_insn_rescan (insn); + + if (dump_file) + fprintf (dump_file, "Replacing store %d with permuted store\n", + INSN_UID (insn)); +} + +/* Given OP that contains a vector extract operation, adjust the index + of the extracted lane to account for the doubleword swap. */ +static void +adjust_extract (rtx insn) +{ + rtx pattern = PATTERN (insn); + if (GET_CODE (pattern) == PARALLEL) + pattern = XVECEXP (pattern, 0, 0); + rtx src = SET_SRC (pattern); + /* The vec_select may be wrapped in a vec_duplicate for a splat, so + account for that. */ + rtx sel = GET_CODE (src) == VEC_DUPLICATE ? XEXP (src, 0) : src; + rtx par = XEXP (sel, 1); + int half_elts = GET_MODE_NUNITS (GET_MODE (XEXP (sel, 0))) >> 1; + int lane = INTVAL (XVECEXP (par, 0, 0)); + lane = lane >= half_elts ? lane - half_elts : lane + half_elts; + XVECEXP (par, 0, 0) = GEN_INT (lane); + INSN_CODE (insn) = -1; /* Force re-recognition. */ + df_insn_rescan (insn); + + if (dump_file) + fprintf (dump_file, "Changing lane for extract %d\n", INSN_UID (insn)); +} + +/* Given OP that contains a vector direct-splat operation, adjust the index + of the source lane to account for the doubleword swap. */ +static void +adjust_splat (rtx insn) +{ + rtx body = PATTERN (insn); + rtx unspec = XEXP (body, 1); + int half_elts = GET_MODE_NUNITS (GET_MODE (unspec)) >> 1; + int lane = INTVAL (XVECEXP (unspec, 0, 1)); + lane = lane >= half_elts ? lane - half_elts : lane + half_elts; + XVECEXP (unspec, 0, 1) = GEN_INT (lane); + INSN_CODE (insn) = -1; /* Force re-recognition. */ + df_insn_rescan (insn); + + if (dump_file) + fprintf (dump_file, "Changing lane for splat %d\n", INSN_UID (insn)); +} + +/* The insn described by INSN_ENTRY[I] can be swapped, but only + with special handling. Take care of that here. */ +static void +handle_special_swappables (swap_web_entry *insn_entry, unsigned i) +{ + rtx insn = insn_entry[i].insn; + rtx body = PATTERN (insn); + + switch (insn_entry[i].special_handling) + { + default: + gcc_unreachable (); + case SH_CONST_VECTOR: + { + /* A CONST_VECTOR will only show up somewhere in the RHS of a SET. */ + gcc_assert (GET_CODE (body) == SET); + rtx rhs = SET_SRC (body); + swap_const_vector_halves (rhs); + if (dump_file) + fprintf (dump_file, "Swapping constant halves in insn %d\n", i); + break; + } + case SH_SUBREG: + /* A subreg of the same size is already safe. For subregs that + select a smaller portion of a reg, adjust the index for + swapped doublewords. */ + adjust_subreg_index (body); + if (dump_file) + fprintf (dump_file, "Adjusting subreg in insn %d\n", i); + break; + case SH_NOSWAP_LD: + /* Convert a non-permuting load to a permuting one. */ + permute_load (insn); + break; + case SH_NOSWAP_ST: + /* Convert a non-permuting store to a permuting one. */ + permute_store (insn); + break; + case SH_EXTRACT: + /* Change the lane on an extract operation. */ + adjust_extract (insn); + break; + case SH_SPLAT: + /* Change the lane on a direct-splat operation. */ + adjust_splat (insn); + break; + } +} + +/* Find the insn from the Ith table entry, which is known to be a + register swap Y = SWAP(X). Replace it with a copy Y = X. */ +static void +replace_swap_with_copy (swap_web_entry *insn_entry, unsigned i) +{ + rtx insn = insn_entry[i].insn; + rtx body = PATTERN (insn); + rtx src_reg = XEXP (SET_SRC (body), 0); + rtx copy = gen_rtx_SET (VOIDmode, SET_DEST (body), src_reg); + rtx new_insn = emit_insn_before (copy, insn); + set_block_for_insn (new_insn, BLOCK_FOR_INSN (insn)); + df_insn_rescan (new_insn); + + if (dump_file) + { + unsigned int new_uid = INSN_UID (new_insn); + fprintf (dump_file, "Replacing swap %d with copy %d\n", i, new_uid); + } + + df_insn_delete (BLOCK_FOR_INSN (insn), INSN_UID (insn)); + remove_insn (insn); + INSN_DELETED_P (insn) = 1; +} + +/* Dump the swap table to DUMP_FILE. */ +static void +dump_swap_insn_table (swap_web_entry *insn_entry) +{ + int e = get_max_uid (); + fprintf (dump_file, "\nRelevant insns with their flag settings\n\n"); + + for (int i = 0; i < e; ++i) + if (insn_entry[i].is_relevant) + { + swap_web_entry *pred_entry = (swap_web_entry *)insn_entry[i].pred (); + fprintf (dump_file, "%6d %6d ", i, + pred_entry && pred_entry->insn + ? INSN_UID (pred_entry->insn) : 0); + if (insn_entry[i].is_load) + fputs ("load ", dump_file); + if (insn_entry[i].is_store) + fputs ("store ", dump_file); + if (insn_entry[i].is_swap) + fputs ("swap ", dump_file); + if (insn_entry[i].is_live_in) + fputs ("live-in ", dump_file); + if (insn_entry[i].is_live_out) + fputs ("live-out ", dump_file); + if (insn_entry[i].contains_subreg) + fputs ("subreg ", dump_file); + if (insn_entry[i].is_128_int) + fputs ("int128 ", dump_file); + if (insn_entry[i].is_call) + fputs ("call ", dump_file); + if (insn_entry[i].is_swappable) + { + fputs ("swappable ", dump_file); + if (insn_entry[i].special_handling == SH_CONST_VECTOR) + fputs ("special:constvec ", dump_file); + else if (insn_entry[i].special_handling == SH_SUBREG) + fputs ("special:subreg ", dump_file); + else if (insn_entry[i].special_handling == SH_NOSWAP_LD) + fputs ("special:load ", dump_file); + else if (insn_entry[i].special_handling == SH_NOSWAP_ST) + fputs ("special:store ", dump_file); + else if (insn_entry[i].special_handling == SH_EXTRACT) + fputs ("special:extract ", dump_file); + else if (insn_entry[i].special_handling == SH_SPLAT) + fputs ("special:splat ", dump_file); + } + if (insn_entry[i].web_not_optimizable) + fputs ("unoptimizable ", dump_file); + if (insn_entry[i].will_delete) + fputs ("delete ", dump_file); + fputs ("\n", dump_file); + } + fputs ("\n", dump_file); +} + +/* Main entry point for this pass. */ +unsigned int +rs6000_analyze_swaps (function *fun) +{ + swap_web_entry *insn_entry; + basic_block bb; + rtx insn; + + /* Dataflow analysis for use-def chains. */ + df_set_flags (DF_RD_PRUNE_DEAD_DEFS); + df_chain_add_problem (DF_DU_CHAIN | DF_UD_CHAIN); + df_analyze (); + df_set_flags (DF_DEFER_INSN_RESCAN); + + /* Allocate structure to represent webs of insns. */ + insn_entry = XCNEWVEC (swap_web_entry, get_max_uid ()); + + /* Walk the insns to gather basic data. */ + FOR_ALL_BB_FN (bb, fun) + FOR_BB_INSNS (bb, insn) + { + unsigned int uid = INSN_UID (insn); + if (NONDEBUG_INSN_P (insn)) + { + insn_entry[uid].insn = insn; + + if (GET_CODE (insn) == CALL_INSN) + insn_entry[uid].is_call = 1; + + /* Walk the uses and defs to see if we mention vector regs. + Record any constraints on optimization of such mentions. */ + df_ref *use_rec; + for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) + { + df_ref mention = *use_rec; + /* We use DF_REF_REAL_REG here to get inside any subregs. */ + machine_mode mode = GET_MODE (DF_REF_REAL_REG (mention)); + + /* If a use gets its value from a call insn, it will be + a hard register and will look like (reg:V4SI 3 3). + The df analysis creates two mentions for GPR3 and GPR4, + both DImode. We must recognize this and treat it as a + vector mention to ensure the call is unioned with this + use. */ + if (mode == DImode && DF_REF_INSN_INFO (mention)) + { + rtx feeder = DF_REF_INSN (mention); + /* FIXME: It is pretty hard to get from the df mention + to the mode of the use in the insn. We arbitrarily + pick a vector mode here, even though the use might + be a real DImode. We can be too conservative + (create a web larger than necessary) because of + this, so consider eventually fixing this. */ + if (GET_CODE (feeder) == CALL_INSN) + mode = V4SImode; + } + + if (VECTOR_MODE_P (mode) || mode == TImode) + { + insn_entry[uid].is_relevant = 1; + if (mode == TImode || mode == V1TImode) + insn_entry[uid].is_128_int = 1; + if (DF_REF_INSN_INFO (mention)) + insn_entry[uid].contains_subreg + = !rtx_equal_p (DF_REF_REG (mention), + DF_REF_REAL_REG (mention)); + union_defs (insn_entry, insn, mention); + } + } + df_ref *def_rec; + for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + { + df_ref mention = *def_rec; + /* We use DF_REF_REAL_REG here to get inside any subregs. */ + machine_mode mode = GET_MODE (DF_REF_REAL_REG (mention)); + + /* If we're loading up a hard vector register for a call, + it looks like (set (reg:V4SI 9 9) (...)). The df + analysis creates two mentions for GPR9 and GPR10, both + DImode. So relying on the mode from the mentions + isn't sufficient to ensure we union the call into the + web with the parameter setup code. */ + if (mode == DImode && GET_CODE (insn) == SET + && VECTOR_MODE_P (GET_MODE (SET_DEST (insn)))) + mode = GET_MODE (SET_DEST (insn)); + + if (VECTOR_MODE_P (mode) || mode == TImode) + { + insn_entry[uid].is_relevant = 1; + if (mode == TImode || mode == V1TImode) + insn_entry[uid].is_128_int = 1; + if (DF_REF_INSN_INFO (mention)) + insn_entry[uid].contains_subreg + = !rtx_equal_p (DF_REF_REG (mention), + DF_REF_REAL_REG (mention)); + /* REG_FUNCTION_VALUE_P is not valid for subregs. */ + else if (REG_FUNCTION_VALUE_P (DF_REF_REG (mention))) + insn_entry[uid].is_live_out = 1; + union_uses (insn_entry, insn, mention); + } + } + + if (insn_entry[uid].is_relevant) + { + /* Determine if this is a load or store. */ + insn_entry[uid].is_load = insn_is_load_p (insn); + insn_entry[uid].is_store = insn_is_store_p (insn); + + /* Determine if this is a doubleword swap. If not, + determine whether it can legally be swapped. */ + if (insn_is_swap_p (insn)) + insn_entry[uid].is_swap = 1; + else + { + unsigned int special = SH_NONE; + insn_entry[uid].is_swappable + = insn_is_swappable_p (insn_entry, insn, &special); + if (special != SH_NONE && insn_entry[uid].contains_subreg) + insn_entry[uid].is_swappable = 0; + else if (special != SH_NONE) + insn_entry[uid].special_handling = special; + else if (insn_entry[uid].contains_subreg) + insn_entry[uid].special_handling = SH_SUBREG; + } + } + } + } + + if (dump_file) + { + fprintf (dump_file, "\nSwap insn entry table when first built\n"); + dump_swap_insn_table (insn_entry); + } + + /* Record unoptimizable webs. */ + unsigned e = get_max_uid (), i; + for (i = 0; i < e; ++i) + { + if (!insn_entry[i].is_relevant) + continue; + + swap_web_entry *root + = (swap_web_entry*)(&insn_entry[i])->unionfind_root (); + unsigned uid = INSN_UID (insn_entry[i].insn); + + if (insn_entry[i].is_live_in || insn_entry[i].is_live_out + || (insn_entry[i].contains_subreg + && insn_entry[i].special_handling != SH_SUBREG) + || insn_entry[i].is_128_int || insn_entry[i].is_call + || !(insn_entry[i].is_swappable || insn_entry[i].is_swap)) + root->web_not_optimizable = 1; + + /* If we have loads or stores that aren't permuting then the + optimization isn't appropriate. */ + else if ((insn_entry[i].is_load || insn_entry[i].is_store) + && !insn_entry[i].is_swap && !insn_entry[i].is_swappable) + root->web_not_optimizable = 1; + + /* If we have permuting loads or stores that are not accompanied + by a register swap, the optimization isn't appropriate. */ + else if (insn_entry[i].is_load && insn_entry[i].is_swap) + { + df_ref *def_rec; + + for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + { + df_ref def = *def_rec; + struct df_link *link = DF_REF_CHAIN (def); + + if (!chain_contains_only_swaps (insn_entry, link, FOR_LOADS)) + { + root->web_not_optimizable = 1; + break; + } + } + } + else if (insn_entry[i].is_store && insn_entry[i].is_swap) + { + df_ref *use_rec; + + for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) + { + df_ref use = *use_rec; + struct df_link *link = DF_REF_CHAIN (use); + + if (!chain_contains_only_swaps (insn_entry, link, FOR_STORES)) + { + root->web_not_optimizable = 1; + break; + } + } + } + } + + if (dump_file) + { + fprintf (dump_file, "\nSwap insn entry table after web analysis\n"); + dump_swap_insn_table (insn_entry); + } + + /* For each load and store in an optimizable web (which implies + the loads and stores are permuting), find the associated + register swaps and mark them for removal. Due to various + optimizations we may mark the same swap more than once. Also + perform special handling for swappable insns that require it. */ + for (i = 0; i < e; ++i) + if ((insn_entry[i].is_load || insn_entry[i].is_store) + && insn_entry[i].is_swap) + { + swap_web_entry* root_entry + = (swap_web_entry*)((&insn_entry[i])->unionfind_root ()); + if (!root_entry->web_not_optimizable) + mark_swaps_for_removal (insn_entry, i); + } + else if (insn_entry[i].is_swappable && insn_entry[i].special_handling) + { + swap_web_entry* root_entry + = (swap_web_entry*)((&insn_entry[i])->unionfind_root ()); + if (!root_entry->web_not_optimizable) + handle_special_swappables (insn_entry, i); + } + + /* Now delete the swaps marked for removal. */ + for (i = 0; i < e; ++i) + if (insn_entry[i].will_delete) + replace_swap_with_copy (insn_entry, i); + + /* Clean up. */ + free (insn_entry); + return 0; +} struct gcc_target targetm = TARGET_INITIALIZER; diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index a408e3e9218..450e1655e07 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -898,7 +898,8 @@ enum data_align { align_abi, align_opt, align_both }; || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \ || (MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode) \ && (ALIGN) < 32) \ - || (VECTOR_MODE_P ((MODE)) && (((int)(ALIGN)) < VECTOR_ALIGN (MODE)))) + || (!TARGET_EFFICIENT_UNALIGNED_VSX \ + && (VECTOR_MODE_P ((MODE)) && (((int)(ALIGN)) < VECTOR_ALIGN (MODE))))) /* Standard register usage. */ diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 5b56eb0da56..87420972bab 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -1,6 +1,6 @@ ; Options for the rs6000 port of the compiler ; -; Copyright (C) 2005-2014 Free Software Foundation, Inc. +; Copyright (C) 2005-2015 Free Software Foundation, Inc. ; Contributed by Aldy Hernandez <aldy@quesejoda.com>. ; ; This file is part of GCC. @@ -201,31 +201,35 @@ mvsx-scalar-memory Target Undocumented Report Alias(mupper-regs-df) mvsx-align-128 -Target Undocumented Report Var(TARGET_VSX_ALIGN_128) +Target Undocumented Report Var(TARGET_VSX_ALIGN_128) Save ; If -mvsx, set alignment to 128 bits instead of 32/64 mallow-movmisalign -Target Undocumented Var(TARGET_ALLOW_MOVMISALIGN) Init(-1) +Target Undocumented Var(TARGET_ALLOW_MOVMISALIGN) Init(-1) Save ; Allow/disallow the movmisalign in DF/DI vectors +mefficient-unaligned-vector +Target Undocumented Report Var(TARGET_EFFICIENT_UNALIGNED_VSX) Init(-1) Save +; Consider unaligned VSX accesses to be efficient/inefficient + mallow-df-permute -Target Undocumented Var(TARGET_ALLOW_DF_PERMUTE) +Target Undocumented Var(TARGET_ALLOW_DF_PERMUTE) Save ; Allow/disallow permutation of DF/DI vectors msched-groups -Target Undocumented Report Var(TARGET_SCHED_GROUPS) Init(-1) +Target Undocumented Report Var(TARGET_SCHED_GROUPS) Init(-1) Save ; Explicitly set/unset whether rs6000_sched_groups is set malways-hint -Target Undocumented Report Var(TARGET_ALWAYS_HINT) Init(-1) +Target Undocumented Report Var(TARGET_ALWAYS_HINT) Init(-1) Save ; Explicitly set/unset whether rs6000_always_hint is set malign-branch-targets -Target Undocumented Report Var(TARGET_ALIGN_BRANCH_TARGETS) Init(-1) +Target Undocumented Report Var(TARGET_ALIGN_BRANCH_TARGETS) Init(-1) Save ; Explicitly set/unset whether rs6000_align_branch_targets is set mvectorize-builtins -Target Undocumented Report Var(TARGET_VECTORIZE_BUILTINS) Init(-1) +Target Undocumented Report Var(TARGET_VECTORIZE_BUILTINS) Init(-1) Save ; Explicitly control whether we vectorize the builtins or not. mno-update @@ -535,7 +539,7 @@ Target Report Var(TARGET_POINTERS_TO_NESTED_FUNCTIONS) Init(1) Save Use/do not use r11 to hold the static link in calls to functions via pointers. msave-toc-indirect -Target Report Var(TARGET_SAVE_TOC_INDIRECT) Save +Target Report Mask(SAVE_TOC_INDIRECT) Var(rs6000_isa_flags) Control whether we save the TOC in the prologue for indirect calls or generate the save inline mvsx-timode @@ -556,7 +560,7 @@ Use/do not use vector and scalar instructions added in ISA 2.07. mcrypto Target Report Mask(CRYPTO) Var(rs6000_isa_flags) -Use ISA 2.07 crypto instructions +Use ISA 2.07 Category:Vector.AES and Category:Vector.SHA2 instructions mdirect-move Target Report Mask(DIRECT_MOVE) Var(rs6000_isa_flags) @@ -575,7 +579,7 @@ Target Report Mask(QUAD_MEMORY_ATOMIC) Var(rs6000_isa_flags) Generate the quad word memory atomic instructions (lqarx/stqcx). mcompat-align-parm -Target Report Var(rs6000_compat_align_parm) Init(1) Save +Target Report Var(rs6000_compat_align_parm) Init(0) Save Generate aggregate parameter passing code with at most 64-bit alignment. mupper-regs-df @@ -585,3 +589,7 @@ Allow double variables in upper registers with -mcpu=power7 or -mvsx mupper-regs-sf Target Undocumented Mask(UPPER_REGS_SF) Var(rs6000_isa_flags) Allow float variables in upper registers with -mcpu=power8 or -mp8-vector + +moptimize-swaps +Target Undocumented Var(rs6000_optimize_swaps) Init(1) Save +Analyze and remove doubleword swaps from VSX computations. diff --git a/gcc/config/rs6000/t-fprules b/gcc/config/rs6000/t-fprules index 2ae04da27a3..46f581a9093 100644 --- a/gcc/config/rs6000/t-fprules +++ b/gcc/config/rs6000/t-fprules @@ -18,9 +18,3 @@ SOFT_FLOAT_CPUS = e300c2 401 403 405 440 464 476 ec603e 801 821 823 860 MULTILIB_MATCHES_FLOAT = $(foreach cpu, $(SOFT_FLOAT_CPUS), msoft-float=mcpu?$(cpu)) - -# Build the libraries for both hard and soft floating point by default - -MULTILIB_OPTIONS = msoft-float -MULTILIB_DIRNAMES = soft-float -MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} diff --git a/gcc/config/rs6000/t-linux b/gcc/config/rs6000/t-linux index 017a293cde3..8900e546969 100644 --- a/gcc/config/rs6000/t-linux +++ b/gcc/config/rs6000/t-linux @@ -1,9 +1,19 @@ # do not define the multiarch name if configured for a soft-float cpu # or soft-float. ifeq (,$(filter $(with_cpu),$(SOFT_FLOAT_CPUS))$(findstring soft,$(with_float))) +ifneq (,$(findstring powerpc64,$(target))) +MULTILIB_OSDIRNAMES := .=../lib64$(call if_multiarch,:powerpc64-linux-gnu) +else ifneq (,$(findstring spe,$(target))) -MULTIARCH_DIRNAME = powerpc-linux-gnuspe$(if $(findstring rs6000/e500-double.h, $(tm_file_list)),,v1) +MULTIARCH_DIRNAME := powerpc-linux-gnuspe$(if $(findstring rs6000/e500-double.h, $(tm_file_list)),,v1) else -MULTIARCH_DIRNAME = powerpc-linux-gnu +MULTIARCH_DIRNAME := powerpc-linux-gnu +endif +endif +ifneq (,$(findstring powerpcle,$(target))) +MULTIARCH_DIRNAME := $(subst -linux,le-linux,$(MULTIARCH_DIRNAME)) +endif +ifneq (,$(findstring powerpc64le,$(target))) +MULTILIB_OSDIRNAMES := $(subst -linux,le-linux,$(MULTILIB_OSDIRNAMES)) endif endif diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 8f171946d86..0d85ccab138 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -1781,22 +1781,7 @@ (vec_select:<VS_scalar> (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z,Z,Z") (parallel [(const_int 0)])))] - "VECTOR_MEM_VSX_P (<MODE>mode) && WORDS_BIG_ENDIAN" - "lxsd%U1x %x0,%y1" - [(set (attr "type") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (const_string "fpload"))) - (set_attr "length" "4")]) - -;; Optimize extracting element 1 from memory for little endian -(define_insn "*vsx_extract_<mode>_one_le" - [(set (match_operand:<VS_scalar> 0 "vsx_register_operand" "=ws,d,?wa") - (vec_select:<VS_scalar> - (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z,Z,Z") - (parallel [(const_int 1)])))] - "VECTOR_MEM_VSX_P (<MODE>mode) && !WORDS_BIG_ENDIAN" + "VECTOR_MEM_VSX_P (<MODE>mode)" "lxsd%U1x %x0,%y1" [(set (attr "type") (if_then_else diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 4fcefd70735..57cd8bdbca9 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -407,24 +407,9 @@ struct GTY(()) machine_function bytes on a z10 (or higher) CPU. */ #define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048) -static const int s390_hotpatch_trampoline_halfwords_default = 12; -static const int s390_hotpatch_trampoline_halfwords_max = 1000000; -static int s390_hotpatch_trampoline_halfwords = -1; - -/* Return the argument of the given hotpatch attribute or the default value if - no argument is present. */ - -static inline int -get_hotpatch_attribute (tree hotpatch_attr) -{ - const_tree args; - - args = TREE_VALUE (hotpatch_attr); - - return (args) ? - TREE_INT_CST_LOW (TREE_VALUE (args)): - s390_hotpatch_trampoline_halfwords_default; -} +static const int s390_hotpatch_hw_max = 1000000; +static int s390_hotpatch_hw_before_label = 0; +static int s390_hotpatch_hw_after_label = 0; /* Check whether the hotpatch attribute is applied to a function and, if it has an argument, the argument is valid. */ @@ -433,34 +418,48 @@ static tree s390_handle_hotpatch_attribute (tree *node, tree name, tree args, int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) { + tree expr; + tree expr2; + int err; + if (TREE_CODE (*node) != FUNCTION_DECL) { warning (OPT_Wattributes, "%qE attribute only applies to functions", name); *no_add_attrs = true; } - else if (args) + if (args != NULL && TREE_CHAIN (args) != NULL) + { + expr = TREE_VALUE (args); + expr2 = TREE_VALUE (TREE_CHAIN (args)); + } + if (args == NULL || TREE_CHAIN (args) == NULL) + err = 1; + else if (TREE_CODE (expr) != INTEGER_CST + || !INTEGRAL_TYPE_P (TREE_TYPE (expr)) + || TREE_INT_CST_HIGH (expr) != 0 + || TREE_INT_CST_LOW (expr) > (unsigned int)s390_hotpatch_hw_max) + err = 1; + else if (TREE_CODE (expr2) != INTEGER_CST + || !INTEGRAL_TYPE_P (TREE_TYPE (expr2)) + || TREE_INT_CST_HIGH (expr2) != 0 + || TREE_INT_CST_LOW (expr2) > (unsigned int)s390_hotpatch_hw_max) + err = 1; + else + err = 0; + if (err) { - tree expr = TREE_VALUE (args); - - if (TREE_CODE (expr) != INTEGER_CST - || !INTEGRAL_TYPE_P (TREE_TYPE (expr)) - || TREE_INT_CST_HIGH (expr) != 0 - || TREE_INT_CST_LOW (expr) > (unsigned int) - s390_hotpatch_trampoline_halfwords_max) - { - error ("requested %qE attribute is not a non-negative integer" - " constant or too large (max. %d)", name, - s390_hotpatch_trampoline_halfwords_max); - *no_add_attrs = true; - } + error ("requested %qE attribute is not a comma separated pair of" + " non-negative integer constants or too large (max. %d)", name, + s390_hotpatch_hw_max); + *no_add_attrs = true; } return NULL_TREE; } static const struct attribute_spec s390_attribute_table[] = { - { "hotpatch", 0, 1, true, false, false, s390_handle_hotpatch_attribute, false + { "hotpatch", 2, 2, true, false, false, s390_handle_hotpatch_attribute, false }, /* End element. */ { NULL, 0, 0, false, false, false, NULL, false } @@ -1664,29 +1663,44 @@ s390_option_override (void) { switch (opt->opt_index) { - case OPT_mhotpatch: - s390_hotpatch_trampoline_halfwords = (opt->value) ? - s390_hotpatch_trampoline_halfwords_default : -1; - break; case OPT_mhotpatch_: { - int val; - - val = integral_argument (opt->arg); - if (val == -1) + int val1; + int val2; + char s[256]; + char *t; + + strncpy (s, opt->arg, 256); + s[255] = 0; + t = strchr (s, ','); + if (t != NULL) + { + *t = 0; + t++; + val1 = integral_argument (s); + val2 = integral_argument (t); + } + else + { + val1 = -1; + val2 = -1; + } + if (val1 == -1 || val2 == -1) { /* argument is not a plain number */ - error ("argument to %qs should be a non-negative integer", - "-mhotpatch="); + error ("arguments to %qs should be non-negative integers", + "-mhotpatch=n,m"); break; } - else if (val > s390_hotpatch_trampoline_halfwords_max) + else if (val1 > s390_hotpatch_hw_max + || val2 > s390_hotpatch_hw_max) { error ("argument to %qs is too large (max. %d)", - "-mhotpatch=", s390_hotpatch_trampoline_halfwords_max); + "-mhotpatch=n,m", s390_hotpatch_hw_max); break; } - s390_hotpatch_trampoline_halfwords = val; + s390_hotpatch_hw_before_label = val1; + s390_hotpatch_hw_after_label = val2; break; } default: @@ -5418,54 +5432,37 @@ get_some_local_dynamic_name (void) gcc_unreachable (); } -/* Returns -1 if the function should not be made hotpatchable. Otherwise it - returns a number >= 0 that is the desired size of the hotpatch trampoline - in halfwords. */ +/* Assigns the number of NOP halfwords to be emitted before and after the + function label to *HW_BEFORE and *HW_AFTER. Both pointers must not be NULL. + If hotpatching is disabled for the function, the values are set to zero. +*/ -static int s390_function_num_hotpatch_trampoline_halfwords (tree decl, - bool do_warn) +static void +s390_function_num_hotpatch_hw (tree decl, + int *hw_before, + int *hw_after) { tree attr; - if (DECL_DECLARED_INLINE_P (decl) - || DECL_ARTIFICIAL (decl) - || MAIN_NAME_P (DECL_NAME (decl))) + attr = lookup_attribute ("hotpatch", DECL_ATTRIBUTES (decl)); + + if (attr) { - /* - Explicitly inlined functions cannot be hotpatched. - - Artificial functions need not be hotpatched. - - Making the main function hotpatchable is useless. */ - return -1; + tree args = TREE_VALUE (attr); + + /* If the hotpatch attribute is present, its values are used even if the + -mhotpatch cmdline option is used. */ + *hw_before = TREE_INT_CST_LOW (TREE_VALUE (args)); + *hw_after = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))); } - attr = lookup_attribute ("hotpatch", DECL_ATTRIBUTES (decl)); - if (attr || s390_hotpatch_trampoline_halfwords >= 0) + else { - if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))) - { - if (do_warn) - warning (OPT_Wattributes, "function %qE with the %qs attribute" - " is not hotpatchable", DECL_NAME (decl), "always_inline"); - return -1; - } - else - { - return (attr) ? - get_hotpatch_attribute (attr) : s390_hotpatch_trampoline_halfwords; - } + /* Values specified by the -mhotpatch cmdline option. */ + *hw_before = s390_hotpatch_hw_before_label; + *hw_after = s390_hotpatch_hw_after_label; } - - return -1; } -/* Hook to determine if one function can safely inline another. */ - -static bool -s390_can_inline_p (tree caller, tree callee) -{ - if (s390_function_num_hotpatch_trampoline_halfwords (callee, false) >= 0) - return false; - - return default_target_can_inline_p (caller, callee); -} /* Write the extra assembler code needed to declare a function properly. */ @@ -5473,44 +5470,46 @@ void s390_asm_output_function_label (FILE *asm_out_file, const char *fname, tree decl) { - int hotpatch_trampoline_halfwords = -1; - - if (decl) - { - hotpatch_trampoline_halfwords = - s390_function_num_hotpatch_trampoline_halfwords (decl, true); - if (hotpatch_trampoline_halfwords >= 0 - && decl_function_context (decl) != NULL_TREE) - { - warning_at (DECL_SOURCE_LOCATION (decl), OPT_mhotpatch, - "hotpatching is not compatible with nested functions"); - hotpatch_trampoline_halfwords = -1; - } - } + int hw_before, hw_after; - if (hotpatch_trampoline_halfwords > 0) + s390_function_num_hotpatch_hw (decl, &hw_before, &hw_after); + if (hw_before > 0) { + unsigned int function_alignment; int i; - /* Add a trampoline code area before the function label and initialize it - with two-byte nop instructions. This area can be overwritten with code + /* Add trampoline code area before the function label and initialize it + with two-byte NOP instructions. This area can be overwritten with code that jumps to a patched version of the function. */ - for (i = 0; i < hotpatch_trampoline_halfwords; i++) - asm_fprintf (asm_out_file, "\tnopr\t%%r7\n"); + asm_fprintf (asm_out_file, "\tnopr\t%%r7" + "\t# pre-label NOPs for hotpatch (%d halfwords)\n", + hw_before); + for (i = 1; i < hw_before; i++) + fputs ("\tnopr\t%r7\n", asm_out_file); + /* Note: The function label must be aligned so that (a) the bytes of the - following nop do not cross a cacheline boundary, and (b) a jump address + following NOP do not cross a cacheline boundary, and (b) a jump address (eight bytes for 64 bit targets, 4 bytes for 32 bit targets) can be stored directly before the label without crossing a cacheline boundary. All this is necessary to make sure the trampoline code can - be changed atomically. */ + be changed atomically. + This alignment is done automatically using the FOUNCTION_BOUNDARY + macro, but if there are NOPs before the function label, the alignment + is placed before them. So it is necessary to duplicate the alignment + after the NOPs. */ + function_alignment = MAX (8, DECL_ALIGN (decl) / BITS_PER_UNIT); + if (! DECL_USER_ALIGN (decl)) + function_alignment = MAX (function_alignment, + (unsigned int) align_functions); + fputs ("\t# alignment for hotpatch\n", asm_out_file); + ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (function_alignment)); } ASM_OUTPUT_LABEL (asm_out_file, fname); - - /* Output a four-byte nop if hotpatching is enabled. This can be overwritten - atomically with a relative backwards jump to the trampoline area. */ - if (hotpatch_trampoline_halfwords >= 0) - asm_fprintf (asm_out_file, "\tnop\t0\n"); + if (hw_after > 0) + asm_fprintf (asm_out_file, + "\t# post-label NOPs for hotpatch (%d halfwords)\n", + hw_after); } /* Output machine-dependent UNSPECs occurring in address constant X @@ -11121,6 +11120,7 @@ static void s390_reorg (void) { bool pool_overflow = false; + int hw_before, hw_after; /* Make sure all splits have been performed; splits after machine_dependent_reorg might confuse insn length counts. */ @@ -11255,6 +11255,40 @@ s390_reorg (void) if (insn_added_p) shorten_branches (get_insns ()); } + + s390_function_num_hotpatch_hw (current_function_decl, &hw_before, &hw_after); + if (hw_after > 0) + { + rtx insn; + + /* Insert NOPs for hotpatching. */ + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + { + if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) + break; + } + gcc_assert (insn); + /* Output a series of NOPs after the NOTE_INSN_FUNCTION_BEG. */ + while (hw_after > 0) + { + if (hw_after >= 3 && TARGET_CPU_ZARCH) + { + insn = emit_insn_after (gen_nop_6_byte (), insn); + hw_after -= 3; + } + else if (hw_after >= 2) + { + insn = emit_insn_after (gen_nop_4_byte (), insn); + hw_after -= 2; + } + else + { + insn = emit_insn_after (gen_nop_2_byte (), insn); + hw_after -= 1; + } + } + gcc_assert (hw_after == 0); + } } /* Return true if INSN is a fp load insn writing register REGNO. */ @@ -11817,8 +11851,8 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop) #undef TARGET_ATTRIBUTE_TABLE #define TARGET_ATTRIBUTE_TABLE s390_attribute_table -#undef TARGET_CAN_INLINE_P -#define TARGET_CAN_INLINE_P s390_can_inline_p +#undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P +#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true struct gcc_target targetm = TARGET_INITIALIZER; diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index fab189843c8..5e6f4d58cdb 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -145,6 +145,11 @@ UNSPECV_CAS UNSPECV_ATOMIC_OP + ; Hotpatching (unremovable NOPs) + UNSPECV_NOP_2_BYTE + UNSPECV_NOP_4_BYTE + UNSPECV_NOP_6_BYTE + ; Transactional Execution support UNSPECV_TBEGIN UNSPECV_TBEGIN_TDB @@ -9440,6 +9445,26 @@ "lr\t1,1" [(set_attr "op_type" "RR")]) +;;- Undeletable nops (used for hotpatching) + +(define_insn "nop_2_byte" + [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)] + "" + "nopr\t%%r7" + [(set_attr "op_type" "RR")]) + +(define_insn "nop_4_byte" + [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)] + "" + "nop\t0" + [(set_attr "op_type" "RX")]) + +(define_insn "nop_6_byte" + [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)] + "TARGET_CPU_ZARCH" + "brcl\t0, 0" + [(set_attr "op_type" "RIL")]) + ; ; Special literal pool access instruction pattern(s). diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt index 65d17c3342e..615e4dde206 100644 --- a/gcc/config/s390/s390.opt +++ b/gcc/config/s390/s390.opt @@ -96,13 +96,15 @@ mhard-float Target Report RejectNegative Negative(msoft-float) InverseMask(SOFT_FLOAT, HARD_FLOAT) Enable hardware floating point -mhotpatch -Target Report Var(s390_deferred_options) Defer -Prepend the function label with 12 two-byte Nop instructions, and add a four byte Nop instruction after the label for hotpatching. - mhotpatch= Target RejectNegative Report Joined Var(s390_deferred_options) Defer -Prepend the function label with the given number of two-byte Nop instructions, and add a four byte Nop instruction after the label for hotpatching. +Takes two non-negative integer numbers separated by a comma. +Prepend the function label with the number of two-byte Nop +instructions indicated by the first. Append Nop instructions +covering the number of halfwords indicated by the second after the +label. Nop instructions of the largest possible size are used +(six, four or two bytes), beginning with the largest possible +size. Using 0 for both values disables hotpatching. mlong-double-128 Target Report RejectNegative Negative(mlong-double-64) Mask(LONG_DOUBLE_128) diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index f86ae3d3e1e..1c4142c308e 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -651,32 +651,6 @@ "tst #255,%0" [(set_attr "type" "mt_group")]) -;; This pattern might be risky because it also tests the upper bits and not -;; only the subreg. However, it seems that combine will get to this only -;; when testing sign/zero extended values. In this case the extended upper -;; bits do not matter. -(define_insn "*tst<mode>_t_zero" - [(set (reg:SI T_REG) - (eq:SI - (subreg:QIHI - (and:SI (match_operand:SI 0 "arith_reg_operand" "%r") - (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_le>) - (const_int 0)))] - "TARGET_SH1 && TARGET_LITTLE_ENDIAN" - "tst %0,%1" - [(set_attr "type" "mt_group")]) - -(define_insn "*tst<mode>_t_zero" - [(set (reg:SI T_REG) - (eq:SI - (subreg:QIHI - (and:SI (match_operand:SI 0 "arith_reg_operand" "%r") - (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_be>) - (const_int 0)))] - "TARGET_SH1 && !TARGET_LITTLE_ENDIAN" - "tst %0,%1" - [(set_attr "type" "mt_group")]) - ;; Extract LSB, negate and store in T bit. (define_insn "tstsi_t_and_not" [(set (reg:SI T_REG) @@ -5649,7 +5623,7 @@ label: (define_insn "swapbsi2" [(set (match_operand:SI 0 "arith_reg_dest" "=r") (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "r") - (const_int 4294901760)) + (const_int -65536)) ;; 0xFFFF0000 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8)) (const_int 65280)) (and:SI (ashiftrt:SI (match_dup 1) (const_int 8)) @@ -5717,7 +5691,7 @@ label: (define_peephole2 [(set (match_operand:SI 0 "arith_reg_dest" "") (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "") - (const_int 4294901760)) + (const_int -65536)) ;; 0xFFFF0000 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8)) (const_int 65280)) (and:SI (ashiftrt:SI (match_dup 1) (const_int 8)) @@ -5727,7 +5701,7 @@ label: "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])" [(set (match_dup 2) (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "") - (const_int 4294901760)) + (const_int -65536)) ;; 0xFFFF0000 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8)) (const_int 65280)) (and:SI (ashiftrt:SI (match_dup 1) (const_int 8)) diff --git a/gcc/config/sh/t-sh b/gcc/config/sh/t-sh index a7e028dc0cf..7b75d61ed47 100644 --- a/gcc/config/sh/t-sh +++ b/gcc/config/sh/t-sh @@ -51,8 +51,12 @@ MULTILIB_MATCHES = $(shell \ done \ done) -# SH1 only supports big endian. +# SH1 and SH2A support big endian only. +ifeq ($(DEFAULT_ENDIAN),ml) +MULTILIB_EXCEPTIONS = m1 ml/m1 m2a* ml/m2a* $(TM_MULTILIB_EXCEPTIONS_CONFIG) +else MULTILIB_EXCEPTIONS = ml/m1 ml/m2a* $(TM_MULTILIB_EXCEPTIONS_CONFIG) +endif MULTILIB_OSDIRNAMES = \ $(OTHER_ENDIAN)=!$(OTHER_ENDIAN) \ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9239750e472..58f9161c078 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2015-04-23 Marek Polacek <polacek@redhat.com> + + PR c++/65727 + * semantics.c (maybe_resolve_dummy): Handle null return. + +2015-04-23 Jason Merrill <jason@redhat.com> + + PR c++/65721 + * name-lookup.c (do_class_using_decl): Complain about specifying + the current class even if there are dependent bases. + 2015-01-13 Jason Merrill <jason@redhat.com> PR c++/64487 diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index da167ec4158..9091e75e230 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3288,7 +3288,7 @@ do_class_using_decl (tree scope, tree name) tf_warning_or_error); if (b_kind < bk_proper_base) { - if (!bases_dependent_p) + if (!bases_dependent_p || b_kind == bk_same_type) { error_not_base_type (scope, current_class_type); return NULL_TREE; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 329f12f0900..b833b079a6b 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -9633,8 +9633,9 @@ maybe_resolve_dummy (tree object) /* In a lambda, need to go through 'this' capture. */ tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type); tree cap = lambda_expr_this_capture (lam); - object = build_x_indirect_ref (EXPR_LOCATION (object), cap, - RO_NULL, tf_warning_or_error); + if (cap && cap != error_mark_node) + object = build_x_indirect_ref (EXPR_LOCATION (object), cap, + RO_NULL, tf_warning_or_error); } return object; @@ -1132,20 +1132,22 @@ df_get_artificial_uses (unsigned int bb_index) /* web */ -/* This entry is allocated for each reference in the insn stream. */ -struct web_entry +class web_entry_base { - /* Pointer to the parent in the union/find tree. */ - struct web_entry *pred; - /* Newly assigned register to the entry. Set only for roots. */ - rtx reg; - void* extra_info; -}; + private: + /* Reference to the parent in the union/find tree. */ + web_entry_base *pred_pvt; + + public: + /* Accessors. */ + web_entry_base *pred () { return pred_pvt; } + void set_pred (web_entry_base *p) { pred_pvt = p; } -extern struct web_entry *unionfind_root (struct web_entry *); -extern bool unionfind_union (struct web_entry *, struct web_entry *); -extern void union_defs (df_ref, struct web_entry *, - unsigned int *used, struct web_entry *, - bool (*fun) (struct web_entry *, struct web_entry *)); + /* Find representative in union-find tree. */ + web_entry_base *unionfind_root (); + + /* Union with another set, returning TRUE if they are already unioned. */ + friend bool unionfind_union (web_entry_base *first, web_entry_base *second); +}; #endif /* GCC_DF_H */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index dc3e0bcba46..a8554665126 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3123,16 +3123,19 @@ this function attribute to make GCC generate the ``hot-patching'' function prologue used in Win32 API functions in Microsoft Windows XP Service Pack 2 and newer. -@item hotpatch [(@var{prologue-halfwords})] +@item hotpatch (@var{halfwords-before-function-label},@var{halfwords-after-function-label}) @cindex @code{hotpatch} attribute On S/390 System z targets, you can use this function attribute to -make GCC generate a ``hot-patching'' function prologue. The -@code{hotpatch} has no effect on funtions that are explicitly -inline. If the @option{-mhotpatch} or @option{-mno-hotpatch} -command-line option is used at the same time, the @code{hotpatch} -attribute takes precedence. If an argument is given, the maximum -allowed value is 1000000. +make GCC generate a ``hot-patching'' function prologue. If the +@option{-mhotpatch=} command-line option is used at the same time, +the @code{hotpatch} attribute takes precedence. The first of the +two arguments specifies the number of halfwords to be added before +the function label. A second argument can be used to specify the +number of halfwords to be added after the function label. For +both arguments the maximum allowed value is 1000000. + +If both ar guments are zero, hotpatching is disabled. @item naked @cindex function without a prologue/epilogue code diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d5a67877140..3e8f44f2bc8 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1,4 +1,4 @@ -@c Copyright (C) 1988-2013 Free Software Foundation, Inc. +@c Copyright (C) 1988-2015 Free Software Foundation, Inc. @c This is part of the GCC manual. @c For copying conditions, see the file gcc.texi. @@ -888,7 +888,7 @@ See RS/6000 and PowerPC Options. -m64 -m31 -mdebug -mno-debug -mesa -mzarch @gol -mtpf-trace -mno-tpf-trace -mfused-madd -mno-fused-madd @gol -mwarn-framesize -mwarn-dynamicstack -mstack-size -mstack-guard @gol --mhotpatch[=@var{halfwords}] -mno-hotpatch} +-mhotpatch=@var{halfwords},@var{halfwords}} @emph{Score Options} @gccoptlist{-meb -mel @gol @@ -17259,12 +17259,13 @@ Supported values for @var{cpu_type} are @samp{401}, @samp{403}, @samp{e6500}, @samp{ec603e}, @samp{G3}, @samp{G4}, @samp{G5}, @samp{titan}, @samp{power3}, @samp{power4}, @samp{power5}, @samp{power5+}, @samp{power6}, @samp{power6x}, @samp{power7}, @samp{power8}, @samp{powerpc}, -@samp{powerpc64}, and @samp{rs64}. +@samp{powerpc64}, @samp{powerpc64le}, and @samp{rs64}. -@option{-mcpu=powerpc}, and @option{-mcpu=powerpc64} specify pure 32-bit -PowerPC and 64-bit PowerPC architecture machine -types, with an appropriate, generic processor model assumed for -scheduling purposes. +@option{-mcpu=powerpc}, @option{-mcpu=powerpc64}, and +@option{-mcpu=powerpc64le} specify pure 32-bit PowerPC (either +endian), 64-bit big endian PowerPC and 64-bit little endian PowerPC +architecture machine types, with an appropriate, generic processor +model assumed for scheduling purposes. The other options specify a specific processor. Code generated under those options runs best on that processor, and may not run at all on @@ -18615,17 +18616,17 @@ In order to be efficient the extra code makes the assumption that the stack star at an address aligned to the value given by @var{stack-size}. The @var{stack-guard} option can only be used in conjunction with @var{stack-size}. -@item -mhotpatch[=@var{halfwords}] -@itemx -mno-hotpatch +@item -mhotpatch=@var{pre-halfwords},@var{post-halfwords} @opindex mhotpatch If the hotpatch option is enabled, a ``hot-patching'' function prologue is generated for all functions in the compilation unit. The funtion label is prepended with the given number of two-byte -Nop instructions (@var{halfwords}, maximum 1000000) or 12 Nop -instructions if no argument is present. Functions with a -hot-patching prologue are never inlined automatically, and a -hot-patching prologue is never generated for functions functions -that are explicitly inline. +NOP instructions (@var{pre-halfwords}, maximum 1000000). After +the label, 2 * @var{post-halfwords} bytes are appended, using the +largest NOP like instructions the architecture allows (maximum +1000000). + +If both arguments are zero, hotpatching is disabled. This option can be overridden for individual functions with the @code{hotpatch} attribute. diff --git a/gcc/dse.c b/gcc/dse.c index e853b411848..c24ee00bd4d 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -1594,6 +1594,10 @@ record_store (rtx body, bb_info_t bb_info) = rtx_group_vec[group_id]; mem_addr = group->canon_base_addr; } + /* get_addr can only handle VALUE but cannot handle expr like: + VALUE + OFFSET, so call get_addr to get original addr for + mem_addr before plus_constant. */ + mem_addr = get_addr (mem_addr); if (offset) mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset); } @@ -2211,6 +2215,10 @@ check_mem_read_rtx (rtx *loc, void *data) = rtx_group_vec[group_id]; mem_addr = group->canon_base_addr; } + /* get_addr can only handle VALUE but cannot handle expr like: + VALUE + OFFSET, so call get_addr to get original addr for + mem_addr before plus_constant. */ + mem_addr = get_addr (mem_addr); if (offset) mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset); } diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index c68453e984b..c04f8136c85 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -18812,6 +18812,9 @@ gen_producer_string (void) case OPT__sysroot_: case OPT_nostdinc: case OPT_nostdinc__: + case OPT_fpreprocessed: + case OPT_fltrans_output_list_: + case OPT_fresolution_: /* Ignore these. */ continue; default: @@ -23316,8 +23319,13 @@ dwarf2out_finish (const char *filename) gen_remaining_tmpl_value_param_die_attribute (); /* Add the name for the main input file now. We delayed this from - dwarf2out_init to avoid complications with PCH. */ - add_name_attribute (comp_unit_die (), remap_debug_filename (filename)); + dwarf2out_init to avoid complications with PCH. + For LTO produced units use a fixed artificial name to avoid + leaking tempfile names into the dwarf. */ + if (!in_lto_p) + add_name_attribute (comp_unit_die (), remap_debug_filename (filename)); + else + add_name_attribute (comp_unit_die (), "<artificial>"); if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir) add_comp_dir_attribute (comp_unit_die ()); else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL) diff --git a/gcc/expr.c b/gcc/expr.c index 8ec37336989..777a191773e 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -6430,11 +6430,12 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, && mode != TYPE_MODE (TREE_TYPE (exp))) temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1); - /* If the modes of TEMP and TARGET are both BLKmode, both - must be in memory and BITPOS must be aligned on a byte - boundary. If so, we simply do a block copy. Likewise - for a BLKmode-like TARGET. */ - if (GET_MODE (temp) == BLKmode + /* If TEMP is not a PARALLEL (see below) and its mode and that of TARGET + are both BLKmode, both must be in memory and BITPOS must be aligned + on a byte boundary. If so, we simply do a block copy. Likewise for + a BLKmode-like TARGET. */ + if (GET_CODE (temp) != PARALLEL + && GET_MODE (temp) == BLKmode && (GET_MODE (target) == BLKmode || (MEM_P (target) && GET_MODE_CLASS (GET_MODE (target)) == MODE_INT diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 2feaa4eba46..5249738e4af 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10605,8 +10605,8 @@ fold_binary_loc (location_t loc, /* Don't introduce overflows through reassociation. */ if (!any_overflows - && ((lit0 && TREE_OVERFLOW (lit0)) - || (minus_lit0 && TREE_OVERFLOW (minus_lit0)))) + && ((lit0 && TREE_OVERFLOW_P (lit0)) + || (minus_lit0 && TREE_OVERFLOW_P (minus_lit0)))) return NULL_TREE; if (minus_lit0) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 81c4c1d860e..930f14b730c 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,46 @@ +2015-04-14 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/56674 + PR fortran/58813 + PR fortran/59016 + PR fortran/59024 + * symbol.c (save_symbol_data, gfc_save_symbol_data): Rename the + former to the latter and make it non-static. Update callers. + * gfortran.h (gfc_save_symbol_data): New prototype. + * decl.c (gfc_match_decl_type_spec): Call 'gfc_save_symbol_data' + before modifying symbols 'sym' and 'dt_sym'. + +2015-03-21 Mikael Morin <mikael@gcc.gnu.org> + + Backport from trunk: + 2015-03-14 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/61138 + * trans-expr.c (gfc_trans_pointer_assignment): Clear DESCRIPTOR_ONLY + field before reusing LSE. + +2015-03-15 Paul Thomas <pault@gcc.gnu.org> + + Backport from mainline + PR fortran/65024 + * trans-expr.c (gfc_conv_component_ref): If the component + backend declaration is missing and the derived type symbol is + available in the reference, call gfc_build_derived_type. + +2015-03-12 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/60898 + * resolve.c (resolve_symbol): Check that the symbol found by + name lookup really is the current symbol being resolved. + +2015-02-13 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/63744 + * module.c (check_for_ambiguous): Change argument type + from gfc_symbol to gfc_symtree. Check local (symtree) name + instead of original (symbol) name. + (read_module): Update caller. + 2015-02-01 Jakub Jelinek <jakub@redhat.com> Backported from mainline diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 9292418adca..e73e32d20cf 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -2852,6 +2852,7 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) return MATCH_ERROR; } + gfc_save_symbol_data (sym); gfc_set_sym_referenced (sym); if (!sym->attr.generic && gfc_add_generic (&sym->attr, sym->name, NULL) == FAILURE) @@ -2876,6 +2877,8 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) sym->generic = intr; sym->attr.if_source = IFSRC_DECL; } + else + gfc_save_symbol_data (dt_sym); gfc_set_sym_referenced (dt_sym); diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index bd1aeb9ffab..2428b519b20 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2638,6 +2638,7 @@ gfc_try verify_bind_c_derived_type (gfc_symbol *); gfc_try verify_com_block_vars_c_interop (gfc_common_head *); void generate_isocbinding_symbol (const char *, iso_c_binding_symbol, const char *); gfc_symbol *get_iso_c_sym (gfc_symbol *, char *, const char *, int); +void gfc_save_symbol_data (gfc_symbol *); int gfc_get_sym_tree (const char *, gfc_namespace *, gfc_symtree **, bool); int gfc_get_ha_symbol (const char *, gfc_symbol **); int gfc_get_ha_sym_tree (const char *, gfc_symtree **); diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index c267ee7d610..4fd0d883c84 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -4401,19 +4401,21 @@ read_cleanup (pointer_info *p) /* It is not quite enough to check for ambiguity in the symbols by the loaded symbol and the new symbol not being identical. */ static bool -check_for_ambiguous (gfc_symbol *st_sym, pointer_info *info) +check_for_ambiguous (gfc_symtree *st, pointer_info *info) { gfc_symbol *rsym; module_locus locus; symbol_attribute attr; + gfc_symbol *st_sym; - if (gfc_current_ns->proc_name && st_sym->name == gfc_current_ns->proc_name->name) + if (gfc_current_ns->proc_name && st->name == gfc_current_ns->proc_name->name) { gfc_error ("'%s' of module '%s', imported at %C, is also the name of the " - "current program unit", st_sym->name, module_name); + "current program unit", st->name, module_name); return true; } + st_sym = st->n.sym; rsym = info->u.rsym.sym; if (st_sym == rsym) return false; @@ -4648,7 +4650,7 @@ read_module (void) if (st != NULL) { /* Check for ambiguous symbols. */ - if (check_for_ambiguous (st->n.sym, info)) + if (check_for_ambiguous (st, info)) st->ambiguous = 1; else info->u.rsym.symtree = st; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index bfb17cdf43e..2ba1cb29a0b 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -13284,10 +13284,13 @@ resolve_symbol (gfc_symbol *sym) { this_symtree = gfc_find_symtree (gfc_current_ns->sym_root, sym->name); - gfc_release_symbol (sym); - symtree->n.sym->refs++; - this_symtree->n.sym = symtree->n.sym; - return; + if (this_symtree->n.sym == sym) + { + symtree->n.sym->refs++; + gfc_release_symbol (sym); + this_symtree->n.sym = symtree->n.sym; + return; + } } } diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 1b3702f821f..785f58200c2 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -2717,8 +2717,8 @@ single_undo_checkpoint_p (void) /* Save symbol with the information necessary to back it out. */ -static void -save_symbol_data (gfc_symbol *sym) +void +gfc_save_symbol_data (gfc_symbol *sym) { gfc_symbol *s; unsigned i; @@ -2813,7 +2813,7 @@ gfc_get_sym_tree (const char *name, gfc_namespace *ns, gfc_symtree **result, p->mark = 1; /* Copy in case this symbol is changed. */ - save_symbol_data (p); + gfc_save_symbol_data (p); } *result = st; @@ -2852,7 +2852,7 @@ gfc_get_ha_sym_tree (const char *name, gfc_symtree **result) if (st != NULL) { - save_symbol_data (st->n.sym); + gfc_save_symbol_data (st->n.sym); *result = st; return i; } diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 850ed834a58..456b2ceadff 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -1553,10 +1553,12 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref) c = ref->u.c.component; - gcc_assert (c->backend_decl); + if (c->backend_decl == NULL_TREE + && ref->u.c.sym != NULL) + gfc_get_derived_type (ref->u.c.sym); field = c->backend_decl; - gcc_assert (TREE_CODE (field) == FIELD_DECL); + gcc_assert (field && TREE_CODE (field) == FIELD_DECL); decl = se->expr; /* Components can correspond to fields of different containing @@ -6545,6 +6547,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) else if (expr2->expr_type == EXPR_VARIABLE) { /* Assign directly to the LHS's descriptor. */ + lse.descriptor_only = 0; lse.direct_byref = 1; gfc_conv_expr_descriptor (&lse, expr2); strlen_rhs = lse.string_length; @@ -6569,7 +6572,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) /* Assign to a temporary descriptor and then copy that temporary to the pointer. */ tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp"); - + lse.descriptor_only = 0; lse.expr = tmp; lse.direct_byref = 1; gfc_conv_expr_descriptor (&lse, expr2); diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 53439333c90..1a27df2e14c 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -831,9 +831,19 @@ evaluate_conditions_for_known_args (struct cgraph_node *node, } if (c->code == IS_NOT_CONSTANT || c->code == CHANGED) continue; - res = fold_binary_to_constant (c->code, boolean_type_node, val, c->val); - if (res && integer_zerop (res)) - continue; + + if (operand_equal_p (TYPE_SIZE (TREE_TYPE (c->val)), + TYPE_SIZE (TREE_TYPE (val)), 0)) + { + val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val); + + res = val + ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val) + : NULL; + + if (res && integer_zerop (res)) + continue; + } clause |= 1 << (i + predicate_first_dynamic_condition); } return clause; diff --git a/gcc/ira.c b/gcc/ira.c index 87e72f067c8..385441a4302 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -2944,11 +2944,8 @@ update_equiv_regs (void) prevent access beyond allocated memory for paradoxical memory subreg. */ FOR_EACH_BB (bb) FOR_BB_INSNS (bb, insn) - { - if (! INSN_P (insn)) - continue; - for_each_rtx (&insn, set_paradoxical_subreg, (void *)pdx_subregs); - } + if (NONDEBUG_INSN_P (insn)) + for_each_rtx (&insn, set_paradoxical_subreg, (void *) pdx_subregs); /* Scan the insns and find which registers have equivalences. Do this in a separate scan of the insns because (due to -fcse-follow-jumps) diff --git a/gcc/lra.c b/gcc/lra.c index 17962eabe02..797e388650a 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -446,13 +446,13 @@ init_insn_regs (void) = create_alloc_pool ("insn regs", sizeof (struct lra_insn_reg), 100); } -/* Create LRA insn related info about referenced REGNO with TYPE - (in/out/inout), biggest reference mode MODE, flag that it is +/* Create LRA insn related info about a reference to REGNO in INSN with + TYPE (in/out/inout), biggest reference mode MODE, flag that it is reference through subreg (SUBREG_P), flag that is early clobbered in the insn (EARLY_CLOBBER), and reference to the next insn reg info (NEXT). */ static struct lra_insn_reg * -new_insn_reg (int regno, enum op_type type, enum machine_mode mode, +new_insn_reg (rtx insn, int regno, enum op_type type, enum machine_mode mode, bool subreg_p, bool early_clobber, struct lra_insn_reg *next) { struct lra_insn_reg *ir; @@ -460,7 +460,8 @@ new_insn_reg (int regno, enum op_type type, enum machine_mode mode, ir = (struct lra_insn_reg *) pool_alloc (insn_reg_pool); ir->type = type; ir->biggest_mode = mode; - if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (lra_reg_info[regno].biggest_mode)) + if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (lra_reg_info[regno].biggest_mode) + && NONDEBUG_INSN_P (insn)) lra_reg_info[regno].biggest_mode = mode; ir->subreg_p = subreg_p; ir->early_clobber = early_clobber; @@ -942,7 +943,7 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data, && ! (FIRST_STACK_REG <= regno && regno <= LAST_STACK_REG)); #endif - list = new_insn_reg (regno, type, mode, subreg_p, + list = new_insn_reg (data->insn, regno, type, mode, subreg_p, early_clobber, list); } } @@ -1540,7 +1541,7 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid, expand_reg_info (); if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, uid)) { - data->regs = new_insn_reg (regno, type, mode, subreg_p, + data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p, early_clobber, data->regs); return; } @@ -1552,8 +1553,9 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid, if (curr->subreg_p != subreg_p || curr->biggest_mode != mode) /* The info can not be integrated into the found structure. */ - data->regs = new_insn_reg (regno, type, mode, subreg_p, - early_clobber, data->regs); + data->regs = new_insn_reg (data->insn, regno, type, mode, + subreg_p, early_clobber, + data->regs); else { if (curr->type != type) diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index b205092f597..c898c23d6f6 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -129,6 +129,9 @@ tree_is_indexable (tree t) else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t) && !TREE_STATIC (t)) return false; + /* IMPORTED_DECL is put into BLOCK and thus it never can be shared. */ + else if (TREE_CODE (t) == IMPORTED_DECL) + return false; /* Variably modified types need to be streamed alongside function bodies because they can refer to local entities. Together with them we have to localize their members as well. diff --git a/gcc/omp-low.c b/gcc/omp-low.c index fc7c9910168..694d24f11ae 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1369,7 +1369,8 @@ fixup_child_record_type (omp_context *ctx) layout_type (type); } - TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type); + TREE_TYPE (ctx->receiver_decl) + = build_qualified_type (build_reference_type (type), TYPE_QUAL_RESTRICT); } /* Instantiate decls as necessary in CTX to satisfy the data sharing diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a3d4b249ddd..ffa7a529aa3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,9 +1,474 @@ +2015-04-30 Marek Polacek <polacek@redhat.com> + + * g++.dg/ipa/pr63551.C: New test. + + Backported from mainline + 2014-12-15 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/63551 + * gcc.dg/ipa/pr63551.c (fn2): Use 4294967286U instead of + 4294967286 to avoid warnings. + + 2014-12-01 Martin Jambor <mjambor@suse.cz> + + PR ipa/63551 + * gcc.dg/ipa/pr63551.c: New test. + * gcc.dg/ipa/pr64041.c: Likewise. + +2015-04-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport from mainline r222362 + 2015-04-23 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + * gcc.target/powerpc/crypto-builtin-2.c: New. + +2015-04-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport from mainline r222351 + 2015-04-22 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + * gcc.target/powerpc/swaps-p8-18.c: New test. + +2015-04-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport from mainline r222349 + 2015-04-22 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + PR target/65456 + * gcc.dg/vect/bb-slp-24.c: Exclude test for POWER8. + * gcc.dg/vect/bb-slp-25.c: Likewise. + * gcc.dg/vect/bb-slp-29.c: Likewise. + * gcc.dg/vect/bb-slp-9.c: Replace vect_no_align with + vect_no_align && { ! vect_hw_misalign }. + * gcc.dg/vect/costmodel/ppc/costmodel-slp-33.c: Exclude test for + vect_hw_misalign. + * gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c: Likewise. + * gcc.dg/vect/costmodel/ppc/costmodel-vect-76b.c: Adjust tests to + account for POWER8, where peeling for alignment is not needed. + * gcc.dg/vect/costmodel/ppc/costmodel-vect-outer-fir.c: Replace + vect_no_align with vect_no_align && { ! vect_hw_misalign }. + * gcc.dg.vect.if-cvt-stores-vect-ifcvt-18.c: Likewise. + * gcc.dg/vect/no-scevccp-outer-6-global.c: Likewise. + * gcc.dg/vect/no-scevccp-outer-6.c: Likewise. + * gcc.dg/vect/no-vfa-vect-43.c: Likewise. + * gcc.dg/vect/no-vfa-vect-57.c: Likewise. + * gcc.dg/vect/no-vfa-vect-61.c: Likewise. + * gcc.dg/vect/no-vfa-vect-depend-1.c: Likewise. + * gcc.dg/vect/pr16105.c: Likewise. + * gcc.dg/vect/pr20122.c: Likewise. + * gcc.dg/vect/pr33804.c: Likewise. + * gcc.dg/vect/pr33953.c: Likewise. + * gcc.dg/vect/slp-25.c: Likewise. + * gcc.dg/vect/vect-105-bit-array.c: Likewise. + * gcc.dg/vect/vect-105.c: Likewise. + * gcc.dg/vect/vect-27.c: Likewise. + * gcc.dg/vect/vect-29.c: Likewise. + * gcc.dg/vect/vect-33.c: Exclude unaligned access test for + POWER8. + * gcc.dg/vect/vect-42.c: Replace vect_no_align with vect_no_align + && { ! vect_hw_misalign }. + * gcc.dg/vect/vect-44.c: Likewise. + * gcc.dg/vect/vect-48.c: Likewise. + * gcc.dg/vect/vect-50.c: Likewise. + * gcc.dg/vect/vect-52.c: Likewise. + * gcc.dg/vect/vect-56.c: Likewise. + * gcc.dg/vect/vect-60.c: Likewise. + * gcc.dg/vect/vect-72.c: Likewise. + * gcc.dg/vect/vect-75-big-array.c: Likewise. + * gcc.dg/vect/vect-75.c: Likewise. + * gcc.dg/vect/vect-77-alignchecks.c: Likewise. + * gcc.dg/vect/vect-77-global.c: Likewise. + * gcc.dg/vect/vect-78-alignchecks.c: Likewise. + * gcc.dg/vect/vect-78-global.c: Likewise. + * gcc.dg/vect/vect-93.c: Likewise. + * gcc.dg/vect/vect-95.c: Likewise. + * gcc.dg/vect/vect-96.c: Likewise. + * gcc.dg/vect/vect-cond-1.c: Likewise. + * gcc.dg/vect/vect-cond-3.c: Likewise. + * gcc.dg/vect/vect-cond-4.c: Likewise. + * gcc.dg/vect/vect-cselim-1.c: Likewise. + * gcc.dg/vect/vect-multitypes-1.c: Likewise. + * gcc.dg/vect/vect-multitypes-3.c: Likewise. + * gcc.dg/vect/vect-multitypes-4.c: Likewise. + * gcc.dg/vect/vect-multitypes-6.c: Likewise. + * gcc.dg/vect/vect-nest-cycle-1.c: Likewise. + * gcc.dg/vect/vect-nest-cycle-2.c: Likewise. + * gcc.dg/vect/vect-outer-3a-big-array.c: Likewise. + * gcc.dg/vect/vect-outer-3a.c: Likewise. + * gcc.dg/vect/vect-outer-5.c: Likewise. + * gcc.dg/vect/vect-outer-fir-big-array.c: Likewise. + * gcc.dg/vect/vect-outer-fir-lb-big-array.c: Likewise. + * gcc.dg/vect/vect-outer-fir-lb.c: Likewise. + * gcc.dg/vect/vect-outer-fir.c: Likewise. + * gcc.dg/vect/vect-peel-3.c: Likewise. + * gcc.dg/vect/vect-peel-4.c: Likewise. + * gcc.dg/vect/vect-pre-interact.c: Likewise. + * gcc.target/powerpc/pr65456.c: New test. + * gcc.target/powerpc/vsx-vectorize-2.c: Exclude test for POWER8. + * gcc.target/powerpc/vsx-vectorize-4.c: Likewise. + * gcc.target/powerpc/vsx-vectorize-6.c: Likewise. + * gcc.target/powerpc/vsx-vectorize-7.c: Likewise. + * gfortran.dg/vect/vect-2.f90: Replace vect_no_align with + vect_no_align && { ! vect_hw_misalign }. + * gfortran.dg/vect/vect-3.f90: Likewise. + * gfortran.dg/vect/vect-4.f90: Likewise. + * gfortran.dg/vect/vect-5.f90: Likewise. + * lib/target-supports.exp (check_effective_target_vect_no_align): + Return 1 for POWER8. + (check_effective_target_vect_hw_misalign): Return 1 for POWER8. + + Backport from mainline r222372 + 2015-04-23 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + * gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c: Replace + vect_no_align with vect_no_align && { ! vect_hw_misalign }. + +2015-04-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport from mainline r222205 + 2015-04-17 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + PR target/65787 + * gcc.target/powerpc/pr65787.c: New. + +2015-04-14 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/56674 + PR fortran/58813 + PR fortran/59016 + PR fortran/59024 + * gfortran.dg/used_types_27.f90: New. + +2015-03-31 Dominik Vogt <vogt@linux.vnet.ibm.com> + + * gcc.target/s390/hotpatch-25.c: New test. + * gcc.target/s390/hotpatch-1.c: Update test. + * gcc.target/s390/hotpatch-10.c: Update test. + * gcc.target/s390/hotpatch-11.c: Update test. + * gcc.target/s390/hotpatch-12.c: Update test. + * gcc.target/s390/hotpatch-13.c: Update test. + * gcc.target/s390/hotpatch-14.c: Update test. + * gcc.target/s390/hotpatch-15.c: Update test. + * gcc.target/s390/hotpatch-16.c: Update test. + * gcc.target/s390/hotpatch-17.c: Update test. + * gcc.target/s390/hotpatch-18.c: Update test. + * gcc.target/s390/hotpatch-19.c: Update test. + * gcc.target/s390/hotpatch-2.c: Update test. + * gcc.target/s390/hotpatch-21.c: Update test. + * gcc.target/s390/hotpatch-22.c: Update test. + * gcc.target/s390/hotpatch-23.c: Update test. + * gcc.target/s390/hotpatch-24.c: Update test. + * gcc.target/s390/hotpatch-3.c: Update test. + * gcc.target/s390/hotpatch-4.c: Update test. + * gcc.target/s390/hotpatch-5.c: Update test. + * gcc.target/s390/hotpatch-6.c: Update test. + * gcc.target/s390/hotpatch-7.c: Update test. + * gcc.target/s390/hotpatch-8.c: Update test. + * gcc.target/s390/hotpatch-9.c: Update test. + * gcc.target/s390/hotpatch-compile-16.c: Update test. + +2015-03-31 Dominik Vogt <vogt@linux.vnet.ibm.com> + + * gcc.target/s390/hotpatch-compile-16.c: Remove include of stdio.h. + +2015-03-26 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport r214254 and related tests from mainline + * gcc.target/powerpc/swaps-p8-1.c: New test. + * gcc.target/powerpc/swaps-p8-3.c: New test. + * gcc.target/powerpc/swaps-p8-4.c: New test. + * gcc.target/powerpc/swaps-p8-5.c: New test. + * gcc.target/powerpc/swaps-p8-6.c: New test. + * gcc.target/powerpc/swaps-p8-7.c: New test. + * gcc.target/powerpc/swaps-p8-8.c: New test. + * gcc.target/powerpc/swaps-p8-9.c: New test. + * gcc.target/powerpc/swaps-p8-10.c: New test. + * gcc.target/powerpc/swaps-p8-11.c: New test. + * gcc.target/powerpc/swaps-p8-12.c: New test. + * gcc.target/powerpc/swaps-p8-13.c: New test. + * gcc.target/powerpc/swaps-p8-15.c: New test. + * gcc.target/powerpc/swaps-p8-17.c: New test. + +2015-03-26 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + * gcc.dg/vmx/extract-vsx.c: Add more cases. + +2015-03-21 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/61138 + * gfortran.dg/pointer_remapping_9.f90: New. + +2015-03-16 Eric Botcazou <ebotcazou@adacore.com> + + * testsuite/g++.dg/pr65049.C: New test. + +2015-03-16 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/loop_optimization18.ad[sb]: New test. + * gnat.dg/loop_optimization18_pkg.ads: New helper. + +2015-03-15 Paul Thomas <pault@gcc.gnu.org> + + Backport from mainline + PR fortran/65024 + * gfortran.dg/unlimited_polymorphic_23.f90: New test + +2015-03-12 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/60898 + * gfortran.dg/entry_20.f90: New. + +2015-03-12 Dominik Vogt <vogt@linux.vnet.ibm.com> + + * gcc.target/s390/hotpatch-21.c: New test for hotpatch alignment. + * gcc.target/s390/hotpatch-22.c: Likewise. + * gcc.target/s390/hotpatch-23.c: Likewise. + * gcc.target/s390/hotpatch-24.c: Likewise. + * gcc.target/s390/hotpatch-2.c: Also check hotpatch alignment. + * gcc.target/s390/hotpatch-1.c: Update expected output. + * gcc.target/s390/hotpatch-2.c: Likewise. + * gcc.target/s390/hotpatch-3.c: Likewise. + * gcc.target/s390/hotpatch-4.c: Likewise. + * gcc.target/s390/hotpatch-5.c: Likewise. + * gcc.target/s390/hotpatch-6.c: Likewise. + * gcc.target/s390/hotpatch-7.c: Likewise. + * gcc.target/s390/hotpatch-8.c: Likewise. + * gcc.target/s390/hotpatch-9.c: Likewise. + * gcc.target/s390/hotpatch-10.c: Likewise. + * gcc.target/s390/hotpatch-11.c: Likewise. + * gcc.target/s390/hotpatch-12.c: Likewise. + * gcc.target/s390/hotpatch-13.c: Likewise. + * gcc.target/s390/hotpatch-14.c: Likewise. + * gcc.target/s390/hotpatch-15.c: Likewise. + * gcc.target/s390/hotpatch-16.c: Likewise. + * gcc.target/s390/hotpatch-17.c: Likewise. + * gcc.target/s390/hotpatch-18.c: Likewise. + * gcc.target/s390/hotpatch-19.c: Likewise. + +2015-03-12 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * gcc.target/s390/hotpatch-8.c: Remove -m31 and guard with ! lp64. + * gcc.target/s390/hotpatch-9.c: Likewise. + +2015-03-10 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/53988 + * gcc.target/sh/pr53988.c: Mark tests as xfail. + +2015-03-04 Thomas Preud'homme <thomas.preudhomme@arm.com> + + Backport from mainline + 2014-11-27 Thomas Preud'homme <thomas.preudhomme@arm.com> + + PR target/59593 + * gcc.target/arm/constant-pool.c: New test. + +2015-03-04 Thomas Preud'homme <thomas.preudhomme@arm.com> + + PR target/64453 + * gcc.target/arm/pr64453.c: New. + +2015-02-27 Richard Biener <rguenther@suse.de> + + PR lto/65193 + * g++.dg/lto/pr65193_0.C: New testcase. + +2015-02-26 Peter Bergner <bergner@vnet.ibm.com> + + Backport from mainline + 2015-02-25 Peter Bergner <bergner@vnet.ibm.com> + + * gcc.target/powerpc/htm-builtin-1.c (dg-do) Change to assemble. + (dg-options): Add -save-temps. + (dg-final): Add cleanup-saved-temps. + + 2015-02-25 Adhemerval Zanella <azanella@linux.vnet.ibm.com> + + * gcc.target/powerpc/htm-builtin-1.c: Fix tcheck expect value. + +2015-02-26 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2014-11-27 Richard Biener <rguenther@suse.de> + + PR tree-optimization/61634 + * gcc.dg/vect/pr61634.c: New testcase. + +2015-02-25 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2015-02-16 Richard Biener <rguenther@suse.de> + + PR tree-optimization/63593 + * gcc.dg/pr63593.c: New testcase. + + 2015-02-18 Richard Biener <rguenther@suse.de> + + PR tree-optimization/65063 + * gcc.dg/pr65063.c: New testcase. + +2015-02-24 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2014-12-09 Richard Biener <rguenther@suse.de> + + PR middle-end/64199 + * gcc.dg/torture/pr64199.c: New testcase. + + 2015-01-14 Richard Biener <rguenther@suse.de> + + PR tree-optimization/64493 + PR tree-optimization/64495 + * gcc.dg/vect/pr64493.c: New testcase. + * gcc.dg/vect/pr64495.c: Likewise. + +2015-02-24 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2015-01-27 Richard Biener <rguenther@suse.de> + + PR tree-optimization/56273 + PR tree-optimization/59124 + PR tree-optimization/64277 + * g++.dg/warn/Warray-bounds-6.C: New testcase. + * gcc.dg/Warray-bounds-12.c: Likewise. + * gcc.dg/Warray-bounds-13.c: Likewise. + +2015-02-24 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + Backport from mainline + 2015-02-23 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * gcc.target/s390/hotpatch-1.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-10.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-11.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-12.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-13.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-14.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-15.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-16.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-17.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-18.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-19.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-2.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-20.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-3.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-4.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-5.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-6.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-7.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-8.c: Remove --save-temps option. + * gcc.target/s390/hotpatch-9.c: Remove --save-temps option. + * gcc.target/s390/htm-nofloat-1.c: Cleanup --save-temps files. + +2015-02-24 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + Add testcases missing from hotpatch v2 + * gcc/testsuite/gcc.target/s390/hotpatch-13.c + * gcc/testsuite/gcc.target/s390/hotpatch-15.c + * gcc/testsuite/gcc.target/s390/hotpatch-17.c + * gcc/testsuite/gcc.target/s390/hotpatch-19.c + * gcc/testsuite/gcc.target/s390/hotpatch-compile-11.c + * gcc/testsuite/gcc.target/s390/hotpatch-compile-13.c + * gcc/testsuite/gcc.target/s390/hotpatch-compile-15.c + * gcc/testsuite/gcc.target/s390/hotpatch-20.c + * gcc/testsuite/gcc.target/s390/hotpatch-compile-9.c + * gcc/testsuite/gcc.target/s390/hotpatch-14.c + * gcc/testsuite/gcc.target/s390/hotpatch-16.c + * gcc/testsuite/gcc.target/s390/hotpatch-18.c + * gcc/testsuite/gcc.target/s390/hotpatch-compile-10.c + * gcc/testsuite/gcc.target/s390/hotpatch-compile-12.c + * gcc/testsuite/gcc.target/s390/hotpatch-compile-14.c + * gcc/testsuite/gcc.target/s390/hotpatch-compile-16.c + + Backport from mainline + 2015-02-23 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * gcc.target/s390/hotpatch-8.c: Add -march=g5. + * gcc.target/s390/hotpatch-9.c: Add -march=g5. + * gcc.target/s390/hotpatch-compile-1.c: Fix error message. + * gcc.target/s390/hotpatch-compile-10.c: Likewise. + * gcc.target/s390/hotpatch-compile-11.c: Likewise. + * gcc.target/s390/hotpatch-compile-12.c: Likewise. + * gcc.target/s390/hotpatch-compile-13.c: Likewise. + * gcc.target/s390/hotpatch-compile-14.c: Likewise. + * gcc.target/s390/hotpatch-compile-2.c: Likewise. + * gcc.target/s390/hotpatch-compile-3.c: Likewise. + * gcc.target/s390/hotpatch-compile-4.c: Likewise. + * gcc.target/s390/hotpatch-compile-5.c: Likewise. + * gcc.target/s390/hotpatch-compile-6.c: Likewise. + * gcc.target/s390/hotpatch-compile-7.c: Likewise. + * gcc.target/s390/hotpatch-compile-8.c: Likewise. + * gcc.target/s390/hotpatch-compile-9.c: Likewise. + +2015-02-23 Oleg Endo <olegendo@gcc.gnu.org> + + Backport from mainline + 2015-02-23 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/65163 + * gcc.c-torture/compile/pr65163.c: New. + +2015-02-20 Georg-Johann Lay <avr@gjlay.de> + + Backport from 2015-02-20 trunk r220847. + + PR target/64452 + * gcc.target/avr/torture/pr64452.c: New test. + +2015-02-20 Uros Bizjak <ubizjak@gmail.com> + + Backport from mainline + 2013-09-08 Richard Sandiford <rdsandiford@googlemail.com> + + * g++.dg/debug/ra1.C: New test. + +2015-02-17 Sandra Loosemore <sandra@codesourcery.com> + + Backported from mainline + 2015-02-17 Sandra Loosemore <sandra@codesourcery.com> + + * gcc.target/arm/divzero.c: New test case. + +2015-02-17 Ilya Tocar <ilya.tocar@intel.com> + + Backport from mainline + 2015-01-14 Ilya Tocar <ilya.tocar@intel.com> + + PR target/64387 + * gcc.target/i386/pr64387.c: New test. + +2015-02-13 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/63744 + gfortran.dg/use_rename_8.f90: New. + +2015-02-12 Jakub Jelinek <jakub@redhat.com> + + Backported from mainline + 2015-02-09 Jakub Jelinek <jakub@redhat.com> + + PR target/64979 + * gcc.dg/tree-ssa/stdarg-7.c: New test. + * gcc.c-torture/execute/pr64979.c: New test. + +2015-02-11 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2014-07-24 Marek Polacek <polacek@redhat.com> + + PR c/57653 + * c-c++-common/pr57653.c: New test. + * c-c++-common/pr57653.h: New file. + * c-c++-common/pr57653-2.c: New test. + * c-c++-common/pr57653-2.h: New file. + 2015-02-04 Uros Bizjak <ubizjak@gmail.com> Backport from mainline 2015-01-31 Uros Bizjak <ubizjak@gmail.com> - PR target/64882 + PR target/64882 * gcc.dg/torture/pr64882.c: New test. 2015-02-01 Jakub Jelinek <jakub@redhat.com> @@ -380,7 +845,7 @@ Backported from mainline 2013-09-17 Cong Hou <congh@google.com> - * gcc.dg/vect/vect-reduc-dot-s16c.c: Add a test case with dot product + * gcc.dg/vect/vect-reduc-dot-s16c.c: Add a test case with dot product on two arrays with short and int types. This should not be recognized as a dot product pattern. diff --git a/gcc/testsuite/c-c++-common/pr57653-2.c b/gcc/testsuite/c-c++-common/pr57653-2.c new file mode 100644 index 00000000000..086f6be5ce1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr57653-2.c @@ -0,0 +1,4 @@ +/* { dg-do preprocess } */ +/* { dg-options "-imacros ${srcdir}/c-c++-common/pr57653-2.h" } */ + +/* Empty. */ diff --git a/gcc/testsuite/c-c++-common/pr57653-2.h b/gcc/testsuite/c-c++-common/pr57653-2.h new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr57653-2.h @@ -0,0 +1 @@ + diff --git a/gcc/testsuite/c-c++-common/pr57653.c b/gcc/testsuite/c-c++-common/pr57653.c new file mode 100644 index 00000000000..620471e2419 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr57653.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-imacros ${srcdir}/c-c++-common/pr57653.h" } */ + +__attribute__((used)) static const char s[] = F; + +/* { dg-final { scan-assembler-not "command-line" } } */ diff --git a/gcc/testsuite/c-c++-common/pr57653.h b/gcc/testsuite/c-c++-common/pr57653.h new file mode 100644 index 00000000000..5a93388e9fd --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr57653.h @@ -0,0 +1 @@ +#define F __FILE__ diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype2.C new file mode 100644 index 00000000000..51bf0ec3352 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype2.C @@ -0,0 +1,25 @@ +// PR c++/65727 +// { dg-do compile { target c++11 } } + +struct type_a { void(*cb)(); }; + +struct type_b +{ + type_b(type_a p); + void dummy(); +}; + +template<class T> +constexpr T function_c(T**t) {return **t;} + +class type_d { + public: + static void dummy(); +}; +class type_e { + public: + static type_b b; + type_d *d[1]; +}; + +type_b type_e::b = {{[](){decltype(function_c(type_e::d))::dummy();}}}; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice3.C index 8ff36478d53..8d32fac0a6c 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice3.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice3.C @@ -3,7 +3,7 @@ class Klass { - unsigned int local; + unsigned int local; // { dg-message "" } public: bool dostuff(); }; @@ -11,7 +11,7 @@ public: bool Klass::dostuff() { auto f = []() -> bool { - if (local & 1) { return true; } // { dg-error "not captured" } + if (local & 1) { return true; } // { dg-error "" } return false; }; } diff --git a/gcc/testsuite/g++.dg/debug/ra1.C b/gcc/testsuite/g++.dg/debug/ra1.C new file mode 100644 index 00000000000..b6f7bfc588d --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/ra1.C @@ -0,0 +1,77 @@ +/* { dg-options "-fcompare-debug" } */ + +enum signop { SIGNED, UNSIGNED }; +enum tree_code { FOO, BAR }; +enum tree_code_class { tcc_type, tcc_other }; +extern enum tree_code_class tree_code_type[]; + +struct tree_base { + enum tree_code code : 16; + unsigned unsigned_flag : 1; +}; + +struct tree_def { + tree_base base; + struct { + int precision; + } type_common; +}; + +typedef tree_def *tree; + +struct storage_ref +{ + storage_ref (const long *, unsigned int, unsigned int); + + const long *val; + unsigned int len; + unsigned int precision; +}; + +inline storage_ref::storage_ref (const long *val_in, + unsigned int len_in, + unsigned int precision_in) + : val (val_in), len (len_in), precision (precision_in) +{ +} + +struct hwi_with_prec +{ + long val; + unsigned int precision; + signop sgn; +}; + +inline storage_ref +decompose (long *scratch, unsigned int precision, + const hwi_with_prec &x) +{ + scratch[0] = x.val; + if (x.sgn == SIGNED || x.val >= 0 || precision <= sizeof (long) * 8) + return storage_ref (scratch, 1, precision); + scratch[1] = 0; + return storage_ref (scratch, 2, precision); +} + +extern void tree_class_check_failed (int) __attribute__ ((__noreturn__)); + +inline tree +tree_class_check (tree t, const enum tree_code_class cls, int x) +{ + if (tree_code_type[t->base.code] != cls) + tree_class_check_failed (x); + return t; +} + +tree wide_int_to_tree (tree, const storage_ref &); + +tree +build_int_cstu (tree type, unsigned long val) +{ + hwi_with_prec x; + x.val = val; + x.precision = tree_class_check (type, tcc_type, 1)->type_common.precision; + x.sgn = (signop) tree_class_check (type, tcc_type, 2)->base.unsigned_flag; + long scratch[2]; + return wide_int_to_tree (type, decompose (scratch, x.precision, x)); +} diff --git a/gcc/testsuite/g++.dg/ipa/pr63551.C b/gcc/testsuite/g++.dg/ipa/pr63551.C new file mode 100644 index 00000000000..03e03397969 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr63551.C @@ -0,0 +1,23 @@ +// { dg-options "-O -Wno-psabi" } +// { dg-do compile } + +struct A { int a; }; +template <typename T, typename V> struct B { V operator[] (T); }; +union U { long double ld; void *v; }; +A a; + +void +bar (U &x) +{ + if (x.v) *reinterpret_cast <A *>(x.v) = a; +} + +struct C { C (A) { c.ld = 0; bar (c); } U c; }; +struct D { A d, e; void foo () { f[0][d] = e; } B <int, B <A, C> > f; }; + +void +baz () +{ + D d; + d.foo (); +} diff --git a/gcc/testsuite/g++.dg/lookup/using55.C b/gcc/testsuite/g++.dg/lookup/using55.C new file mode 100644 index 00000000000..61098b186fb --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/using55.C @@ -0,0 +1,19 @@ +// PR c++/65721 + +template<typename T> +struct A { + typedef T D; +}; + +template<typename X> +class B : public A<X> { + using typename B::D; // { dg-error "not a base" } +public: + D echo(D x) { // { dg-error "D" } + return x; + } +}; + +int main() { + B<int> b; +} diff --git a/gcc/testsuite/g++.dg/lto/pr65193_0.C b/gcc/testsuite/g++.dg/lto/pr65193_0.C new file mode 100644 index 00000000000..d778fcabb7f --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr65193_0.C @@ -0,0 +1,71 @@ +/* { dg-lto-do link } */ +/* { dg-require-effective-target fpic } */ +/* { dg-lto-options {{-fPIC -r -nostdlib -flto -O2 -g}} } */ + +void frexp (int, int *); +namespace std +{ + int ldexp (int, int); + struct A + { + }; + template <class T> T get_min_shift_value (); + template <class> struct min_shift_initializer + { + struct B + { + B () { get_min_shift_value<long double> (); } + } static const b; + static void + m_fn1 () + { + b; + } + }; + template <class T> + const typename min_shift_initializer<T>::B min_shift_initializer<T>::b; + template <class T> + inline T + get_min_shift_value () + { + using std::ldexp; + static T c = ldexp (0, 0); + min_shift_initializer<T>::m_fn1; + } + template <class T, class Policy> + void + float_next_imp (T p1, Policy p2) + { + using std::ldexp; + int d; + float_next (0, p2); + frexp (p1, &d); + } + template <class T, class Policy> + int + float_next (const T &p1, Policy &p2) + { + float_next_imp (p1, p2); + } + template <class T, class Policy> void float_prior_imp (T, Policy) + { + get_min_shift_value<T> (); + } + template <class T, class Policy> int float_prior (T, Policy) + { + float_prior_imp (static_cast<T> (0), 0); + } + template <class T, class U, class Policy> + void + nextafter (T p1, U p2, Policy p3) + { + p2 ? float_next (0, p3) : float_prior (p1, 0); + } + long double e; + int f; + void + nextafter () + { + nextafter (e, f, A ()); + } +} diff --git a/gcc/testsuite/g++.dg/pr65049.C b/gcc/testsuite/g++.dg/pr65049.C new file mode 100644 index 00000000000..7ced500a6f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr65049.C @@ -0,0 +1,19 @@ +// PR middle-end/65409 +// Reported by Ignacy Gawedzki <bugs@qult.net> + +struct Foo +{ + Foo() {} + int a; + int b; + char c; +}; + +Foo copy_foo(Foo); + +struct Bar : Foo +{ + Bar(Foo t) : Foo(copy_foo(t)) {} +}; + +Bar a = Foo(); diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-6.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-6.C new file mode 100644 index 00000000000..f2e5f2f597a --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-6.C @@ -0,0 +1,26 @@ +// { dg-do compile } +// { dg-options "-O3 -Warray-bounds" } + +struct type { + bool a, b; + bool get_b() { return b; } +}; + +type stuff[9u]; + +void bar(); + +void foo() +{ + for(unsigned i = 0u; i < 9u; i++) + { + if(!stuff[i].a) + continue; + + bar(); + + for(unsigned j = i + 1u; j < 9u; j++) + if(stuff[j].a && stuff[j].get_b()) // { dg-bogus "above array bounds" } + return; + } +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr65163.c b/gcc/testsuite/gcc.c-torture/compile/pr65163.c new file mode 100644 index 00000000000..3a6b2880e31 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr65163.c @@ -0,0 +1,22 @@ +/* PR target/65163 */ + +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +union unaligned_32 { uint32_t l; } __attribute__((packed)); +union unaligned_16 { uint16_t l; } __attribute__((packed)); + +int +test_00 (unsigned char* buf, int bits_per_component) +{ + (((union unaligned_32*)(buf))->l) = + __builtin_bswap32 (bits_per_component == 10 ? 1 : 0); + return 0; +} + +int +test_01 (unsigned char* buf, int bits_per_component) +{ + (((union unaligned_16*)(buf))->l) = + __builtin_bswap16 (bits_per_component == 10 ? 1 : 0); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr64979.c b/gcc/testsuite/gcc.c-torture/execute/pr64979.c new file mode 100644 index 00000000000..ccb46087e02 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr64979.c @@ -0,0 +1,36 @@ +/* PR target/64979 */ + +#include <stdarg.h> + +void __attribute__((noinline, noclone)) +bar (int x, va_list *ap) +{ + if (ap) + { + int i; + for (i = 0; i < 10; i++) + if (i != va_arg (*ap, int)) + __builtin_abort (); + if (va_arg (*ap, double) != 0.5) + __builtin_abort (); + } +} + +void __attribute__((noinline, noclone)) +foo (int x, ...) +{ + va_list ap; + int n; + + va_start (ap, x); + n = va_arg (ap, int); + bar (x, (va_list *) ((n == 0) ? ((void *) 0) : &ap)); + va_end (ap); +} + +int +main () +{ + foo (100, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0.5); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-12.c b/gcc/testsuite/gcc.dg/Warray-bounds-12.c new file mode 100644 index 00000000000..ef26c6596bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-12.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -Warray-bounds" } */ +/* { dg-additional-options "-mssse3" { target x86_64-*-* i?86-*-* } } */ + +void foo(short a[], short m) +{ + int i, j; + int f1[10]; + short nc; + + nc = m + 1; + if (nc > 3) + { + for (i = 0; i <= nc; i++) + { + f1[i] = f1[i] + 1; + } + } + + for (i = 0, j = m; i < nc; i++, j--) + { + a[i] = f1[i]; /* { dg-bogus "above array bounds" } */ + a[j] = i; + } + return; +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-13.c b/gcc/testsuite/gcc.dg/Warray-bounds-13.c new file mode 100644 index 00000000000..7b40a83887d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-13.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -Warray-bounds" } */ + +extern char *bar[17]; + +int foo(int argc, char **argv) +{ + int i; + int n = 0; + + for (i = 0; i < argc; i++) + n++; + + for (i = 0; i < argc; i++) + argv[i] = bar[i + n]; /* { dg-bogus "above array bounds" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ipa/pr63551.c b/gcc/testsuite/gcc.dg/ipa/pr63551.c new file mode 100644 index 00000000000..48b020aee40 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr63551.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-options "-Os" } */ + +union U +{ + unsigned int f0; + int f1; +}; + +int a, d; + +void +fn1 (union U p) +{ + if (p.f1 <= 0) + if (a) + d = 0; +} + +void +fn2 () +{ + d = 0; + union U b = { 4294967286U }; + fn1 (b); +} + +int +main () +{ + fn2 (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ipa/pr64041.c b/gcc/testsuite/gcc.dg/ipa/pr64041.c new file mode 100644 index 00000000000..4877b4b68a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr64041.c @@ -0,0 +1,64 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +int printf (const char *, ...); + +int a, b = 1, d; + +union U1 +{ + unsigned int f0; + int f1; +}; + +union U2 +{ + int f2; + int f3; +} c; + +int +fn1 (int p) +{ + int t = p && a || p && a && p; + return t ? t : a; +} + +unsigned +fn2 (union U1 p1, union U2 p2) +{ + if (p1.f1 <= 0) + { + for (; p2.f2;) + c.f2 = 0; + p2.f2 = fn1 (d); + } + return p2.f3; +} + +int g = 0; + +int +foo () +{ + if (b) + { + union U1 f = { 0xFFFFFFFFU }; + + fn2 (f, c); + } + g = 1; + return 0; +} + + +int +main () +{ + foo (); + + if (g == 0) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr63593.c b/gcc/testsuite/gcc.dg/pr63593.c new file mode 100644 index 00000000000..08bc8f976d2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr63593.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-tree-vectorize" } */ + +int in[2 * 4][4]; +int out[4]; + +void +foo (void) +{ + int sum; + int i, j, k; + for (k = 0; k < 4; k++) + { + sum = 1; + for (j = 0; j < 4; j++) + for (i = 0; i < 4; i++) + sum *= in[i + k][j]; + out[k] = sum; + } +} diff --git a/gcc/testsuite/gcc.dg/pr65063.c b/gcc/testsuite/gcc.dg/pr65063.c new file mode 100644 index 00000000000..bcbdbf098d8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr65063.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-tree-loop-ivcanon -fno-tree-vectorize" } */ + +static int in[8][4]; +static int out[4]; +static const int check_result[] = {0, 16, 256, 4096}; + +static inline void foo () +{ + int sum; + int i, j, k; + for (k = 0; k < 4; k++) + { + sum = 1; + for (j = 0; j < 4; j++) + for (i = 0; i < 4; i++) + sum *= in[i + k][j]; + out[k] = sum; + } +} + +int main () +{ + int i, j, k; + for (i = 0; i < 8; i++) + for (j = 0; j < 4; j++) + in[i][j] = (i + 2) / 3; + foo (); + for (k = 0; k < 4; k++) + if (out[k] != check_result[k]) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr64199.c b/gcc/testsuite/gcc.dg/torture/pr64199.c new file mode 100644 index 00000000000..e3f1002f1bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr64199.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffast-math -frounding-math" } */ + +float +foo (void) +{ + return 1.1f + 2.2f + 2.2f; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-7.c b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-7.c new file mode 100644 index 00000000000..9b497c07270 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-7.c @@ -0,0 +1,22 @@ +/* PR target/64979 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-stdarg" } */ + +#include <stdarg.h> + +void bar (int x, va_list *ap); + +void +foo (int x, ...) +{ + va_list ap; + int n; + + va_start (ap, x); + n = va_arg (ap, int); + bar (x, (va_list *) ((n == 0) ? ((void *) 0) : &ap)); + va_end (ap); +} + +/* { dg-final { scan-tree-dump "foo: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" } } */ +/* { dg-final { cleanup-tree-dump "stdarg" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-24.c b/gcc/testsuite/gcc.dg/vect/bb-slp-24.c index cbe1cb3edea..1e91d0826b2 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-24.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-24.c @@ -54,6 +54,8 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */ +/* Exclude POWER8 (only POWER cpu for which vect_element_align is true) + because loops have vectorized before SLP gets a shot. */ +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_element_align && { ! powerpc*-*-* } } } } } */ /* { dg-final { cleanup-tree-dump "slp" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-25.c b/gcc/testsuite/gcc.dg/vect/bb-slp-25.c index 193ab9d4db3..5d98cd318cd 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-25.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-25.c @@ -54,6 +54,8 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */ +/* Exclude POWER8 (only POWER cpu for which vect_element_align is true) + because loops have vectorized before SLP gets a shot. */ +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_element_align && { ! powerpc*-*-* } } } } } */ /* { dg-final { cleanup-tree-dump "slp" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-29.c b/gcc/testsuite/gcc.dg/vect/bb-slp-29.c index e37b96d14d9..65bc5fee6e3 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-29.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-29.c @@ -54,6 +54,8 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_int_mult && vect_element_align } } } } */ +/* Exclude POWER8 (only POWER cpu for which vect_element_align is true) + because loops have vectorized before SLP gets a shot. */ +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { { vect_int_mult && vect_element_align } && { ! powerpc*-*-* } } } } } */ /* { dg-final { cleanup-tree-dump "slp" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c index 5535dee0641..dfe90ad91e2 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c @@ -46,6 +46,6 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "slp" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c index 4e8d71b9673..29630d5547f 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c @@ -41,6 +41,6 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "slp" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-33.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-33.c index 9cae12fdbb3..9bc3ea55c30 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-33.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-33.c @@ -41,5 +41,5 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_hw_misalign } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c index 272b3f0d733..161497faf68 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c @@ -47,5 +47,5 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_hw_misalign } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76b.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76b.c index d716b613946..2d1ee97c398 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76b.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76b.c @@ -43,8 +43,8 @@ int main (void) } /* Peeling to align the store is used. Overhead of peeling is too high. */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target vector_alignment_reachable } } } */ -/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { target { vector_alignment_reachable && {! vect_no_align} } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { vector_alignment_reachable && {! vect_no_align} } } } } */ +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { target { vector_alignment_reachable && {! vect_hw_misalign} } } } } */ /* Versioning to align the store is used. Overhead of versioning is not too high. */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_no_align || {! vector_alignment_reachable} } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-outer-fir.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-outer-fir.c index efab0469bd3..5123950806d 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-outer-fir.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-outer-fir.c @@ -67,5 +67,5 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/if-cvt-stores-vect-ifcvt-18.c b/gcc/testsuite/gcc.dg/vect/if-cvt-stores-vect-ifcvt-18.c index 38906a94af2..cdf687ab420 100644 --- a/gcc/testsuite/gcc.dg/vect/if-cvt-stores-vect-ifcvt-18.c +++ b/gcc/testsuite/gcc.dg/vect/if-cvt-stores-vect-ifcvt-18.c @@ -65,5 +65,5 @@ main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align || { ! vect_strided2 } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || { ! vect_strided2 } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6-global.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6-global.c index 9447524e817..4aa4a5e98c2 100644 --- a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6-global.c +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6-global.c @@ -52,5 +52,5 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6.c index 70cf520d950..187a78c3744 100644 --- a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6.c +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6.c @@ -51,6 +51,6 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { unaligned_stack || vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { unaligned_stack || { vect_no_align && { ! vect_hw_misalign } } } } } } */ /* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c index 16a01d1a320..d09cd41447b 100644 --- a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c @@ -90,5 +90,5 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 2 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 6 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 6 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c index 63d332a39b2..fd4288c9d29 100644 --- a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c @@ -71,5 +71,5 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c index 2df45fdfe85..8b1b6c6d8fb 100644 --- a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c @@ -73,5 +73,5 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-1.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-1.c index 5679ff765c1..2be160426e2 100644 --- a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-1.c +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-1.c @@ -50,7 +50,7 @@ int main (void) return main1 (); } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "dependence distance negative" 1 "vect" } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr16105.c b/gcc/testsuite/gcc.dg/vect/pr16105.c index c59fe05730f..50c16c468f7 100644 --- a/gcc/testsuite/gcc.dg/vect/pr16105.c +++ b/gcc/testsuite/gcc.dg/vect/pr16105.c @@ -18,5 +18,5 @@ void square(const float * __restrict__ a, } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr20122.c b/gcc/testsuite/gcc.dg/vect/pr20122.c index 9d21fc60062..c9c523c5d12 100644 --- a/gcc/testsuite/gcc.dg/vect/pr20122.c +++ b/gcc/testsuite/gcc.dg/vect/pr20122.c @@ -52,5 +52,5 @@ int main (int argc, char **argv) /* The loops in VecBug and VecBug2 require versioning for alignment. The loop in main is aligned. */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr33804.c b/gcc/testsuite/gcc.dg/vect/pr33804.c index a4fb3868397..c7f3b6fa556 100644 --- a/gcc/testsuite/gcc.dg/vect/pr33804.c +++ b/gcc/testsuite/gcc.dg/vect/pr33804.c @@ -11,6 +11,6 @@ void f(unsigned char *s, unsigned char *d, int n) { } } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr33953.c b/gcc/testsuite/gcc.dg/vect/pr33953.c index f501a452e53..3a882692dcb 100644 --- a/gcc/testsuite/gcc.dg/vect/pr33953.c +++ b/gcc/testsuite/gcc.dg/vect/pr33953.c @@ -28,8 +28,8 @@ void blockmove_NtoN_blend_noremap32 (const UINT32 *srcdata, int srcwidth, } } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" {xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr61634.c b/gcc/testsuite/gcc.dg/vect/pr61634.c new file mode 100644 index 00000000000..80b2c3a2546 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr61634.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +int a, b, c, d; +short *e; +void fn1 (int p1[], int p2, int p3[], int p4[], int p5[], int *p6) +{ + int f; + c = *p1; + d = *p5; + (void)p6; + for (; a; a--) + { + f = *e >> 2; + *e++ = f; + b += f * f; + f = *e >> 2; + *e++ = f; + } + p4[0] = p3[0]; + for (;; p2--) + ; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr64493.c b/gcc/testsuite/gcc.dg/vect/pr64493.c new file mode 100644 index 00000000000..a7dee4d66eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr64493.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ + +#include "tree-vect.h" + +int a, b, c, d, e, f, g, h; + +int +main () +{ + check_vect (); + + for (; a; a--) + for (d = 1; d <= 0; d++) + for (; d;) + if (h) + { + if (!g) __builtin_abort (); + if (!0) __builtin_abort (); + } + + for (f = 4; f; f--) + { + for (b = 0; b < 2; b++) + c |= 1; + e |= c; + } + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr64495.c b/gcc/testsuite/gcc.dg/vect/pr64495.c new file mode 100644 index 00000000000..aad87526ee5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr64495.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ + +#include <assert.h> +#include "tree-vect.h" + +int a, b, c, d, e, f, g, i, j; +static int *h = &e; + +int +main () +{ + check_vect (); + + for (; a;) + for (; g; g++) + for (; f; f++) + if (j) + { + assert(b); + assert(0); + } + for (i = 24; i; i--) + { + for (c = 0; c < 6; c++) + d |= 1; + *h |= d; + } + + if (e != 1) + __builtin_abort (); + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-25.c b/gcc/testsuite/gcc.dg/vect/slp-25.c index e5e5e3bdfa6..d69be28da4f 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-25.c +++ b/gcc/testsuite/gcc.dg/vect/slp-25.c @@ -56,5 +56,5 @@ int main (void) /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { vect_no_align || { ! vect_natural_alignment } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || { ! vect_natural_alignment } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-105-big-array.c b/gcc/testsuite/gcc.dg/vect/vect-105-big-array.c index f99a2afd728..0a4746e2edb 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-105-big-array.c +++ b/gcc/testsuite/gcc.dg/vect/vect-105-big-array.c @@ -100,7 +100,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 0 "vect" } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-105.c b/gcc/testsuite/gcc.dg/vect/vect-105.c index bbf42af897f..79d31c168a4 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-105.c +++ b/gcc/testsuite/gcc.dg/vect/vect-105.c @@ -66,7 +66,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 0 "vect" } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-27.c b/gcc/testsuite/gcc.dg/vect/vect-27.c index 4a2da227e3c..36c23fa5cc6 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-27.c +++ b/gcc/testsuite/gcc.dg/vect/vect-27.c @@ -43,8 +43,8 @@ int main (void) } /* The initialization induction loop (with aligned access) is also vectorized. */ -/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-29.c b/gcc/testsuite/gcc.dg/vect/vect-29.c index 0ad28488056..6e62ee969bc 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-29.c +++ b/gcc/testsuite/gcc.dg/vect/vect-29.c @@ -50,7 +50,7 @@ int main (void) /* The initialization induction loop (with aligned access) is also vectorized. */ /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" {target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" {target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-33.c b/gcc/testsuite/gcc.dg/vect/vect-33.c index 43daaa80704..d4126afb9ae 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-33.c +++ b/gcc/testsuite/gcc.dg/vect/vect-33.c @@ -38,7 +38,7 @@ int main (void) /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! vect_hw_misalign } } } } */ /* { dg-final { scan-tree-dump "Alignment of access forced using peeling" "vect" { target vector_alignment_reachable } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-42.c b/gcc/testsuite/gcc.dg/vect/vect-42.c index 31810817b46..6781ece182d 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-42.c +++ b/gcc/testsuite/gcc.dg/vect/vect-42.c @@ -64,7 +64,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { { ! vector_alignment_reachable } && { ! vect_element_align } } } } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail { vect_no_align || { { ! vector_alignment_reachable } || vect_element_align } } } } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" { target vect_element_align } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-44.c b/gcc/testsuite/gcc.dg/vect/vect-44.c index ef1a4635bfa..70f28dba315 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-44.c +++ b/gcc/testsuite/gcc.dg/vect/vect-44.c @@ -65,8 +65,8 @@ int main (void) two loads to be aligned). */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align } } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || {! vector_alignment_reachable} } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {{! vect_no_align} && {! vect_hw_misalign} } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-48.c b/gcc/testsuite/gcc.dg/vect/vect-48.c index d2eed3a6b97..5da97372d77 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-48.c +++ b/gcc/testsuite/gcc.dg/vect/vect-48.c @@ -55,7 +55,7 @@ int main (void) (The store is aligned). */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-50.c b/gcc/testsuite/gcc.dg/vect/vect-50.c index 068c804a168..98ccf9a891f 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-50.c +++ b/gcc/testsuite/gcc.dg/vect/vect-50.c @@ -61,9 +61,9 @@ int main (void) align the store will not force the two loads to be aligned). */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target vect_hw_misalign } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || {! vector_alignment_reachable} } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && { {! vect_no_align } && {! vect_hw_misalign } } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-52.c b/gcc/testsuite/gcc.dg/vect/vect-52.c index 69c097966ed..c7cf6abbf60 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-52.c +++ b/gcc/testsuite/gcc.dg/vect/vect-52.c @@ -56,7 +56,7 @@ int main (void) (The store is aligned). */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-56.c b/gcc/testsuite/gcc.dg/vect/vect-56.c index 5a8130b11e2..ced829e4837 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-56.c +++ b/gcc/testsuite/gcc.dg/vect/vect-56.c @@ -67,7 +67,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target { vect_element_align } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { xfail { vect_element_align } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-60.c b/gcc/testsuite/gcc.dg/vect/vect-60.c index 838a9bca417..8cfb8d9552b 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-60.c +++ b/gcc/testsuite/gcc.dg/vect/vect-60.c @@ -68,7 +68,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target { vect_element_align } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { xfail { vect_element_align } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-72.c b/gcc/testsuite/gcc.dg/vect/vect-72.c index 67a19751952..5d231782874 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-72.c +++ b/gcc/testsuite/gcc.dg/vect/vect-72.c @@ -45,7 +45,7 @@ int main (void) return main1 (); } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-75-big-array.c b/gcc/testsuite/gcc.dg/vect/vect-75-big-array.c index 1c70cc2c518..3524fa9a253 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-75-big-array.c +++ b/gcc/testsuite/gcc.dg/vect/vect-75-big-array.c @@ -52,6 +52,6 @@ int main (void) /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-75.c b/gcc/testsuite/gcc.dg/vect/vect-75.c index 092a3013e07..35336b93953 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-75.c +++ b/gcc/testsuite/gcc.dg/vect/vect-75.c @@ -44,6 +44,6 @@ int main (void) /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-77-alignchecks.c b/gcc/testsuite/gcc.dg/vect/vect-77-alignchecks.c index 4a05874b67e..56a2197d82b 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-77-alignchecks.c +++ b/gcc/testsuite/gcc.dg/vect/vect-77-alignchecks.c @@ -49,8 +49,8 @@ int main (void) both for the load and the store. */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { {! vect_no_align} && { unaligned_stack && vector_alignment_reachable } } } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { { {! unaligned_stack} && vect_no_align } || {unaligned_stack && { {! vector_alignment_reachable} && {! vect_no_align} } } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { { {! unaligned_stack} && { vect_no_align && { ! vect_hw_misalign } } } || {unaligned_stack && { {! vector_alignment_reachable} && {! vect_no_align } } } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target { { unaligned_stack && { vector_alignment_reachable && vect_no_align } } || {unaligned_stack && { {! vector_alignment_reachable} && vect_no_align } } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-77-global.c b/gcc/testsuite/gcc.dg/vect/vect-77-global.c index ac29d7d3c44..6236caf131d 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-77-global.c +++ b/gcc/testsuite/gcc.dg/vect/vect-77-global.c @@ -47,7 +47,7 @@ int main (void) /* Requires versioning for aliasing. */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-78-alignchecks.c b/gcc/testsuite/gcc.dg/vect/vect-78-alignchecks.c index 71c01ae1ce7..d4207074a07 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-78-alignchecks.c +++ b/gcc/testsuite/gcc.dg/vect/vect-78-alignchecks.c @@ -50,8 +50,8 @@ int main (void) both for the load and the store. */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { {! vect_no_align} && { unaligned_stack && vector_alignment_reachable } } } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { { {! unaligned_stack} && vect_no_align } || {unaligned_stack && { {! vector_alignment_reachable} && {! vect_no_align} } } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { { {! unaligned_stack} && { vect_no_align && { ! vect_hw_misalign } } } || {unaligned_stack && { {! vector_alignment_reachable} && { ! vect_no_align } } } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target { { unaligned_stack && { vector_alignment_reachable && vect_no_align } } || {unaligned_stack && { {! vector_alignment_reachable} && vect_no_align } } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-78-global.c b/gcc/testsuite/gcc.dg/vect/vect-78-global.c index ec6520fd8a0..22065bf10df 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-78-global.c +++ b/gcc/testsuite/gcc.dg/vect/vect-78-global.c @@ -47,7 +47,7 @@ int main (void) (The store is aligned). */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-93.c b/gcc/testsuite/gcc.dg/vect/vect-93.c index 65403eb72fc..52ba1ca4e7c 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-93.c +++ b/gcc/testsuite/gcc.dg/vect/vect-93.c @@ -76,10 +76,10 @@ int main (void) /* in main1: */ /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target !powerpc*-*-* !i?86-*-* !x86_64-*-* } } } */ -/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* in main: */ -/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { target vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-95.c b/gcc/testsuite/gcc.dg/vect/vect-95.c index c03d1965df1..be560a6c316 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-95.c +++ b/gcc/testsuite/gcc.dg/vect/vect-95.c @@ -64,6 +64,6 @@ int main (void) /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align} } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 4 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 4 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-96.c b/gcc/testsuite/gcc.dg/vect/vect-96.c index 0060d4eb4bf..7d8c92a5489 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-96.c +++ b/gcc/testsuite/gcc.dg/vect/vect-96.c @@ -46,5 +46,5 @@ int main (void) /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target { {! vect_no_align} && vector_alignment_reachable } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align } || { { ! vector_alignment_reachable} || vect_element_align } } } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { vect_no_align || { {! vector_alignment_reachable} && {! vect_element_align} } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { { vect_no_align && { ! vect_hw_misalign } } || { {! vector_alignment_reachable} && {! vect_element_align} } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-1.c b/gcc/testsuite/gcc.dg/vect/vect-cond-1.c index e42752f97a4..bd2d2fb6247 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-cond-1.c +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-1.c @@ -51,7 +51,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-3.c b/gcc/testsuite/gcc.dg/vect/vect-cond-3.c index 32ebf0fff4f..0f36e848b55 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-cond-3.c +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-3.c @@ -59,7 +59,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-4.c b/gcc/testsuite/gcc.dg/vect/vect-cond-4.c index 3c37c68250d..9a6e117d912 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-cond-4.c +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-4.c @@ -56,7 +56,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-cselim-1.c b/gcc/testsuite/gcc.dg/vect/vect-cselim-1.c index 3c21918efb7..ce2db7d8b5d 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-cselim-1.c +++ b/gcc/testsuite/gcc.dg/vect/vect-cselim-1.c @@ -82,5 +82,5 @@ main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align || { ! vect_strided2 } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || { ! vect_strided2 } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c index 7ab21f1df6e..7fbfa3c7af5 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c @@ -80,8 +80,8 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail { vect_no_align } } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail {{ vect_no_align } || {vect_sizes_32B_16B }}} } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail {{ vect_no_align } || {vect_sizes_32B_16B }}} } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail {{ vect_no_align && { ! vect_hw_misalign } } || {vect_sizes_32B_16B }}} } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail {{ vect_no_align && { ! vect_hw_misalign } } || {vect_sizes_32B_16B }}} } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-3.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-3.c index 93796d0cec3..2fdd4b7c9e5 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-3.c +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-3.c @@ -54,7 +54,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" {xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" {xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c index ed6ac6eda6b..44891af5232 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c @@ -91,7 +91,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { target { vect_element_align} } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 8 "vect" { xfail { vect_no_align || vect_element_align } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-6.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-6.c index 7f72785069a..a337ca4b649 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-6.c +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-6.c @@ -61,7 +61,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { sparc*-*-* && ilp32 } }} } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 6 "vect" { target vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 6 "vect" {xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 6 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 6 "vect" {xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c index 84883ca191e..588751e85cb 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c +++ b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c @@ -43,6 +43,6 @@ int main () return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c index 22b1d98de4b..247d3272e8b 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c +++ b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c @@ -42,6 +42,6 @@ int main () return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-3a-big-array.c b/gcc/testsuite/gcc.dg/vect/vect-outer-3a-big-array.c index c6486db691b..532d9b3d958 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-outer-3a-big-array.c +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-3a-big-array.c @@ -48,7 +48,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "step doesn't divide the vector-size" 2 "vect" { target { ! vect_multiple_sizes } } } } */ /* { dg-final { scan-tree-dump-times "step doesn't divide the vector-size" 3 "vect" { target vect_multiple_sizes } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-3a.c b/gcc/testsuite/gcc.dg/vect/vect-outer-3a.c index 3d6e1076e79..d1382cc1e26 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-outer-3a.c +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-3a.c @@ -48,7 +48,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "step doesn't divide the vector-size" 2 "vect" { target { ! vect_multiple_sizes } } } } */ /* { dg-final { scan-tree-dump-times "step doesn't divide the vector-size" 3 "vect" { target vect_multiple_sizes } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-5.c b/gcc/testsuite/gcc.dg/vect/vect-outer-5.c index 2d37d6d148e..f0cdcaebe85 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-outer-5.c +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-5.c @@ -78,5 +78,5 @@ int main () is known. */ /* { dg-final { scan-tree-dump-times "not vectorized: possible dependence between data-refs" 1 "vect" { xfail *-*-* } } } */ /* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ -/* { dg-final { scan-tree-dump "zero step in outer loop." "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump "zero step in outer loop." "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-fir-big-array.c b/gcc/testsuite/gcc.dg/vect/vect-outer-fir-big-array.c index c69b7d74950..07db614484a 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-outer-fir-big-array.c +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-fir-big-array.c @@ -70,5 +70,5 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb-big-array.c b/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb-big-array.c index 5ac62ac3a2f..505eef58f17 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb-big-array.c +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb-big-array.c @@ -74,5 +74,5 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb.c b/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb.c index 3c1a362c003..c1732d9fbca 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb.c +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb.c @@ -74,5 +74,5 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-fir.c b/gcc/testsuite/gcc.dg/vect/vect-outer-fir.c index af787b96a33..fa10263558f 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-outer-fir.c +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-fir.c @@ -70,5 +70,5 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-3.c b/gcc/testsuite/gcc.dg/vect/vect-peel-3.c index 5aab8053ed6..312947afc45 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-peel-3.c +++ b/gcc/testsuite/gcc.dg/vect/vect-peel-3.c @@ -47,7 +47,7 @@ int main (void) return main1 (); } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { { vect_no_align } || {vect_sizes_32B_16B } } } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align } || {vect_sizes_32B_16B } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || {vect_sizes_32B_16B } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || {vect_sizes_32B_16B } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-4.c b/gcc/testsuite/gcc.dg/vect/vect-peel-4.c index dffb858e2b2..53871c8833f 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-peel-4.c +++ b/gcc/testsuite/gcc.dg/vect/vect-peel-4.c @@ -44,7 +44,7 @@ int main (void) return main1 (); } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c b/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c index 096839f9c2d..8b7a72ba7e6 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c +++ b/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c @@ -12,5 +12,5 @@ void foo (void) res[i] = data[i] + data[i + 1]; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vmx/extract-vsx.c b/gcc/testsuite/gcc.dg/vmx/extract-vsx.c index cd34a2ae3d3..1695094228b 100644 --- a/gcc/testsuite/gcc.dg/vmx/extract-vsx.c +++ b/gcc/testsuite/gcc.dg/vmx/extract-vsx.c @@ -10,7 +10,11 @@ static void test() vector double vd = {0.0, 1.0}; check (vec_extract (vl, 0) == 0, "vec_extract, vl, 0"); + check (vec_extract (vl, 1) == 1, "vec_extract, vl, 1"); + check (vec_extract (vd, 0) == 0.0, "vec_extract, vd, 0"); check (vec_extract (vd, 1) == 1.0, "vec_extract, vd, 1"); check (vl[0] == 0, "[], vl, 0"); - check (vd[1] == 1.0, "[], vd, 0"); + check (vl[1] == 1, "[], vl, 1"); + check (vd[0] == 0.0, "[], vd, 0"); + check (vd[1] == 1.0, "[], vd, 1"); } diff --git a/gcc/testsuite/gcc.target/arm/constant-pool.c b/gcc/testsuite/gcc.target/arm/constant-pool.c new file mode 100644 index 00000000000..8427dfb1a80 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/constant-pool.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +unsigned short v = 0x5678; +int i; +int j = 0; +int *ptr = &j; + +int +func (void) +{ + for (i = 0; i < 1; ++i) + { + *ptr = -1; + v = 0x1234; + } + return v; +} + +int +main (void) +{ + func (); + if (v != 0x1234) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arm/divzero.c b/gcc/testsuite/gcc.target/arm/divzero.c new file mode 100644 index 00000000000..7d398a5683b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/divzero.c @@ -0,0 +1,85 @@ +/* { dg-require-effective-target arm_eabi } */ +/* { dg-options "" } */ +/* { dg-do run } */ + +/* Check that long long divmod functions pass the right argument to + __aeabi_ldiv0 on divide by zero. */ + +#ifdef DEBUGME +#include <stdio.h> +#else +extern void abort (void); +#endif + +/* Override div zero handler and simply return the provided value. */ +long long __aeabi_ldiv0 (long long r) +{ + return r; +} + +long long lldiv (long long a, long long b) +{ + return a / b; +} + +unsigned long long ulldiv (unsigned long long a, unsigned long long b) +{ + return a / b; +} + +void check (long long num, long long expected) +{ + long long res = lldiv (num, 0LL); + if (res != expected) +#ifdef DEBUGME + { + printf ("num=%08X:%08X\n", (unsigned)(num >> 32), (unsigned)num); + printf ("res=%08X:%08X\n", (unsigned)(res >> 32), (unsigned)res); + } +#else + abort (); +#endif +} + +void ucheck (unsigned long long num, unsigned long long expected) +{ + unsigned long long res = ulldiv (num, 0ULL); + if (res != expected) +#ifdef DEBUGME + { + printf ("num=%08X:%08X\n", (unsigned)(num >> 32), (unsigned)num); + printf ("res=%08X:%08X\n", (unsigned)(res >> 32), (unsigned)res); + } +#else + abort (); +#endif +} + +#define POS_BIG 0x7fffffffffffffffLL +#define NEG_BIG 0x8000000000000000LL +#define UNS_BIG 0xffffffffffffffffULL + +int main () +{ + check (0LL, 0LL); + check (1LL, POS_BIG); + check (0x000000007fffffffLL, POS_BIG); + check (0x00000000ffffffffLL, POS_BIG); + check (0x0000000100000000LL, POS_BIG); + check (POS_BIG, POS_BIG); + check (-1LL, NEG_BIG); + check (-0x000000007fffffffLL, NEG_BIG); + check (-0x00000000ffffffffLL, NEG_BIG); + check (-0x0000000100000000LL, NEG_BIG); + check (NEG_BIG, NEG_BIG); + + ucheck (0ULL, 0ULL); + ucheck (1ULL, UNS_BIG); + ucheck (0x000000007fffffffULL, UNS_BIG); + ucheck (0x00000000ffffffffULL, UNS_BIG); + ucheck (0x0000000100000000ULL, UNS_BIG); + ucheck ((unsigned long long)POS_BIG, UNS_BIG); + ucheck (UNS_BIG, UNS_BIG); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/arm/pr64453.c b/gcc/testsuite/gcc.target/arm/pr64453.c new file mode 100644 index 00000000000..17155afc9d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr64453.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-mthumb -Os " } */ +/* { dg-require-effective-target arm_thumb1_ok } */ + +void save_regs () { + __asm volatile ("" ::: "r8"); +} + +/* { dg-final { scan-assembler "\tmov\tr., r8" } } */ diff --git a/gcc/testsuite/gcc.target/avr/torture/pr64452.c b/gcc/testsuite/gcc.target/avr/torture/pr64452.c new file mode 100644 index 00000000000..44cb2e057dd --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr64452.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c99" } */ + +struct A +{ + char str[8]; + void* v; +}; + +int varf (char* fmt, ...); + +void foo (struct A a, struct A b) +{ + varf ("%s%s", b.str, b.str); +} + +long long x64; + +void foo2 (long long j0, + struct A a, struct A b, struct A c, struct A d, + struct A e, struct A f, struct A g, struct A h, struct A i, + long long j1) +{ + varf ("%s%s", i.str, i.str, x64, j1+j0); +} + + +void foo3 (long long j0, + struct A a, struct A b, struct A c, struct A d, + struct A e, struct A f, struct A g, struct A h, struct A i, + long long j1) +{ + varf ("%s%s", &i.str, &b.str, x64, j1+j0); +} diff --git a/gcc/testsuite/gcc.target/i386/pr64387.c b/gcc/testsuite/gcc.target/i386/pr64387.c new file mode 100644 index 00000000000..332a639871c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr64387.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -ffloat-store -mavx2" } */ + +float x[256]; + +double * +foo (void) +{ + double *z = __builtin_malloc (sizeof (double) * 256); + int i; + for (i = 0; i < 256; ++i) + z[i] = x[i] + 1.0f; + foo (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/crypto-builtin-2.c b/gcc/testsuite/gcc.target/powerpc/crypto-builtin-2.c new file mode 100644 index 00000000000..6d5ecdc0c12 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/crypto-builtin-2.c @@ -0,0 +1,36 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-O2 -mcpu=power8 -mno-crypto" } */ + +void use_builtins_d (__vector unsigned long long *p, __vector unsigned long long *q, __vector unsigned long long *r, __vector unsigned long long *s) +{ + p[0] = __builtin_crypto_vcipher (q[0], r[0]); /* { dg-error "Builtin function __builtin_crypto_vcipher is not supported with the current options" } */ + p[1] = __builtin_crypto_vcipherlast (q[1], r[1]); /* { dg-error "Builtin function __builtin_crypto_vcipherlast is not supported with the current options" } */ + p[2] = __builtin_crypto_vncipher (q[2], r[2]); /* { dg-error "Builtin function __builtin_crypto_vncipher is not supported with the current options" } */ + p[3] = __builtin_crypto_vncipherlast (q[3], r[3]); /* { dg-error "Builtin function __builtin_crypto_vncipherlast is not supported with the current options" } */ + p[4] = __builtin_crypto_vpermxor (q[4], r[4], s[4]); + p[5] = __builtin_crypto_vpmsumd (q[5], r[5]); + p[6] = __builtin_crypto_vshasigmad (q[6], 1, 15); /* { dg-error "Builtin function __builtin_crypto_vshasigmad is not supported with the current options" } */ + p[7] = __builtin_crypto_vsbox (q[7]); /* { dg-error "Builtin function __builtin_crypto_vsbox is not supported with the current options" } */ +} + +void use_builtins_w (__vector unsigned int *p, __vector unsigned int *q, __vector unsigned int *r, __vector unsigned int *s) +{ + p[0] = __builtin_crypto_vpermxor (q[0], r[0], s[0]); + p[1] = __builtin_crypto_vpmsumw (q[1], r[1]); + p[2] = __builtin_crypto_vshasigmaw (q[2], 1, 15); /* { dg-error "Builtin function __builtin_crypto_vshasigmaw is not supported with the current options" } */ +} + +void use_builtins_h (__vector unsigned short *p, __vector unsigned short *q, __vector unsigned short *r, __vector unsigned short *s) +{ + p[0] = __builtin_crypto_vpermxor (q[0], r[0], s[0]); + p[1] = __builtin_crypto_vpmsumh (q[1], r[1]); +} + +void use_builtins_b (__vector unsigned char *p, __vector unsigned char *q, __vector unsigned char *r, __vector unsigned char *s) +{ + p[0] = __builtin_crypto_vpermxor (q[0], r[0], s[0]); + p[1] = __builtin_crypto_vpmsumb (q[1], r[1]); +} diff --git a/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c b/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c index e58816a7f0f..3e4b72919e9 100644 --- a/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c +++ b/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c @@ -1,7 +1,7 @@ -/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-do assemble { target { powerpc*-*-* } } } */ /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ /* { dg-require-effective-target powerpc_htm_ok } */ -/* { dg-options "-O2 -mhtm" } */ +/* { dg-options "-O2 -mhtm -save-temps" } */ /* { dg-final { scan-assembler-times "tbegin\\." 1 } } */ /* { dg-final { scan-assembler-times "tend\\." 2 } } */ @@ -10,7 +10,7 @@ /* { dg-final { scan-assembler-times "tabortdci\\." 1 } } */ /* { dg-final { scan-assembler-times "tabortwc\\." 1 } } */ /* { dg-final { scan-assembler-times "tabortwci\\." 2 } } */ -/* { dg-final { scan-assembler-times "tcheck\\." 1 } } */ +/* { dg-final { scan-assembler-times "tcheck" 1 } } */ /* { dg-final { scan-assembler-times "trechkpt\\." 1 } } */ /* { dg-final { scan-assembler-times "treclaim\\." 1 } } */ /* { dg-final { scan-assembler-times "tsr\\." 3 } } */ @@ -49,3 +49,4 @@ void use_builtins (long *p, char code, long *a, long *b) __builtin_set_tfhar (a[22]); __builtin_set_tfiar (a[23]); } +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr65456.c b/gcc/testsuite/gcc.target/powerpc/pr65456.c new file mode 100644 index 00000000000..5a645c76f96 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr65456.c @@ -0,0 +1,65 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc64le-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ + +/* Verify that swap optimization properly removes swaps for unaligned + vector stores. See PR65456. */ + +typedef unsigned char UChar; +typedef unsigned short UShort; +typedef unsigned int UWord; + +typedef unsigned long SizeT; +typedef unsigned long Addr; + +void *memmove(void *dst, const void *src, SizeT len) +{ + const Addr WS = sizeof(UWord);/* 8 or 4 */ + const Addr WM = WS - 1;/* 7 or 3 */ + + /* Copying backwards. */ + SizeT n = len; + Addr d = (Addr) dst; + Addr s = (Addr) src; + + if (((s ^ d) & WM) == 0) { + /* s and d have same UWord alignment. */ + /* Pull up to a UWord boundary. */ + while ((s & WM) != 0 && n >= 1) { + *(UChar *) d = *(UChar *) s; + s += 1; + d += 1; + n -= 1; + } + /* Copy UWords. */ + while (n >= WS) { + *(UWord *) d = *(UWord *) s; + s += WS; + d += WS; + n -= WS; + } + if (n == 0) + return dst; + } + if (((s | d) & 1) == 0) { + /* Both are 16-aligned; copy what we can thusly. */ + while (n >= 2) { + *(UShort *) d = *(UShort *) s; + s += 2; + d += 2; + n -= 2; + } + } + /* Copy leftovers, or everything if misaligned. */ + while (n >= 1) { + *(UChar *) d = *(UChar *) s; + s += 1; + d += 1; + n -= 1; + } + + return dst; +} + +/* { dg-final { scan-assembler-not "xxpermdi" } } */ +/* { dg-final { scan-assembler-not "xxswapd" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr65787.c b/gcc/testsuite/gcc.target/powerpc/pr65787.c new file mode 100644 index 00000000000..c819be9a707 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr65787.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ +/* { dg-final { scan-assembler "xxsldwi \[0-9\]*,\[0-9\]*,\[0-9\]*,3" } } */ +/* { dg-final { scan-assembler-not "xxpermdi" } } */ + +/* This test verifies that a vector extract operand properly has its + lane changed by the swap optimization. Element 2 of LE corresponds + to element 1 of BE. When doublewords are swapped, this becomes + element 3 of BE, so we need to shift the vector left by 3 words + to be able to extract the correct value from BE element zero. */ + +typedef float v4f32 __attribute__ ((__vector_size__ (16))); + +void foo (float); +extern v4f32 x, y; + +int main() { + v4f32 z = x + y; + foo (z[2]); +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-1.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-1.c new file mode 100644 index 00000000000..ab85e9160a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-1.c @@ -0,0 +1,35 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ +/* { dg-final { scan-assembler "lxvd2x" } } */ +/* { dg-final { scan-assembler "stxvd2x" } } */ +/* { dg-final { scan-assembler-not "xxpermdi" } } */ + +void abort(); + +#define N 16 + +signed char ca[N] __attribute__((aligned(16))); +signed char cb[] __attribute__((aligned(16))) + = {8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7}; +signed char cc[] __attribute__((aligned(16))) + = {1, 1, 2, 2, 3, 3, 2, 2, 1, 1, 0, 0, -1, -1, -2, -2}; + +__attribute__((noinline)) void foo () +{ + int i; + for (i = 0; i < N; i++) { + ca[i] = cb[i] - cc[i]; + } +} + +int main () +{ + signed char cd[] = {7, 6, 4, 3, 1, 0, 0, -1, -1, -2, -2, -3, -3, -4, -4, -5}; + int i; + foo (); + for (i = 0; i < N; ++i) + if (ca[i] != cd[i]) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-10.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-10.c new file mode 100644 index 00000000000..170649df608 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-10.c @@ -0,0 +1,42 @@ +/* { dg-do run { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ + +void abort (); + +#define N 4096 +int ca[N] __attribute__((aligned(16))); +int cb[N] __attribute__((aligned(16))); +int cc[N] __attribute__((aligned(16))); +int cd[N] __attribute__((aligned(16))); + +__attribute__((noinline)) void foo () +{ + int i; + for (i = 0; i < N; i++) { + ca[i] = ((cb[i] + cc[i]) * cd[i]) >> 3; + } +} + +__attribute__((noinline)) void init () +{ + int i; + for (i = 0; i < N; ++i) { + cb[i] = 3 * i - 2048; + cc[i] = -5 * i + 93; + cd[i] = i % 2 ? 1 : -1; + } +} + +int main () +{ + int i; + init (); + foo (); + for (i = 0; i < N; ++i) + if (i % 2 == 1 && ca[i] != (-2 * i - 1955) >> 3) + abort (); + else if (i % 2 == 0 && ca[i] != (1955 + 2 * i) >> 3) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-11.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-11.c new file mode 100644 index 00000000000..699b5baf404 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-11.c @@ -0,0 +1,53 @@ +/* { dg-do run { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ + +#include <altivec.h> +void abort (); + +#define N 4096 +int ca[N] __attribute__((aligned(16))); +int cb[N] __attribute__((aligned(16))); +int cc[N] __attribute__((aligned(16))); +int cd[N] __attribute__((aligned(16))); +int hey; + +__attribute__((noinline)) void foo () +{ + int i; + vector int va, vb, vc, vd, tmp; + vector unsigned int threes = vec_splat_u32(3); + for (i = 0; i < N; i+=4) { + vb = vec_vsx_ld (0, &cb[i]); + vc = vec_vsx_ld (0, &cc[i]); + vd = vec_vsx_ld (0, &cd[i]); + tmp = vec_add (vb, vc); + tmp = vec_sub (tmp, vd); + tmp = vec_sra (tmp, threes); + hey = tmp[3]; + vec_vsx_st (tmp, 0, &ca[i]); + } +} + +__attribute__((noinline)) void init () +{ + int i; + for (i = 0; i < N; ++i) { + cb[i] = 3 * i - 2048; + cc[i] = -5 * i + 93; + cd[i] = i + 14; + } +} + +int main () +{ + int i; + init (); + foo (); + for (i = 0; i < N; ++i) + if (ca[i] != (-3 * i - 1969) >> 3) + abort (); + if (hey != ca[N-1]) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-12.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-12.c new file mode 100644 index 00000000000..529d03e64c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-12.c @@ -0,0 +1,56 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ +/* { dg-final { scan-assembler "lxvd2x" } } */ +/* { dg-final { scan-assembler "stxvd2x" } } */ +/* { dg-final { scan-assembler-not "xxpermdi" } } */ + +#include "altivec.h" +void abort (); + +#define N 4096 +int ca[N] __attribute__((aligned(16))); +int cb[N] __attribute__((aligned(16))); +int cc[N] __attribute__((aligned(16))); +int cd[N] __attribute__((aligned(16))); +int hey; + +__attribute__((noinline)) void foo () +{ + int i; + vector int va, vb, vc, vd, tmp; + vector unsigned int threes = vec_splat_u32(3); + for (i = 0; i < N; i+=4) { + vb = vec_vsx_ld (0, &cb[i]); + vc = vec_vsx_ld (0, &cc[i]); + vd = vec_vsx_ld (0, &cd[i]); + tmp = vec_add (vb, vc); + tmp = vec_sub (tmp, vd); + tmp = vec_sra (tmp, threes); + hey = tmp[3]; + vec_vsx_st (tmp, 0, &ca[i]); + } +} + +__attribute__((noinline)) void init () +{ + int i; + for (i = 0; i < N; ++i) { + cb[i] = 3 * i - 2048; + cc[i] = -5 * i + 93; + cd[i] = i + 14; + } +} + +int main () +{ + int i; + init (); + foo (); + for (i = 0; i < N; ++i) + if (ca[i] != (-3 * i - 1969) >> 3) + abort (); + if (hey != ca[N-1]) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-13.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-13.c new file mode 100644 index 00000000000..787b02e6427 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-13.c @@ -0,0 +1,54 @@ +/* { dg-do run { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ + +#include <altivec.h> +void abort (); + +#define N 4096 +long long ca[N] __attribute__((aligned(16))); +long long cb[N] __attribute__((aligned(16))); +long long cc[N] __attribute__((aligned(16))); +long long cd[N] __attribute__((aligned(16))); +long long x; + +__attribute__((noinline)) void foo () +{ + int i; + vector long long va, vb, vc, vd, tmp; + volatile unsigned long long three = 3; + vector unsigned long long threes = vec_splats (three); + for (i = 0; i < N; i+=2) { + vb = vec_vsx_ld (0, (vector long long *)&cb[i]); + vc = vec_vsx_ld (0, (vector long long *)&cc[i]); + vd = vec_vsx_ld (0, (vector long long *)&cd[i]); + tmp = vec_add (vb, vc); + tmp = vec_sub (tmp, vd); + tmp = vec_sra (tmp, threes); + x = vec_extract (tmp, 0); + vec_vsx_st (tmp, 0, (vector long long *)&ca[i]); + } +} + +__attribute__((noinline)) void init () +{ + int i; + for (i = 0; i < N; ++i) { + cb[i] = 3 * i - 2048; + cc[i] = -5 * i + 93; + cd[i] = i + 14; + } +} + +int main () +{ + int i; + init (); + foo (); + for (i = 0; i < N; ++i) + if (ca[i] != (-3 * i - 1969) >> 3) + abort (); + if (x != ca[N-1]) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-15.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-15.c new file mode 100644 index 00000000000..172e4bd4cb1 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-15.c @@ -0,0 +1,51 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ +/* { dg-final { scan-assembler "lxvd2x" } } */ +/* { dg-final { scan-assembler "stxvd2x" } } */ +/* { dg-final { scan-assembler "xxspltw" } } */ + +/* Currently the analyze_swaps phase cannot optimize this loop because + of the presence of an UNSPEC_VSX_CVDPSPN. At such time as this is + handled, we need to add a 'scan-assembler-not "xxpermdi"' directive to + this test. */ +#include <altivec.h> +void abort(); + +#define N 4096 +#define M 10000000 +vector float ca[N][4] = {0}; +vector float cb[N][4] = {0}; +vector float cc[N][4] = {0}; + +__attribute__((noinline)) void foo () +{ + int i; + for (i = 0; i < N; i++) { + cc[i][0] = vec_mul(vec_splats(cb[i][0][0]), ca[i][0]); + cc[i][0] = vec_madd(cc[i][0],vec_splats(cb[i][0][1]), ca[i][1]); + cc[i][0] = vec_madd(cc[i][0],vec_splats(cb[i][0][2]), ca[i][2]); + cc[i][0] = vec_madd(cc[i][0],vec_splats(cb[i][0][3]), ca[i][3]); + + cc[i][1] = vec_mul(vec_splats(cb[i][1][0]), ca[i][0]); + cc[i][1] = vec_madd(cc[i][0],vec_splats(cb[i][1][1]), ca[i][1]); + cc[i][1] = vec_madd(cc[i][0],vec_splats(cb[i][1][2]), ca[i][2]); + cc[i][1] = vec_madd(cc[i][0],vec_splats(cb[i][1][3]), ca[i][3]); + + cc[i][2] = vec_mul(vec_splats(cb[i][2][0]), ca[i][0]); + cc[i][2] = vec_madd(cc[i][0],vec_splats(cb[i][2][1]), ca[i][1]); + cc[i][2] = vec_madd(cc[i][0],vec_splats(cb[i][2][2]), ca[i][2]); + cc[i][2] = vec_madd(cc[i][0],vec_splats(cb[i][2][3]), ca[i][3]); + + cc[i][3] = vec_mul(vec_splats(cb[i][3][0]), ca[i][0]); + cc[i][3] = vec_madd(cc[i][0],vec_splats(cb[i][3][1]), ca[i][1]); + cc[i][3] = vec_madd(cc[i][0],vec_splats(cb[i][3][2]), ca[i][2]); + cc[i][3] = vec_madd(cc[i][0],vec_splats(cb[i][3][3]), ca[i][3]); + } +} + +int main () +{ + foo (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-17.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-17.c new file mode 100644 index 00000000000..7a9cfbf954e --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-17.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O1" } */ +/* { dg-final { scan-assembler "lxvd2x" } } */ +/* { dg-final { scan-assembler "xxpermdi" } } */ + +/* Verify that we don't try to do permute removal in the presence of + vec_ste. This used to ICE. */ +#include <altivec.h> + +void f (void *p) +{ + vector unsigned int u32 = vec_vsx_ld (1, (const unsigned int *)p); + vec_ste (u32, 1, (unsigned int *)p); +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-18.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-18.c new file mode 100644 index 00000000000..c55f527d420 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-18.c @@ -0,0 +1,35 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ +/* { dg-final { scan-assembler-not "xxpermdi" } } */ + +/* This is a test for a specific convert-splat permute removal. */ + +void compute (float*, float*, float*, int, int); +double test (void); +double gorp; + +int main (void) +{ + float X[10000], Y[256], Z[2000]; + int i; + for (i = 0; i < 2500; i++) + compute (X, Y, Z, 256, 2000); + gorp = test (); +} + +void compute(float *X, float *Y, float *Z, int m, int n) +{ + int i, j; + float w, *x, *y; + + for (i = 0; i < n; i++) + { + w = 0.0; + x = X++; + y = Y; + for (j = 0; j < m; j++) + w += (*x++) * (*y++); + Z[i] = w; + } +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-3.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-3.c new file mode 100644 index 00000000000..35dacd4b578 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-3.c @@ -0,0 +1,43 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ +/* { dg-final { scan-assembler "lxvd2x" } } */ +/* { dg-final { scan-assembler "stxvd2x" } } */ +/* { dg-final { scan-assembler-not "xxpermdi" } } */ + +void abort (); + +#define N 4096 +signed char ca[N] __attribute__((aligned(16))); +signed char cb[N] __attribute__((aligned(16))); +signed char cc[N] __attribute__((aligned(16))); + +__attribute__((noinline)) void foo () +{ + int i; + for (i = 0; i < N; i++) { + ca[i] = cb[i] - cc[i]; + } +} + +__attribute__((noinline)) void init () +{ + int i, ii; + for (i = 0, ii = 0; i < N; ++i, ii = (ii + 1) % 128) { + cb[i] = ii - 128; + cc[i] = ii/2 - 64; + } +} + +int main () +{ + int i, ii; + init (); + foo (); + for (i = 0; i < N; ++i) { + ii = i % 128; + if (ca[i] != ii - ii/2 - 64) + abort (); + } + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-4.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-4.c new file mode 100644 index 00000000000..61fe99b357b --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-4.c @@ -0,0 +1,45 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ +/* { dg-final { scan-assembler "lxvd2x" } } */ +/* { dg-final { scan-assembler "stxvd2x" } } */ +/* { dg-final { scan-assembler-not "xxpermdi" } } */ + +void abort (); + +#define N 4096 +int ca[N] __attribute__((aligned(16))); +int cb[N] __attribute__((aligned(16))); +int cc[N] __attribute__((aligned(16))); +int cd[N] __attribute__((aligned(16))); + +__attribute__((noinline)) void foo () +{ + int i; + for (i = 0; i < N; i++) { + ca[i] = (cb[i] + cc[i]) * cd[i]; + } +} + +__attribute__((noinline)) void init () +{ + int i; + for (i = 0; i < N; ++i) { + cb[i] = 3 * i - 2048; + cc[i] = -5 * i + 93; + cd[i] = i % 2 ? 1 : -1; + } +} + +int main () +{ + int i; + init (); + foo (); + for (i = 0; i < N; ++i) + if (i % 2 == 1 && ca[i] != -2 * i - 1955) + abort (); + else if (i % 2 == 0 && ca[i] != 1955 + 2 * i) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-5.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-5.c new file mode 100644 index 00000000000..b367fb6b514 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-5.c @@ -0,0 +1,45 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ +/* { dg-final { scan-assembler "lxvd2x" } } */ +/* { dg-final { scan-assembler "stxvd2x" } } */ +/* { dg-final { scan-assembler-not "xxpermdi" } } */ + +void abort (); + +#define N 4096 +int ca[N] __attribute__((aligned(16))); +int cb[N] __attribute__((aligned(16))); +int cc[N] __attribute__((aligned(16))); +int cd[N] __attribute__((aligned(16))); + +__attribute__((noinline)) void foo () +{ + int i; + for (i = 0; i < N; i++) { + ca[i] = ((cb[i] + cc[i]) * cd[i]) >> 3; + } +} + +__attribute__((noinline)) void init () +{ + int i; + for (i = 0; i < N; ++i) { + cb[i] = 3 * i - 2048; + cc[i] = -5 * i + 93; + cd[i] = i % 2 ? 1 : -1; + } +} + +int main () +{ + int i; + init (); + foo (); + for (i = 0; i < N; ++i) + if (i % 2 == 1 && ca[i] != (-2 * i - 1955) >> 3) + abort (); + else if (i % 2 == 0 && ca[i] != (1955 + 2 * i) >> 3) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-6.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-6.c new file mode 100644 index 00000000000..f7084529ce8 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-6.c @@ -0,0 +1,32 @@ +/* { dg-do run { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ + +void abort(); + +#define N 16 + +signed char ca[N] __attribute__((aligned(16))); +signed char cb[] __attribute__((aligned(16))) + = {8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7}; +signed char cc[] __attribute__((aligned(16))) + = {1, 1, 2, 2, 3, 3, 2, 2, 1, 1, 0, 0, -1, -1, -2, -2}; + +__attribute__((noinline)) void foo () +{ + int i; + for (i = 0; i < N; i++) { + ca[i] = cb[i] - cc[i]; + } +} + +int main () +{ + signed char cd[] = {7, 6, 4, 3, 1, 0, 0, -1, -1, -2, -2, -3, -3, -4, -4, -5}; + int i; + foo (); + for (i = 0; i < N; ++i) + if (ca[i] != cd[i]) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-7.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-7.c new file mode 100644 index 00000000000..27a31b711ff --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-7.c @@ -0,0 +1,38 @@ +/* { dg-do run { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ + +void abort (); + +#define N 256 +signed char ca[N] __attribute__((aligned(16))); +signed char cb[N] __attribute__((aligned(16))); +signed char cc[N] __attribute__((aligned(16))); + +__attribute__((noinline)) void foo () +{ + int i; + for (i = 0; i < N; i++) { + ca[i] = cb[i] - cc[i]; + } +} + +__attribute__((noinline)) void init () +{ + int i; + for (i = 0; i < N; ++i) { + cb[i] = i - 128; + cc[i] = i/2 - 64; + } +} + +int main () +{ + int i; + init (); + foo (); + for (i = 0; i < N; ++i) + if (ca[i] != i - i/2 - 64) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-8.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-8.c new file mode 100644 index 00000000000..7264d2586b3 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-8.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ + +void abort (); + +#define N 4096 +signed char ca[N] __attribute__((aligned(16))); +signed char cb[N] __attribute__((aligned(16))); +signed char cc[N] __attribute__((aligned(16))); + +__attribute__((noinline)) void foo () +{ + int i; + for (i = 0; i < N; i++) { + ca[i] = cb[i] - cc[i]; + } +} + +__attribute__((noinline)) void init () +{ + int i, ii; + for (i = 0, ii = 0; i < N; ++i, ii = (ii + 1) % 128) { + cb[i] = ii - 128; + cc[i] = ii/2 - 64; + } +} + +int main () +{ + int i, ii; + init (); + foo (); + for (i = 0; i < N; ++i) { + ii = i % 128; + if (ca[i] != ii - ii/2 - 64) + abort (); + } + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-9.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-9.c new file mode 100644 index 00000000000..cdca070e3d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-9.c @@ -0,0 +1,42 @@ +/* { dg-do run { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3" } */ + +void abort (); + +#define N 4096 +int ca[N] __attribute__((aligned(16))); +int cb[N] __attribute__((aligned(16))); +int cc[N] __attribute__((aligned(16))); +int cd[N] __attribute__((aligned(16))); + +__attribute__((noinline)) void foo () +{ + int i; + for (i = 0; i < N; i++) { + ca[i] = (cb[i] + cc[i]) * cd[i]; + } +} + +__attribute__((noinline)) void init () +{ + int i; + for (i = 0; i < N; ++i) { + cb[i] = 3 * i - 2048; + cc[i] = -5 * i + 93; + cd[i] = i % 2 ? 1 : -1; + } +} + +int main () +{ + int i; + init (); + foo (); + for (i = 0; i < N; ++i) + if (i % 2 == 1 && ca[i] != -2 * i - 1955) + abort (); + else if (i % 2 == 0 && ca[i] != 1955 + 2 * i) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-2.c b/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-2.c index 7bb7db0fa5f..c17fe28ec87 100644 --- a/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-2.c +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-2.c @@ -58,7 +58,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" {xfail {! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" {xfail { {! vect_hw_misalign } || powerpc*-*-* } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" {xfail {! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" {xfail { {! vect_hw_misalign } || powerpc*-*-* } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-4.c b/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-4.c index ad6f8f0fec5..952a68e58b8 100644 --- a/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-4.c +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-4.c @@ -54,7 +54,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" {xfail {! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" {xfail { {! vect_hw_misalign } || powerpc*-*-* } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" {xfail {! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" {xfail { {! vect_hw_misalign } || powerpc*-*-* } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-6.c b/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-6.c index 8e6e288b9bf..1538cc1a421 100644 --- a/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-6.c +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-6.c @@ -58,7 +58,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" {xfail {! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" {xfail { {! vect_hw_misalign } || powerpc*-*-* } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" {xfail {! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" {xfail { {! vect_hw_misalign } || powerpc*-*-* } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-7.c b/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-7.c index c09583535e1..a45233b8e05 100644 --- a/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-7.c +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vectorize-7.c @@ -58,7 +58,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" {xfail {! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" {xfail { {! vect_hw_misalign } || powerpc*-*-* } } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" {xfail {! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" {xfail { {! vect_hw_misalign } || powerpc*-*-* } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-1.c b/gcc/testsuite/gcc.target/s390/hotpatch-1.c index b9d6139b080..b14fa9010a8 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-1.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-1.c @@ -1,7 +1,7 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ #include <stdio.h> @@ -10,11 +10,10 @@ void hp1(void) printf("hello, world!\n"); } -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ -/* { dg-final { scan-assembler-times "nopr\t%r7" 12 } } */ -/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler-not "post-label NOPs" } } */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-10.c b/gcc/testsuite/gcc.target/s390/hotpatch-10.c index b91b3478ee3..a990c4cad6e 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-10.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-10.c @@ -1,21 +1,19 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mno-hotpatch --save-temps" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,0" } */ #include <stdio.h> -__attribute__ ((hotpatch(2))) void hp1(void) { printf("hello, world!\n"); } -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ -/* { dg-final { scan-assembler-times "nopr\t%r7" 2 } } */ -/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler-not "post-label NOPs" } } */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-11.c b/gcc/testsuite/gcc.target/s390/hotpatch-11.c index 49167734253..6f8a52b26d3 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-11.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-11.c @@ -1,7 +1,7 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch -mno-hotpatch --save-temps" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1,0" } */ #include <stdio.h> @@ -10,11 +10,9 @@ void hp1(void) printf("hello, world!\n"); } -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ -/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */ +/* { dg-final { scan-assembler-not "post-label NOPs" } } */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ /* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-12.c b/gcc/testsuite/gcc.target/s390/hotpatch-12.c index b3e9427d4e2..b73ca90fd3d 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-12.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-12.c @@ -1,7 +1,7 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mno-hotpatch -mhotpatch=1 --save-temps" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=999,0" } */ #include <stdio.h> @@ -10,11 +10,9 @@ void hp1(void) printf("hello, world!\n"); } -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ -/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ -/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler "pre-label.*(999 halfwords)" } } */ +/* { dg-final { scan-assembler-not "post-label NOPs" } } */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 999 } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-13.c b/gcc/testsuite/gcc.target/s390/hotpatch-13.c new file mode 100644 index 00000000000..150667a1c66 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-13.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch(1,0))) +void hp1(void) +{ + printf("hello, world!\n"); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */ +/* { dg-final { scan-assembler-not "post-label NOPs" } } */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ +/* { dg-final { scan-assembler "alignment for hotpatch" } } */ +/* { dg-final { scan-assembler-times "\.align\t8" 2 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-14.c b/gcc/testsuite/gcc.target/s390/hotpatch-14.c new file mode 100644 index 00000000000..c5f118c1cc6 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-14.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch(0,2))) +void hp1(void) +{ + printf("hello, world!\n"); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-15.c b/gcc/testsuite/gcc.target/s390/hotpatch-15.c new file mode 100644 index 00000000000..ef0fb746227 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-15.c @@ -0,0 +1,19 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch(1,2))) +void hp1(void) +{ + printf("hello, world!\n"); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */ +/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-16.c b/gcc/testsuite/gcc.target/s390/hotpatch-16.c new file mode 100644 index 00000000000..a34bf95c3cb --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-16.c @@ -0,0 +1,19 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,0" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch(1,2))) +void hp1(void) +{ + printf("hello, world!\n"); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */ +/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-17.c b/gcc/testsuite/gcc.target/s390/hotpatch-17.c new file mode 100644 index 00000000000..66ac725d16a --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-17.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1,2" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch(0,0))) +void hp1(void) +{ + printf("hello, world!\n"); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler-not "post-label NOPs" } } */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-18.c b/gcc/testsuite/gcc.target/s390/hotpatch-18.c new file mode 100644 index 00000000000..8b076a4e175 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-18.c @@ -0,0 +1,19 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1,2 -mhotpatch=0,0" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler-not "post-label NOPs" } } */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-19.c b/gcc/testsuite/gcc.target/s390/hotpatch-19.c new file mode 100644 index 00000000000..6993c7e855c --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-19.c @@ -0,0 +1,25 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1,2" } */ + +#include <stdio.h> + +/* { dg-prune-output "always_inline function might not be inlinable" } */ +__attribute__ ((always_inline)) +static void hp2(void) +{ + printf("hello, world!\n"); +} + +void hp1(void) +{ + hp2(); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */ +/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-2.c b/gcc/testsuite/gcc.target/s390/hotpatch-2.c index 6cc29447de4..67189f8a28b 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-2.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-2.c @@ -1,7 +1,7 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch=1 --save-temps" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,1" } */ #include <stdio.h> @@ -10,11 +10,10 @@ void hp1(void) printf("hello, world!\n"); } -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler "post-label.*(1 halfwords)" } } */ /* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ -/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-20.c b/gcc/testsuite/gcc.target/s390/hotpatch-20.c new file mode 100644 index 00000000000..09ef5caaea3 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-20.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +#include <stdio.h> + +/* { dg-prune-output "always_inline function might not be inlinable" } */ +__attribute__ ((hotpatch(1,2))) +__attribute__ ((always_inline)) +static void hp2(void) +{ + printf("hello, world!\n"); +} + +/* { dg-prune-output "called from here" } */ +void hp1(void) +{ + hp2(); +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-21.c b/gcc/testsuite/gcc.target/s390/hotpatch-21.c new file mode 100644 index 00000000000..e9099900855 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-21.c @@ -0,0 +1,14 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,1" } */ + +#include <stdio.h> + +void __attribute__ ((aligned(512))) hp1(void) +{ + printf("hello, world!\n"); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-22.c b/gcc/testsuite/gcc.target/s390/hotpatch-22.c new file mode 100644 index 00000000000..d89d7790426 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-22.c @@ -0,0 +1,14 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,1 -falign-functions=1024" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-23.c b/gcc/testsuite/gcc.target/s390/hotpatch-23.c new file mode 100644 index 00000000000..1e05d123c22 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-23.c @@ -0,0 +1,14 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,1 -falign-functions=4096" } */ + +#include <stdio.h> + +void __attribute__ ((aligned(2048))) hp1(void) +{ + printf("hello, world!\n"); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-24.c b/gcc/testsuite/gcc.target/s390/hotpatch-24.c new file mode 100644 index 00000000000..fc6427479d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-24.c @@ -0,0 +1,14 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,1 -falign-functions=2048" } */ + +#include <stdio.h> + +void __attribute__ ((aligned(4096))) hp1(void) +{ + printf("hello, world!\n"); +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-25.c b/gcc/testsuite/gcc.target/s390/hotpatch-25.c new file mode 100644 index 00000000000..e9257e3744e --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-25.c @@ -0,0 +1,33 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +typedef long (*fn_t)(void); + +__attribute__ ((hotpatch(1,2))) +fn_t outer(void) +{ + __attribute__ ((hotpatch(4,8))) + long nested1(void) + { + __attribute__ ((hotpatch(16,32))) + long nested2(void) + { + return 2; + } + return (long)(void *)nested2; + } + + return nested1; +} + +/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */ +/* { dg-final { scan-assembler "pre-label.*(4 halfwords)" } } */ +/* { dg-final { scan-assembler "pre-label.*(16 halfwords)" } } */ +/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */ +/* { dg-final { scan-assembler "post-label.*(8 halfwords)" } } */ +/* { dg-final { scan-assembler "post-label.*(32 halfwords)" } } */ +/* { dg-final { scan-assembler-times "alignment for hotpatch" 3 } } */ +/* { dg-final { scan-assembler-times "\.align\t8" 6 } } */ +/* { dg-final { scan-assembler "nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-3.c b/gcc/testsuite/gcc.target/s390/hotpatch-3.c index 9f0b2b756a4..ec4a978f72e 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-3.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-3.c @@ -1,7 +1,7 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch=0 --save-temps" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,2" } */ #include <stdio.h> @@ -10,11 +10,9 @@ void hp1(void) printf("hello, world!\n"); } -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */ /* { dg-final { scan-assembler-not "nopr\t%r7" } } */ /* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-4.c b/gcc/testsuite/gcc.target/s390/hotpatch-4.c index c1dba20a379..d55e71d3d69 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-4.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-4.c @@ -1,26 +1,18 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,3" } */ #include <stdio.h> -inline void hp1(void) +void hp1(void) { printf("hello, world!\n"); } -__attribute__ ((always_inline)) -void hp2(void) /* { dg-warning "always_inline function might not be inlinable" } */ -{ - printf("hello, world!\n"); -} /* { dg-warning "function 'hp2' with the 'always_inline' attribute is not hotpatchable" } */ - -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler "post-label.*(3 halfwords)" } } */ /* { dg-final { scan-assembler-not "nopr\t%r7" } } */ /* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-times "brcl\t0, 0" 1 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-5.c b/gcc/testsuite/gcc.target/s390/hotpatch-5.c index ec267d65aae..f77d83aea07 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-5.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-5.c @@ -1,21 +1,18 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,4" } */ #include <stdio.h> -__attribute__ ((hotpatch)) void hp1(void) { printf("hello, world!\n"); } -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ -/* { dg-final { scan-assembler-times "nopr\t%r7" 12 } } */ -/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler "post-label.*(4 halfwords)" } } */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-times "brcl\t0, 0" 1 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-6.c b/gcc/testsuite/gcc.target/s390/hotpatch-6.c index 5af090d03a6..330cf5d011f 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-6.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-6.c @@ -1,21 +1,18 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,5" } */ #include <stdio.h> -__attribute__ ((hotpatch(1))) void hp1(void) { printf("hello, world!\n"); } -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ -/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler "post-label.*(5 halfwords)" } } */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ /* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-times "brcl\t0, 0" 1 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-7.c b/gcc/testsuite/gcc.target/s390/hotpatch-7.c index e73a510b4d6..2f24e3cc152 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-7.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-7.c @@ -1,21 +1,18 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,6" } */ #include <stdio.h> -__attribute__ ((hotpatch(0))) void hp1(void) { printf("hello, world!\n"); } -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler "post-label.*(6 halfwords)" } } */ /* { dg-final { scan-assembler-not "nopr\t%r7" } } */ -/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-times "brcl\t0, 0" 2 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-8.c b/gcc/testsuite/gcc.target/s390/hotpatch-8.c index 399aa7260b4..7b266bd463e 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-8.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-8.c @@ -1,28 +1,19 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ +/* { dg-do compile { target { ! lp64 } } } */ +/* { dg-options "-O3 -mesa -march=g5 -mhotpatch=0,3" } */ #include <stdio.h> -__attribute__ ((hotpatch)) -inline void hp1(void) +void hp1(void) { printf("hello, world!\n"); } -__attribute__ ((hotpatch)) -__attribute__ ((always_inline)) -void hp2(void) /* { dg-warning "always_inline function might not be inlinable" } */ -{ - printf("hello, world!\n"); -} /* { dg-warning "function 'hp2' with the 'always_inline' attribute is not hotpatchable" } */ - -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ -/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ -/* { dg-final { scan-assembler-not "nop\t0" } } */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler "post-label.*(3 halfwords)" } } */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ +/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-9.c b/gcc/testsuite/gcc.target/s390/hotpatch-9.c index 5da675866b3..c0ad319c0bb 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-9.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-9.c @@ -1,21 +1,18 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch=1 --save-temps" } */ +/* { dg-do compile { target { ! lp64 } } } */ +/* { dg-options "-O3 -mesa -march=g5 -mhotpatch=0,4" } */ #include <stdio.h> -__attribute__ ((hotpatch(2))) void hp1(void) { printf("hello, world!\n"); } -int main (void) -{ - return 0; -} - /* Check number of occurences of certain instructions. */ -/* { dg-final { scan-assembler-times "nopr\t%r7" 2 } } */ -/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ +/* { dg-final { scan-assembler-not "pre-label NOPs" } } */ +/* { dg-final { scan-assembler "post-label.*(4 halfwords)" } } */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-times "nop\t0" 2 } } */ +/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c index 45a2cc5dc20..ca47f6be5de 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c @@ -1,27 +1,5 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch" } */ - -#include <stdio.h> - -void hp1(void) -{ - printf("hello, world!\n"); -} - -inline void hp2(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((always_inline)) -void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */ -{ - printf("hello, world!\n"); -} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */ - -int main (void) -{ - return 0; -} +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=-1,0" } */ +/* { dg-error "arguments to .-mhotpatch=n,m. should be non-negative integers" "" { target *-*-* } 1 } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-10.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-10.c new file mode 100644 index 00000000000..8b6441d771e --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-10.c @@ -0,0 +1,10 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +__attribute__((hotpatch(0,0,0))) +int main (void) +{/* { dg-error "wrong number of arguments specified" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-11.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-11.c new file mode 100644 index 00000000000..36c0e225e4d --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-11.c @@ -0,0 +1,12 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +int a; + +__attribute__((hotpatch(a,0))) +int main (void) +{ /* { dg-error "attribute is not a comma separated pair of non-negative integer constants or too large" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-12.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-12.c new file mode 100644 index 00000000000..9b5fbd3f927 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-12.c @@ -0,0 +1,12 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +int a; + +__attribute__((hotpatch(0,a))) +int main (void) +{ /* { dg-error "attribute is not a comma separated pair of non-negative integer constants or too large" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-13.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-13.c new file mode 100644 index 00000000000..a8752412742 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-13.c @@ -0,0 +1,29 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1000000,1000000" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(1000000,1000000))) +void hp2(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(1000001,1000000))) +void hp3(void) +{ /* { dg-error " requested .hotpatch. attribute is not a comma separated pair" } */ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(1000000,1000001))) +void hp4(void) +{ /* { dg-error " requested .hotpatch. attribute is not a comma separated pair" } */ + printf("hello, world!\n"); +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-14.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-14.c new file mode 100644 index 00000000000..0b5e674d407 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-14.c @@ -0,0 +1,11 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1000001,1000000" } */ + +viod main(void) +{ + return 0; +} + +/* { dg-error "argument to .-mhotpatch=n,m. is too large" "" { target *-*-* } 1 } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-15.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-15.c new file mode 100644 index 00000000000..4ce7375a7c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-15.c @@ -0,0 +1,43 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +/* { dg-prune-output "always_inline function might not be inlinable" } */ +/* { dg-prune-output "called from here" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch(1,2))) +static void hp1(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(1,2))) +static inline void hp2(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(0,0))) +__attribute__ ((always_inline)) +static void hp3(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(1,2))) +__attribute__ ((always_inline)) +static void hp4(void) +{ + printf("hello, world!\n"); +} + +void main(void) +{ + hp1(); + hp2(); + hp3(); + hp4(); +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-16.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-16.c new file mode 100644 index 00000000000..2e8291ede34 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-16.c @@ -0,0 +1,24 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +typedef int (*fn_t)(void); + +fn_t hp1(void) +{ + __attribute__((hotpatch(0,0))) + int nested1(void) + { return 1; } + + return nested1; +} + +fn_t hp2(void) +{ + __attribute__ ((hotpatch(1,2))) + int nested2(void) + { return 2; } + + return nested2; +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c index 5947f564f53..78253f59583 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c @@ -1,27 +1,5 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch=0" } */ - -#include <stdio.h> - -void hp1(void) -{ - printf("hello, world!\n"); -} - -inline void hp2(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((always_inline)) -void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */ -{ - printf("hello, world!\n"); -} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */ - -int main (void) -{ - return 0; -} +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,-1" } */ +/* { dg-error "arguments to .-mhotpatch=n,m. should be non-negative integers" "" { target *-*-* } 1 } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c index e0c7f6f52c1..6dde22422b0 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c @@ -1,27 +1,5 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch=1" } */ - -#include <stdio.h> - -void hp1(void) -{ - printf("hello, world!\n"); -} - -inline void hp2(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((always_inline)) -void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */ -{ - printf("hello, world!\n"); -} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */ - -int main (void) -{ - return 0; -} +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0" } */ +/* { dg-error "arguments to .-mhotpatch=n,m. should be non-negative integers" "" { target *-*-* } 1 } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c index d9f13425adc..fbb30833775 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c @@ -1,11 +1,5 @@ /* Functional tests for the function hotpatching feature. */ /* { dg-do compile } */ -/* { dg-options "-O3 -mzarch -mhotpatch=-1" } */ - -int main (void) -{ - return 0; -} - -/* { dg-excess-errors "argument to '-mhotpatch=' should be a non-negative integer" } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,0,0" } */ +/* { dg-error "arguments to .-mhotpatch=n,m. should be non-negative integers" "" { target *-*-* } 1 } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c index 53f7eac9e54..dc0ff6775b8 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c @@ -1,28 +1,5 @@ /* Functional tests for the function hotpatching feature. */ /* { dg-do compile } */ -/* { dg-options "-O3 -mzarch -mhotpatch=1000000" } */ - -#include <stdio.h> - -void hp1(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((hotpatch(1000000))) -void hp2(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((hotpatch(1000001))) -void hp3(void) -{ /* { dg-error "requested 'hotpatch' attribute is not a non-negative integer constant or too large .max. 1000000." } */ - printf("hello, world!\n"); -} - -int main (void) -{ - return 0; -} +/* { dg-options "-O3 -mzarch -mhotpatch=a,0" } */ +/* { dg-error "arguments to .-mhotpatch=n,m. should be non-negative integers" "" { target *-*-* } 1 } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c index cb10b66f0d3..d04045eecd5 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c @@ -1,11 +1,5 @@ /* Functional tests for the function hotpatching feature. */ /* { dg-do compile } */ -/* { dg-options "-O3 -mzarch -mhotpatch=1000001" } */ - -int main (void) -{ - return 0; -} - -/* { dg-excess-errors "argument to '-mhotpatch=' is too large .max. 1000000." } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0,a" } */ +/* { dg-error "arguments to .-mhotpatch=n,m. should be non-negative integers" "" { target *-*-* } 1 } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c index 98ccb42c003..3505703fe8c 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c @@ -1,68 +1,10 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mno-hotpatch" } */ - -#include <stdio.h> - -__attribute__ ((hotpatch)) -void hp1(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((hotpatch)) -inline void hp2(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((hotpatch)) -__attribute__ ((always_inline)) -void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */ -{ - printf("hello, world!\n"); -} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */ - -__attribute__ ((hotpatch(0))) -void hp4(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((hotpatch(0))) -inline void hp5(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((hotpatch(0))) -__attribute__ ((always_inline)) -void hp6(void) /* { dg-warning "always_inline function might not be inlinable" } */ -{ - printf("hello, world!\n"); -} /* { dg-warning "function 'hp6' with the 'always_inline' attribute is not hotpatchable" } */ - -__attribute__ ((hotpatch(1))) -void hp7(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((hotpatch(1))) -inline void hp8(void) -{ - printf("hello, world!\n"); -} - -__attribute__ ((hotpatch(1))) -__attribute__ ((always_inline)) -void hp9(void) /* { dg-warning "always_inline function might not be inlinable" } */ -{ - printf("hello, world!\n"); -} /* { dg-warning "function 'hp9' with the 'always_inline' attribute is not hotpatchable" } */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ +__attribute__((hotpatch(-1,0))) int main (void) -{ +{/* { dg-error "attribute is not a comma separated pair of non-negative integer constants or too large" } */ return 0; } diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-8.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-8.c index 489fc5dd9f0..fd354313627 100644 --- a/gcc/testsuite/gcc.target/s390/hotpatch-compile-8.c +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-8.c @@ -1,23 +1,10 @@ /* Functional tests for the function hotpatching feature. */ -/* { dg-do run } */ -/* { dg-options "-O3 -mzarch -mhotpatch" } */ - -#include <stdio.h> - -int hp1(void) -{ - int nested1(void) /* { dg-warning "hotpatching is not compatible with nested functions" } */ - { return 1; } - - __attribute__ ((hotpatch)) - int nested2(void) /* { dg-warning "hotpatching is not compatible with nested functions" } */ - { return 1; } - - return nested1() - nested2(); -} +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ +__attribute__((hotpatch(0,-1))) int main (void) -{ - return hp1(); +{/* { dg-error "attribute is not a comma separated pair of non-negative integer constants or too large" } */ + return 0; } diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-9.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-9.c new file mode 100644 index 00000000000..dcefbe4aac7 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-9.c @@ -0,0 +1,10 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch" } */ + +__attribute__((hotpatch(0))) +int main (void) +{/* { dg-error "wrong number of arguments specified" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c b/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c index 6022efb97fe..62f2d68e909 100644 --- a/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c +++ b/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c @@ -48,3 +48,4 @@ int main(void) /* Make sure no FPR saves/restores are emitted. */ /* { dg-final { scan-assembler-not "\tstd\t" } } */ /* { dg-final { scan-assembler-not "\tld\t" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/sh/pr53988.c b/gcc/testsuite/gcc.target/sh/pr53988.c index 4bade1efb73..407754781ff 100644 --- a/gcc/testsuite/gcc.target/sh/pr53988.c +++ b/gcc/testsuite/gcc.target/sh/pr53988.c @@ -5,9 +5,9 @@ /* { dg-do compile { target "sh*-*-*" } } */ /* { dg-options "-O1" } */ /* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ -/* { dg-final { scan-assembler-times "tst\tr" 8 } } */ -/* { dg-final { scan-assembler-not "tst\t#255" } } */ -/* { dg-final { scan-assembler-not "exts|extu|and|movu" } } */ +/* { dg-final { scan-assembler-times "tst\tr" 8 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-not "tst\t#255" { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-not "exts|extu|and|movu" { xfail *-*-*} } } */ int test00 (char* a, char* b, int c, int d) diff --git a/gcc/testsuite/gfortran.dg/entry_20.f90 b/gcc/testsuite/gfortran.dg/entry_20.f90 new file mode 100644 index 00000000000..1069d1e3816 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/entry_20.f90 @@ -0,0 +1,148 @@ +! { dg-do compile } +! +! PR fortran/50898 +! A symbol was freed prematurely during resolution, +! despite remaining reachable +! +! Original testcase from <shaojuncycle@gmail.com> + +MODULE MODULE_pmat2 + +IMPLICIT NONE + +INTERFACE cad1b; MODULE PROCEDURE cad1b; END INTERFACE +INTERFACE csb1b; MODULE PROCEDURE csb1b; END INTERFACE +INTERFACE copbt; MODULE PROCEDURE copbt; END INTERFACE +INTERFACE conbt; MODULE PROCEDURE conbt; END INTERFACE +INTERFACE copmb; MODULE PROCEDURE copmb; END INTERFACE +INTERFACE conmb; MODULE PROCEDURE conmb; END INTERFACE +INTERFACE copbm; MODULE PROCEDURE copbm; END INTERFACE +INTERFACE conbm; MODULE PROCEDURE conbm; END INTERFACE +INTERFACE mulvb; MODULE PROCEDURE mulvb; END INTERFACE +INTERFACE madvb; MODULE PROCEDURE madvb; END INTERFACE +INTERFACE msbvb; MODULE PROCEDURE msbvb; END INTERFACE +INTERFACE mulxb; MODULE PROCEDURE mulxb; END INTERFACE +INTERFACE madxb; MODULE PROCEDURE madxb; END INTERFACE +INTERFACE msbxb; MODULE PROCEDURE msbxb; END INTERFACE + +integer, parameter :: i_kind=4 +integer, parameter :: r_kind=4 +real(r_kind), parameter :: zero=0.0 +real(r_kind), parameter :: one=1.0 +real(r_kind), parameter :: two=2.0 + +CONTAINS + +SUBROUTINE cad1b(a,m1,mah1,mah2,mirror2) +implicit none +INTEGER(i_kind), INTENT(IN ) :: m1,mah1,mah2,mirror2 +REAL(r_kind), INTENT(INOUT) :: a(0:m1-1,-mah1:mah2) +RETURN +ENTRY csb1b(a,m1,mah1,mah2,mirror2) +END SUBROUTINE cad1b + +SUBROUTINE copbt(a,b,m1,m2,mah1,mah2) +implicit none +INTEGER(i_kind), INTENT(IN ) :: m1, m2, mah1, mah2 +REAL(r_kind), INTENT(IN ) :: a(m1,-mah1:mah2) +REAL(r_kind), INTENT( OUT) :: b(m2,-mah2:mah1) +RETURN +ENTRY conbt(a,b,m1,m2,mah1,mah2) +END SUBROUTINE copbt + +SUBROUTINE copmb(afull,aband,m1,m2,mah1,mah2) +implicit none +INTEGER(i_kind), INTENT(IN ) :: m1, m2, mah1, mah2 +REAL(r_kind), DIMENSION(m1,m2), INTENT(IN ) :: afull +REAL(r_kind), DIMENSION(m1,-mah1:mah2),INTENT( OUT) :: aband +RETURN +ENTRY conmb(afull,aband,m1,m2,mah1,mah2) +END SUBROUTINE copmb + +SUBROUTINE copbm(aband,afull,m1,m2,mah1,mah2) +implicit none +INTEGER(i_kind), INTENT(IN ) :: m1, m2, mah1, mah2 +REAL(r_kind), DIMENSION(m1,-mah1:mah2),INTENT(IN ) :: aband +REAL(r_kind), DIMENSION(m1,m2), INTENT( OUT) :: afull +RETURN +ENTRY conbm(aband,afull,m1,m2,mah1,mah2) +END SUBROUTINE copbm + +SUBROUTINE mulbb(a,b,c,m1,m2,mah1,mah2,mbh1,mbh2,mch1,mch2) +implicit none +INTEGER(i_kind), INTENT(IN ) :: m1, m2, mah1, mah2, mbh1, mbh2, mch1, mch2 +REAL(r_kind), INTENT(IN ) :: a(m1,-mah1:mah2), b(m2,-mbh1:mbh2) +REAL(r_kind), INTENT(INOUT) :: c(m1,-mch1:mch2) +INTEGER(i_kind) :: nch1, nch2, j, k, jpk, i1,i2 +c=zero +ENTRY madbb(a,b,c,m1,m2,mah1,mah2,mbh1,mbh2,mch1,mch2) +nch1=mah1+mbh1; nch2=mah2+mbh2 +IF(nch1 /= mch1 .OR. nch2 /= mch2)STOP 'In MULBB, dimensions inconsistent' +DO j=-mah1,mah2 + DO k=-mbh1,mbh2; jpk=j+k; i1=MAX(1,1-j); i2=MIN(m1,m2-j) + c(i1:i2,jpk)=c(i1:i2,jpk)+a(i1:i2,j)*b(j+i1:j+i2,k) + ENDDO +ENDDO +END SUBROUTINE mulbb + +SUBROUTINE MULVB(v1,a,v2, m1,m2,mah1,mah2) +implicit none +INTEGER(i_kind), INTENT(IN ) :: m1, m2, mah1, mah2 +REAL(r_kind), INTENT(IN ) :: v1(m1), a(m1,-mah1:mah2) +REAL(r_kind), INTENT( OUT) :: v2(m2) +INTEGER(i_kind) :: j, i1,i2 +v2=zero +ENTRY madvb(v1,a,v2, m1,m2,mah1,mah2) +DO j=-mah1,mah2; i1=MAX(1,1-j); i2=MIN(m1,m2-j) + v2(j+i1:j+i2)=v2(j+i1:j+i2)+v1(i1:i2)*a(i1:i2,j) +ENDDO +RETURN +ENTRY msbvb(v1,a,v2, m1,m2,mah1,mah2) +DO j=-mah1,mah2; i1=MAX(1,1-j); i2=MIN(m1,m2-j) + v2(j+i1:j+i2)=v2(j+i1:j+i2)-v1(i1:i2)*a(i1:i2,j) +ENDDO +END SUBROUTINE mulvb + +SUBROUTINE mulxb(v1,a,v2, m1,m2,mah1,mah2,my) +implicit none +INTEGER(i_kind), INTENT(IN ) :: m1, m2, mah1, mah2, my +REAL(r_kind), INTENT(IN ) :: v1(m1,my), a(m1,-mah1:mah2) +REAL(r_kind), INTENT( OUT) :: v2(m2,my) +INTEGER(i_kind) :: i,j +v2=zero +ENTRY madxb(v1,a,v2, m1,m2,mah1,mah2,my) +DO j=-mah1,mah2 + DO i=MAX(1,1-j),MIN(m1,m2-j); v2(j+i,:)=v2(j+i,:)+v1(i,:)*a(i,j); ENDDO +ENDDO +RETURN +ENTRY msbxb(v1,a,v2, m1,m2,mah1,mah2,my) +DO j=-mah1,mah2 + DO i=MAX(1,1-j),MIN(m1,m2-j); v2(j+i,:)=v2(j+i,:)-v1(i,:)*a(i,j); ENDDO +ENDDO +END SUBROUTINE mulxb + +SUBROUTINE mulyb(v1,a,v2, m1,m2,mah1,mah2,mx) +implicit none +INTEGER(i_kind), INTENT(IN ) :: m1, m2, mah1, mah2, mx +REAL(r_kind), INTENT(IN ) :: v1(mx,m1), a(m1,-mah1:mah2) +REAL(r_kind), INTENT( OUT) :: v2(mx,m2) +INTEGER(i_kind) :: i,j +v2=zero +ENTRY madyb(v1,a,v2, m1,m2,mah1,mah2,mx) +DO j=-mah1,mah2 + DO i=MAX(1,1-j),MIN(m1,m2-j) + v2(:,j+i)=v2(:,j+i)+v1(:,i)*a(i,j) + ENDDO +ENDDO +RETURN +ENTRY msbyb(v1,a,v2, m1,m2,mah1,mah2,mx) + DO j=-mah1,mah2 + DO i=MAX(1,1-j),MIN(m1,m2-j) + v2(:,j+i)=v2(:,j+i)-v1(:,i)*a(i,j) + ENDDO + ENDDO +RETURN +END SUBROUTINE mulyb + +END MODULE MODULE_pmat2 + diff --git a/gcc/testsuite/gfortran.dg/pointer_remapping_9.f90 b/gcc/testsuite/gfortran.dg/pointer_remapping_9.f90 new file mode 100644 index 00000000000..7c1e2320b4b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pointer_remapping_9.f90 @@ -0,0 +1,31 @@ +! { dg-do run } +! +! PR fortran/61138 +! Wrong code with pointer-bounds remapping +! +! Contributed by Tobias Burnus <burnus@net-b.de> + +implicit none +integer, target :: tgt(10) +integer, target, allocatable :: tgt2(:) +integer, pointer :: ptr(:) + +tgt = [1,2,3,4,5,6,7,8,9,10] +tgt2 = [1,2,3,4,5,6,7,8,9,10] + + +ptr(-5:) => tgt(5:) ! Okay + +if (size(ptr) /= 6 .or. lbound(ptr,1) /= -5) call abort() +if (any (ptr /= [5,6,7,8,9,10])) call abort() + + +ptr(-5:) => tgt2(5:) ! wrongly associates the whole array + +print '(*(i4))', size(ptr), lbound(ptr) +print '(*(i4))', ptr + +if (size(ptr) /= 6 .or. lbound(ptr,1) /= -5) call abort() +if (any (ptr /= [5,6,7,8,9,10])) call abort() +end + diff --git a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_23.f90 b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_23.f90 new file mode 100644 index 00000000000..27eff310532 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_23.f90 @@ -0,0 +1,35 @@ +! {dg-do run } +! +! Test the fix for PR65024, in which the structure for the 'info' +! component of type 'T' was not being converted into TREE_SSA and +! so caused an ICE in trans-expr.c:gfc_conv_component_ref. +! +! Reported by <matt@gneilson.plus.com> +! +MODULE X + TYPE T + CLASS(*), pointer :: info + END TYPE +END MODULE + +PROGRAM P + call bug +CONTAINS + SUBROUTINE BUG + USE X + CLASS(T), pointer :: e + integer, target :: i = 42 + allocate(e) + e%info => NULL () ! used to ICE + if (.not.associated(e%info)) e%info => i ! used to ICE + select type (z => e%info) + type is (integer) + if (z .ne.i) call abort + end select + END SUBROUTINE + + SUBROUTINE NEXT + USE X + CLASS (T), pointer :: e + END SUBROUTINE +END diff --git a/gcc/testsuite/gfortran.dg/use_rename_8.f90 b/gcc/testsuite/gfortran.dg/use_rename_8.f90 new file mode 100644 index 00000000000..ad3ab3977c5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/use_rename_8.f90 @@ -0,0 +1,50 @@ +! { dg-do compile } +! +! PR fortran/63744 +! duplicate use rename used to be rejected when the target name +! was that of the current program unit +! +! Original testcase from Roger Ferrer Ibanez <roger.ferrer@bsc.es> + +MODULE MOO + INTEGER :: A, B, C, D, E, F, G, H, I +END MODULE MOO + +SUBROUTINE S + USE MOO, ONLY: X => A, X => A +END SUBROUTINE S + +SUBROUTINE T + USE MOO, ONLY: X => B + USE MOO, ONLY: X => B +END SUBROUTINE T + +SUBROUTINE C + USE MOO, ONLY: C ! { dg-error "is also the name of the current program unit" } +END SUBROUTINE C + +SUBROUTINE D + USE MOO, ONLY: X => D +END SUBROUTINE D + +SUBROUTINE E + USE MOO, ONLY: X => E, X => E +END SUBROUTINE E + +SUBROUTINE F + USE MOO, ONLY: X => F + USE MOO, ONLY: X => F +END SUBROUTINE F + +SUBROUTINE X + USE MOO, ONLY: X => G ! { dg-error "is also the name of the current program unit" } +END SUBROUTINE X + +SUBROUTINE Y + USE MOO, ONLY: Y => H ! { dg-error "is also the name of the current program unit" } +END SUBROUTINE Y + +SUBROUTINE Z + USE MOO, ONLY: Z => I, Z => I ! { dg-error "is also the name of the current program unit" } +END SUBROUTINE Z + diff --git a/gcc/testsuite/gfortran.dg/used_types_27.f90 b/gcc/testsuite/gfortran.dg/used_types_27.f90 new file mode 100644 index 00000000000..4797f855cac --- /dev/null +++ b/gcc/testsuite/gfortran.dg/used_types_27.f90 @@ -0,0 +1,18 @@ +! { dg-do compile } +! +! PR fortran/56674 +! PR fortran/58813 +! PR fortran/59016 +! PR fortran/59024 +! The generic name 'atomic_kind_types' was keeping pointers to freed +! symbols, leading to random error-recovery ICEs. +! +! Original test case from Joost VandeVondele <Joost.VandeVondele@mat.ethz.ch>. + +MODULE atomic_kind_types + PUBLIC :: atomic_kind_type +CONTAINS + INTEGER FUNCTION is_hydrogen(atomic_kind) + TYPE(atomic_kind_type), pointer :: atomic_kind ! { dg-error "used before it is defined" } + END FUNCTION +END MODULE diff --git a/gcc/testsuite/gfortran.dg/vect/pr32380.f b/gcc/testsuite/gfortran.dg/vect/pr32380.f index b7593807fa5..33c4eecdf58 100644 --- a/gcc/testsuite/gfortran.dg/vect/pr32380.f +++ b/gcc/testsuite/gfortran.dg/vect/pr32380.f @@ -259,5 +259,5 @@ c return end -! { dg-final { scan-tree-dump-times "vectorized 6 loops" 1 "vect" { xfail powerpc*-*-* ia64-*-*-* } } } +! { dg-final { scan-tree-dump-times "vectorized 6 loops" 1 "vect" { xfail { { powerpc*-*-* && { ! vect_hw_misalign } } || ia64-*-*-* } } } } ! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-2.f90 b/gcc/testsuite/gfortran.dg/vect/vect-2.f90 index 0f45a70c53b..b4358c81430 100644 --- a/gcc/testsuite/gfortran.dg/vect/vect-2.f90 +++ b/gcc/testsuite/gfortran.dg/vect/vect-2.f90 @@ -15,8 +15,8 @@ END ! support unaligned loads). ! { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } -! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail { vect_no_align || { ! vector_alignment_reachable } } } } } -! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { vect_no_align && { ! vector_alignment_reachable } } } } } -! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align } } } } -! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" {target { vect_no_align || { { ! vector_alignment_reachable } && { ! vect_hw_misalign } } } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || { ! vector_alignment_reachable } } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { { vect_no_align && { ! vect_hw_misalign } } && { ! vector_alignment_reachable } } } } } +! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" {target { { vect_no_align && { ! vect_hw_misalign } } || { { ! vector_alignment_reachable } && { ! vect_hw_misalign } } } } } } ! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-3.f90 b/gcc/testsuite/gfortran.dg/vect/vect-3.f90 index 5fc4fbf49e3..d70c6b4d1c1 100644 --- a/gcc/testsuite/gfortran.dg/vect/vect-3.f90 +++ b/gcc/testsuite/gfortran.dg/vect/vect-3.f90 @@ -6,10 +6,10 @@ DIMENSION X(N), Y(N) Y = Y + A * X END -! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target vect_no_align } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } ! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { {! vect_no_align} && { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } } ! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target { {! vect_no_align} && { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } } -! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable}} } } } -! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { { vect_no_align } || { ! vector_alignment_reachable} } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || {! vector_alignment_reachable}} } } } +! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || { ! vector_alignment_reachable} } } } } ! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-4.f90 b/gcc/testsuite/gfortran.dg/vect/vect-4.f90 index 592282fb09b..0d29852704f 100644 --- a/gcc/testsuite/gfortran.dg/vect/vect-4.f90 +++ b/gcc/testsuite/gfortran.dg/vect/vect-4.f90 @@ -10,8 +10,8 @@ Y = Y + A * X END ! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } -! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align } || {! vector_alignment_reachable} } } } } -! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { { vect_no_align } || {! vector_alignment_reachable} } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || {! vector_alignment_reachable} } } } } +! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || {! vector_alignment_reachable} } } } } ! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } ! { dg-final { scan-tree-dump-times "accesses have the same alignment." 1 "vect" } } ! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-5.f90 b/gcc/testsuite/gfortran.dg/vect/vect-5.f90 index 72776a6fb49..77ef77b09b6 100644 --- a/gcc/testsuite/gfortran.dg/vect/vect-5.f90 +++ b/gcc/testsuite/gfortran.dg/vect/vect-5.f90 @@ -36,8 +36,8 @@ end ! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } -! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } -! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } -! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target { vect_no_align } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align && { ! vect_hw_misalign } } || {! vector_alignment_reachable} } } } } +! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target { vect_no_align && { ! vect_hw_misalign } } } } } ! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } ! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gnat.dg/loop_optimization18.adb b/gcc/testsuite/gnat.dg/loop_optimization18.adb new file mode 100644 index 00000000000..eb4eeca32e2 --- /dev/null +++ b/gcc/testsuite/gnat.dg/loop_optimization18.adb @@ -0,0 +1,16 @@ +-- { dg-do compile } +-- { dg-options "-O3" } + +package body Loop_Optimization18 is + + procedure Proc (Message : Byte_Array_Type) is + + R : Rec (Conv (Message)); + + begin + for Division in 1 .. R.UB loop + R.L (Division) := 0; + end loop; + end; + +end Loop_Optimization18; diff --git a/gcc/testsuite/gnat.dg/loop_optimization18.ads b/gcc/testsuite/gnat.dg/loop_optimization18.ads new file mode 100644 index 00000000000..c9f3e2a1eb9 --- /dev/null +++ b/gcc/testsuite/gnat.dg/loop_optimization18.ads @@ -0,0 +1,7 @@ +with Loop_Optimization18_Pkg; use Loop_Optimization18_Pkg; + +package Loop_Optimization18 is + + procedure Proc (Message : Byte_Array_Type); + +end Loop_Optimization18; diff --git a/gcc/testsuite/gnat.dg/loop_optimization18_pkg.ads b/gcc/testsuite/gnat.dg/loop_optimization18_pkg.ads new file mode 100644 index 00000000000..9fb3311ca03 --- /dev/null +++ b/gcc/testsuite/gnat.dg/loop_optimization18_pkg.ads @@ -0,0 +1,15 @@ +with Unchecked_Conversion; + +package Loop_Optimization18_Pkg is + + type Arr is array (Integer range <>) of Natural; + + type Rec (UB : Integer) is record + L : Arr (1 .. UB); + end record; + + type Byte_Array_Type is new String (1..4); + + function Conv is new Unchecked_Conversion (Byte_Array_Type, Integer); + +end Loop_Optimization18_Pkg; diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index f8e633744b8..3527e976430 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3835,6 +3835,7 @@ proc check_effective_target_vect_no_align { } { || [istarget sparc*-*-*] || [istarget ia64-*-*] || [check_effective_target_arm_vect_no_misalign] + || ([istarget powerpc*-*-*] && [check_p8vector_hw_available]) || ([istarget mips*-*-*] && [check_effective_target_mips_loongson]) } { set et_vect_no_align_saved 1 @@ -3856,8 +3857,9 @@ proc check_effective_target_vect_hw_misalign { } { } else { set et_vect_hw_misalign_saved 0 if { ([istarget x86_64-*-*] - || [istarget aarch64*-*-*] - || [istarget i?86-*-*]) } { + || ([istarget powerpc*-*-*] && [check_p8vector_hw_available]) + || [istarget aarch64*-*-*] + || [istarget i?86-*-*]) } { set et_vect_hw_misalign_saved 1 } } @@ -5395,7 +5397,7 @@ proc check_vect_support_and_set_flags { } { lappend DEFAULT_VECTCFLAGS "-maltivec" if [check_p8vector_hw_available] { - lappend DEFAULT_VECTCFLAGS "-mpower8-vector" "-mno-allow-movmisalign" + lappend DEFAULT_VECTCFLAGS "-mpower8-vector" } elseif [check_vsx_hw_available] { lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign" } diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 73a7a26c9dd..4bc85e46df8 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1666,9 +1666,8 @@ execute_pred_commoning_chain (struct loop *loop, chain_p chain, if (chain->combined) { /* For combined chains, just remove the statements that are used to - compute the values of the expression (except for the root one). */ - for (i = 1; chain->refs.iterate (i, &a); i++) - remove_stmt (a->stmt); + compute the values of the expression (except for the root one). + We delay this until after all chains are processed. */ } else { @@ -1697,9 +1696,21 @@ determine_unroll_factor (vec<chain_p> chains) FOR_EACH_VEC_ELT (chains, i, chain) { - if (chain->type == CT_INVARIANT || chain->combined) + if (chain->type == CT_INVARIANT) continue; + if (chain->combined) + { + /* For combined chains, we can't handle unrolling if we replace + looparound PHIs. */ + dref a; + unsigned j; + for (j = 1; chain->refs.iterate (j, &a); j++) + if (gimple_code (a->stmt) == GIMPLE_PHI) + return 1; + continue; + } + /* The best unroll factor for this chain is equal to the number of temporary variables that we create for it. */ af = chain->length; @@ -1732,6 +1743,21 @@ execute_pred_commoning (struct loop *loop, vec<chain_p> chains, execute_pred_commoning_chain (loop, chain, tmp_vars); } + FOR_EACH_VEC_ELT (chains, i, chain) + { + if (chain->type == CT_INVARIANT) + ; + else if (chain->combined) + { + /* For combined chains, just remove the statements that are used to + compute the values of the expression (except for the root one). */ + dref a; + unsigned j; + for (j = 1; chain->refs.iterate (j, &a); j++) + remove_stmt (a->stmt); + } + } + update_ssa (TODO_update_ssa_only_virtuals); } diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c index 3f35657e398..46a14bc5c7b 100644 --- a/gcc/tree-ssa-tail-merge.c +++ b/gcc/tree-ssa-tail-merge.c @@ -550,7 +550,7 @@ same_succ_def::equal (const value_type *e1, const compare_type *e2) if (!inverse_flags (e1, e2)) { for (i = 0; i < e1->succ_flags.length (); ++i) - if (e1->succ_flags[i] != e1->succ_flags[i]) + if (e1->succ_flags[i] != e2->succ_flags[i]) return 0; } diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c index 8ad9fc2d22e..d6f81a104ed 100644 --- a/gcc/tree-stdarg.c +++ b/gcc/tree-stdarg.c @@ -809,21 +809,22 @@ execute_optimize_stdarg (void) /* For va_list_simple_ptr, we have to check PHI nodes too. We treat them as assignments for the purpose of escape analysis. This is not needed for non-simple va_list because virtual phis don't perform - any real data movement. */ - if (va_list_simple_ptr) - { - tree lhs, rhs; - use_operand_p uop; - ssa_op_iter soi; + any real data movement. Also, check PHI nodes for taking address of + the va_list vars. */ + tree lhs, rhs; + use_operand_p uop; + ssa_op_iter soi; - for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) - { - gimple phi = gsi_stmt (i); - lhs = PHI_RESULT (phi); + for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) + { + gimple phi = gsi_stmt (i); + lhs = PHI_RESULT (phi); - if (virtual_operand_p (lhs)) - continue; + if (virtual_operand_p (lhs)) + continue; + if (va_list_simple_ptr) + { FOR_EACH_PHI_ARG (uop, phi, soi, SSA_OP_USE) { rhs = USE_FROM_PTR (uop); @@ -846,6 +847,22 @@ execute_optimize_stdarg (void) } } } + + for (unsigned j = 0; !va_list_escapes + && j < gimple_phi_num_args (phi); ++j) + if ((!va_list_simple_ptr + || TREE_CODE (gimple_phi_arg_def (phi, j)) != SSA_NAME) + && walk_tree (gimple_phi_arg_def_ptr (phi, j), + find_va_list_reference, &wi, NULL)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fputs ("va_list escapes in ", dump_file); + print_gimple_stmt (dump_file, phi, 0, dump_flags); + fputc ('\n', dump_file); + } + va_list_escapes = true; + } } for (i = gsi_start_bb (bb); @@ -868,8 +885,8 @@ execute_optimize_stdarg (void) if (is_gimple_assign (stmt)) { - tree lhs = gimple_assign_lhs (stmt); - tree rhs = gimple_assign_rhs1 (stmt); + lhs = gimple_assign_lhs (stmt); + rhs = gimple_assign_rhs1 (stmt); if (va_list_simple_ptr) { diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 1c6cb5838a0..065b92c6a05 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -4362,7 +4362,10 @@ vect_finalize_reduction: && !STMT_VINFO_LIVE_P (exit_phi_vinfo)) || double_reduc); - STMT_VINFO_VEC_STMT (exit_phi_vinfo) = epilog_stmt; + if (double_reduc) + STMT_VINFO_VEC_STMT (exit_phi_vinfo) = inner_phi; + else + STMT_VINFO_VEC_STMT (exit_phi_vinfo) = epilog_stmt; if (!double_reduc || STMT_VINFO_DEF_TYPE (exit_phi_vinfo) != vect_double_reduction_def) diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index b29fbd15b78..8bdf265868c 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -1805,51 +1805,83 @@ vect_make_slp_decision (loop_vec_info loop_vinfo) can't be SLPed) in the tree rooted at NODE. Mark such stmts as HYBRID. */ static void -vect_detect_hybrid_slp_stmts (slp_tree node) +vect_detect_hybrid_slp_stmts (slp_tree node, unsigned i, slp_vect_type stype) { - int i; - vec<gimple> stmts = SLP_TREE_SCALAR_STMTS (node); - gimple stmt = stmts[0]; + gimple stmt = SLP_TREE_SCALAR_STMTS (node)[i]; imm_use_iterator imm_iter; gimple use_stmt; - stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); + stmt_vec_info use_vinfo, stmt_vinfo = vinfo_for_stmt (stmt); slp_void_p child; loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); - struct loop *loop = NULL; - bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo); - basic_block bb = NULL; + struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); + int j; + + /* Propagate hybrid down the SLP tree. */ + if (stype == hybrid) + ; + else if (HYBRID_SLP_STMT (stmt_vinfo)) + stype = hybrid; + else + { + /* Check if a pure SLP stmt has uses in non-SLP stmts. */ + gcc_checking_assert (PURE_SLP_STMT (stmt_vinfo)); + if (TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME) + FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, gimple_op (stmt, 0)) + if (gimple_bb (use_stmt) + && flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)) + && (use_vinfo = vinfo_for_stmt (use_stmt)) + && !STMT_SLP_TYPE (use_vinfo) + && (STMT_VINFO_RELEVANT (use_vinfo) + || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (use_vinfo)) + || (STMT_VINFO_IN_PATTERN_P (use_vinfo) + && STMT_VINFO_RELATED_STMT (use_vinfo) + && !STMT_SLP_TYPE (vinfo_for_stmt + (STMT_VINFO_RELATED_STMT (use_vinfo))))) + && !(gimple_code (use_stmt) == GIMPLE_PHI + && STMT_VINFO_DEF_TYPE (use_vinfo) == vect_reduction_def)) + stype = hybrid; + } + + if (stype == hybrid) + STMT_SLP_TYPE (stmt_vinfo) = hybrid; + + FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) + vect_detect_hybrid_slp_stmts ((slp_tree) child, i, stype); +} - if (!node) - return; +/* Helpers for vect_detect_hybrid_slp walking pattern stmt uses. */ - if (loop_vinfo) - loop = LOOP_VINFO_LOOP (loop_vinfo); - else - bb = BB_VINFO_BB (bb_vinfo); +static tree +vect_detect_hybrid_slp_1 (tree *tp, int *, void *data) +{ + walk_stmt_info *wi = (walk_stmt_info *)data; + struct loop *loopp = (struct loop *)wi->info; - FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt) - if (PURE_SLP_STMT (vinfo_for_stmt (stmt)) - && TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME) - FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, gimple_op (stmt, 0)) - if (gimple_bb (use_stmt) - && ((loop && flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) - || bb == gimple_bb (use_stmt)) - && (stmt_vinfo = vinfo_for_stmt (use_stmt)) - && !STMT_SLP_TYPE (stmt_vinfo) - && (STMT_VINFO_RELEVANT (stmt_vinfo) - || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_vinfo)) - || (STMT_VINFO_IN_PATTERN_P (stmt_vinfo) - && STMT_VINFO_RELATED_STMT (stmt_vinfo) - && !STMT_SLP_TYPE (vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_vinfo))))) - && !(gimple_code (use_stmt) == GIMPLE_PHI - && STMT_VINFO_DEF_TYPE (stmt_vinfo) - == vect_reduction_def)) - vect_mark_slp_stmts (node, hybrid, i); + if (wi->is_lhs) + return NULL_TREE; - FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child) - vect_detect_hybrid_slp_stmts ((slp_tree) child); + if (TREE_CODE (*tp) == SSA_NAME + && !SSA_NAME_IS_DEFAULT_DEF (*tp)) + { + gimple def_stmt = SSA_NAME_DEF_STMT (*tp); + if (flow_bb_inside_loop_p (loopp, gimple_bb (def_stmt)) + && PURE_SLP_STMT (vinfo_for_stmt (def_stmt))) + STMT_SLP_TYPE (vinfo_for_stmt (def_stmt)) = hybrid; + } + + return NULL_TREE; } +static tree +vect_detect_hybrid_slp_2 (gimple_stmt_iterator *gsi, bool *handled, + walk_stmt_info *) +{ + /* If the stmt is in a SLP instance then this isn't a reason + to mark use definitions in other SLP instances as hybrid. */ + if (STMT_SLP_TYPE (vinfo_for_stmt (gsi_stmt (*gsi))) != loop_vect) + *handled = true; + return NULL_TREE; +} /* Find stmts that must be both vectorized and SLPed. */ @@ -1863,8 +1895,41 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "=== vect_detect_hybrid_slp ==="); + /* First walk all pattern stmt in the loop and mark defs of uses as + hybrid because immediate uses in them are not recorded. */ + for (i = 0; i < LOOP_VINFO_LOOP (loop_vinfo)->num_nodes; ++i) + { + basic_block bb = LOOP_VINFO_BBS (loop_vinfo)[i]; + for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); + gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + stmt_vec_info stmt_info = vinfo_for_stmt (stmt); + if (STMT_VINFO_IN_PATTERN_P (stmt_info)) + { + walk_stmt_info wi; + memset (&wi, 0, sizeof (wi)); + wi.info = LOOP_VINFO_LOOP (loop_vinfo); + gimple_stmt_iterator gsi2 + = gsi_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info)); + walk_gimple_stmt (&gsi2, vect_detect_hybrid_slp_2, + vect_detect_hybrid_slp_1, &wi); + walk_gimple_seq (STMT_VINFO_PATTERN_DEF_SEQ (stmt_info), + vect_detect_hybrid_slp_2, + vect_detect_hybrid_slp_1, &wi); + } + } + } + + /* Then walk the SLP instance trees marking stmts with uses in + non-SLP stmts as hybrid, also propagating hybrid down the + SLP tree, collecting the above info on-the-fly. */ FOR_EACH_VEC_ELT (slp_instances, i, instance) - vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance)); + { + for (unsigned i = 0; i < SLP_INSTANCE_GROUP_SIZE (instance); ++i) + vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance), + i, pure_slp); + } } diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 6363e453822..ece180c175e 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -9211,7 +9211,7 @@ vrp_finalize (void) substitute_and_fold (op_with_constant_singleton_value_range, vrp_fold_stmt, false); - if (warn_array_bounds) + if (warn_array_bounds && first_pass_instance) check_all_array_refs (); /* We must identify jump threading opportunities before we release diff --git a/gcc/varasm.c b/gcc/varasm.c index ea709fd8eeb..eb406b7cc96 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -91,11 +91,6 @@ tree last_assemble_variable_decl; bool first_function_block_is_cold; -/* We give all constants their own alias set. Perhaps redundant with - MEM_READONLY_P, but pre-dates it. */ - -static alias_set_type const_alias_set; - /* Whether we saw any functions with no_split_stack. */ static bool saw_no_split_stack; @@ -3139,7 +3134,6 @@ build_constant_desc (tree exp) rtl = gen_const_mem (TYPE_MODE (TREE_TYPE (exp)), symbol); set_mem_attributes (rtl, exp, 1); set_mem_alias_set (rtl, 0); - set_mem_alias_set (rtl, const_alias_set); /* We cannot share RTX'es in pool entries. Mark this piece of RTL as required for unsharing. */ @@ -5865,7 +5859,6 @@ init_varasm_once (void) const_desc_htab = htab_create_ggc (1009, const_desc_hash, const_desc_eq, NULL); - const_alias_set = new_alias_set (); shared_constant_pool = create_constant_pool (); #ifdef TEXT_SECTION_ASM_OP @@ -6858,7 +6851,13 @@ default_file_start (void) fputs (ASM_APP_OFF, asm_out_file); if (targetm.asm_file_start_file_directive) - output_file_directive (asm_out_file, main_input_filename); + { + /* LTO produced units have no meaningful main_input_filename. */ + if (in_lto_p) + output_file_directive (asm_out_file, "<artificial>"); + else + output_file_directive (asm_out_file, main_input_filename); + } } /* This is a generic routine suitable for use as TARGET_ASM_FILE_END diff --git a/gcc/web.c b/gcc/web.c index d09d1d51f72..605f05c906c 100644 --- a/gcc/web.c +++ b/gcc/web.c @@ -53,17 +53,17 @@ along with GCC; see the file COPYING3. If not see /* Find the root of unionfind tree (the representative of set). */ -struct web_entry * -unionfind_root (struct web_entry *element) +web_entry_base * +web_entry_base::unionfind_root () { - struct web_entry *element1 = element, *element2; + web_entry_base *element = this, *element1 = this, *element2; - while (element->pred) - element = element->pred; - while (element1->pred) + while (element->pred ()) + element = element->pred (); + while (element1->pred ()) { - element2 = element1->pred; - element1->pred = element; + element2 = element1->pred (); + element1->set_pred (element); element1 = element2; } return element; @@ -74,23 +74,32 @@ unionfind_root (struct web_entry *element) nothing is done. Otherwise, return false. */ bool -unionfind_union (struct web_entry *first, struct web_entry *second) +unionfind_union (web_entry_base *first, web_entry_base *second) { - first = unionfind_root (first); - second = unionfind_root (second); + first = first->unionfind_root (); + second = second->unionfind_root (); if (first == second) return true; - second->pred = first; + second->set_pred (first); return false; } +class web_entry : public web_entry_base +{ + private: + rtx reg_pvt; + + public: + rtx reg () { return reg_pvt; } + void set_reg (rtx r) { reg_pvt = r; } +}; + /* For INSN, union all defs and uses that are linked by match_dup. FUN is the function that does the union. */ static void -union_match_dups (rtx insn, struct web_entry *def_entry, - struct web_entry *use_entry, - bool (*fun) (struct web_entry *, struct web_entry *)) +union_match_dups (rtx insn, web_entry *def_entry, web_entry *use_entry, + bool (*fun) (web_entry_base *, web_entry_base *)) { struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); df_ref *use_link = DF_INSN_INFO_USES (insn_info); @@ -157,9 +166,9 @@ union_match_dups (rtx insn, struct web_entry *def_entry, the values 0 and 1 are reserved for use by entry_register. */ void -union_defs (df_ref use, struct web_entry *def_entry, - unsigned int *used, struct web_entry *use_entry, - bool (*fun) (struct web_entry *, struct web_entry *)) +union_defs (df_ref use, web_entry *def_entry, + unsigned int *used, web_entry *use_entry, + bool (*fun) (web_entry_base *, web_entry_base *)) { struct df_insn_info *insn_info = DF_REF_INSN_INFO (use); struct df_link *link = DF_REF_CHAIN (use); @@ -260,15 +269,15 @@ union_defs (df_ref use, struct web_entry *def_entry, /* Find the corresponding register for the given entry. */ static rtx -entry_register (struct web_entry *entry, df_ref ref, unsigned int *used) +entry_register (web_entry *entry, df_ref ref, unsigned int *used) { - struct web_entry *root; + web_entry *root; rtx reg, newreg; /* Find the corresponding web and see if it has been visited. */ - root = unionfind_root (entry); - if (root->reg) - return root->reg; + root = (web_entry *)entry->unionfind_root (); + if (root->reg ()) + return root->reg (); /* We are seeing this web for the first time, do the assignment. */ reg = DF_REF_REAL_REG (ref); @@ -292,7 +301,7 @@ entry_register (struct web_entry *entry, df_ref ref, unsigned int *used) REGNO (newreg)); } - root->reg = newreg; + root->set_reg (newreg); return newreg; } @@ -326,8 +335,8 @@ gate_handle_web (void) static unsigned int web_main (void) { - struct web_entry *def_entry; - struct web_entry *use_entry; + web_entry *def_entry; + web_entry *use_entry; unsigned int max = max_reg_num (); unsigned int *used; basic_block bb; @@ -364,9 +373,9 @@ web_main (void) } /* Record the number of uses and defs at the beginning of the optimization. */ - def_entry = XCNEWVEC (struct web_entry, DF_DEFS_TABLE_SIZE()); + def_entry = XCNEWVEC (web_entry, DF_DEFS_TABLE_SIZE()); used = XCNEWVEC (unsigned, max); - use_entry = XCNEWVEC (struct web_entry, uses_num); + use_entry = XCNEWVEC (web_entry, uses_num); /* Produce the web. */ FOR_ALL_BB (bb) diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index c2995c3b7af..7efaf4f2efa 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,15 @@ +2015-02-17 Sandra Loosemore <sandra@codesourcery.com> + + Backported from mainline + 2015-02-17 Sandra Loosemore <sandra@codesourcery.com> + + * config/arm/bpabi.S (test_div_by_zero): Make label names + consistent between thumb2 and arm mode cases. Separate the + signed comparison on the high word of the numerator from the + unsigned comparison on the low word. + * config/arm/bpabi-v6m.S (test_div_by_zero): Similarly separate + signed comparison. + 2014-12-19 Release Manager * GCC 4.8.4 released. diff --git a/libgcc/config/arm/bpabi-v6m.S b/libgcc/config/arm/bpabi-v6m.S index 2ad8f037482..6da3682a48e 100644 --- a/libgcc/config/arm/bpabi-v6m.S +++ b/libgcc/config/arm/bpabi-v6m.S @@ -85,19 +85,21 @@ FUNC_START aeabi_ulcmp cmp yyl, #0 bne 7f cmp xxh, #0 + .ifc \signed, unsigned bne 2f cmp xxl, #0 2: - .ifc \signed, unsigned beq 3f mov xxh, #0 mvn xxh, xxh @ 0xffffffff mov xxl, xxh 3: .else - beq 5f blt 6f - mov xxl, #0 + bgt 4f + cmp xxl, #0 + beq 5f +4: mov xxl, #0 mvn xxl, xxl @ 0xffffffff lsr xxh, xxl, #1 @ 0x7fffffff b 5f diff --git a/libgcc/config/arm/bpabi.S b/libgcc/config/arm/bpabi.S index d3493b357ca..99df4a720b5 100644 --- a/libgcc/config/arm/bpabi.S +++ b/libgcc/config/arm/bpabi.S @@ -78,26 +78,29 @@ ARM_FUNC_START aeabi_ulcmp /* Tail-call to divide-by-zero handlers which may be overridden by the user, so unwinding works properly. */ #if defined(__thumb2__) - cbnz yyh, 1f - cbnz yyl, 1f + cbnz yyh, 2f + cbnz yyl, 2f cmp xxh, #0 + .ifc \signed, unsigned do_it eq cmpeq xxl, #0 - .ifc \signed, unsigned - beq 2f - mov xxh, #0xffffffff - mov xxl, xxh -2: + do_it ne, t + movne xxh, #0xffffffff + movne xxl, #0xffffffff .else - do_it lt, t + do_it lt, tt movlt xxl, #0 movlt xxh, #0x80000000 - do_it gt, t - movgt xxh, #0x7fffffff - movgt xxl, #0xffffffff + blt 1f + do_it eq + cmpeq xxl, #0 + do_it ne, t + movne xxh, #0x7fffffff + movne xxl, #0xffffffff .endif +1: b SYM (__aeabi_ldiv0) __PLT__ -1: +2: #else /* Note: Thumb-1 code calls via an ARM shim on processors which support ARM mode. */ @@ -105,16 +108,19 @@ ARM_FUNC_START aeabi_ulcmp cmpeq yyl, #0 bne 2f cmp xxh, #0 - cmpeq xxl, #0 .ifc \signed, unsigned + cmpeq xxl, #0 movne xxh, #0xffffffff movne xxl, #0xffffffff .else movlt xxh, #0x80000000 movlt xxl, #0 - movgt xxh, #0x7fffffff - movgt xxl, #0xffffffff + blt 1f + cmpeq xxl, #0 + movne xxh, #0x7fffffff + movne xxl, #0xffffffff .endif +1: b SYM (__aeabi_ldiv0) __PLT__ 2: #endif diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index bfa4927652f..184bf3d8092 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,21 @@ +2015-03-30 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libgfortran/59513 + * io/transfer.c (data_transfer_init): Do not error for + -std=legacy. + +2015-03-22 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libgfortran/60956 + Backport from mainline + * io/fbuf.c (fbuf_flush_list): New function that only flushes + if current fbuf position exceeds a limit. + * io/fbuf.h: Declare the new function. + * io/io.h (enum unit_mode): Add two new modes. + * io/list_read.c (list_formatted_read_scalar): Call new function. + * io/write.c: Include fbuf.h. (list_formatted_write_scalar): + Call new function. + 2014-12-19 Release Manager * GCC 4.8.4 released. diff --git a/libgfortran/io/fbuf.c b/libgfortran/io/fbuf.c index ace990db821..4d48cc9fb40 100644 --- a/libgfortran/io/fbuf.c +++ b/libgfortran/io/fbuf.c @@ -174,6 +174,42 @@ fbuf_flush (gfc_unit * u, unit_mode mode) } +/* The mode argument is LIST_WRITING for write mode and LIST_READING for + read. This should only be used for list directed I/O. + Return value is 0 for success, -1 on failure. */ + +int +fbuf_flush_list (gfc_unit * u, unit_mode mode) +{ + int nwritten; + + if (!u->fbuf) + return 0; + + if (u->fbuf->pos < 524288) /* Upper limit for list writing. */ + return 0; + + fbuf_debug (u, "fbuf_flush_list with mode %d: ", mode); + + if (mode == LIST_WRITING) + { + nwritten = swrite (u->s, u->fbuf->buf, u->fbuf->pos); + if (nwritten < 0) + return -1; + } + + /* Salvage remaining bytes for both reading and writing. */ + if (u->fbuf->act > u->fbuf->pos) + memmove (u->fbuf->buf, u->fbuf->buf + u->fbuf->pos, + u->fbuf->act - u->fbuf->pos); + + u->fbuf->act -= u->fbuf->pos; + u->fbuf->pos = 0; + + return 0; +} + + int fbuf_seek (gfc_unit * u, int off, int whence) { diff --git a/libgfortran/io/fbuf.h b/libgfortran/io/fbuf.h index d125a2cf6e1..64cf0430fad 100644 --- a/libgfortran/io/fbuf.h +++ b/libgfortran/io/fbuf.h @@ -59,6 +59,9 @@ internal_proto(fbuf_alloc); extern int fbuf_flush (gfc_unit *, unit_mode); internal_proto(fbuf_flush); +extern int fbuf_flush_list (gfc_unit *, unit_mode); +internal_proto(fbuf_flush_list); + extern int fbuf_seek (gfc_unit *, int, int); internal_proto(fbuf_seek); diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 10f09855f1f..e78f3151bbd 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -201,7 +201,7 @@ typedef enum unit_advance; typedef enum -{READING, WRITING} +{READING, WRITING, LIST_READING, LIST_WRITING} unit_mode; typedef enum diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index 3c766d7c780..2b80838fc9f 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -2001,6 +2001,7 @@ cleanup: free_line (dtp); hit_eof (dtp); } + fbuf_flush_list (dtp->u.p.current_unit, LIST_READING); return err; } diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 2e11727d1a3..87c67bf6a3d 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -2529,15 +2529,16 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag) return; } - if (dtp->u.p.current_unit->endfile == AFTER_ENDFILE) - { + if (compile_options.warn_std && + dtp->u.p.current_unit->endfile == AFTER_ENDFILE) + { generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT, "Sequential READ or WRITE not allowed after " "EOF marker, possibly use REWIND or BACKSPACE"); return; } - } + /* Process the ADVANCE option. */ dtp->u.p.advance_status diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c index a3c78ce7c6f..4ef5586a657 100644 --- a/libgfortran/io/write.c +++ b/libgfortran/io/write.c @@ -25,6 +25,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #include "io.h" +#include "fbuf.h" #include "format.h" #include "unix.h" #include <assert.h> @@ -1577,6 +1578,7 @@ list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind, internal_error (&dtp->common, "list_formatted_write(): Bad type"); } + fbuf_flush_list (dtp->u.p.current_unit, LIST_WRITING); dtp->u.p.char_flag = (type == BT_CHARACTER); } diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b266521bc95..a62ea728a99 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2015-03-25 Jonathan Wakely <jwakely@redhat.com> + + Backport from mainline + 2015-03-02 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/65279 + * include/std/scoped_allocator (__inner_type_impl, + scoped_allocator_adaptor): Add defaulted copy assignment and move + assignment operators. + * testsuite/20_util/scoped_allocator/65279.cc: New. + +2015-03-25 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/65543 + * include/std/istream (operator>>(basic_istream<>&&, _Tp&): Revert + thinko in r150387. + * include/std/ostream (operator<<(basic_ostream<>&&, const _Tp&): + Likewise. + * testsuite/27_io/rvalue_streams-2.cc: New. + 2015-01-09 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/60966 diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream index 861bca53adf..6e72c94e069 100644 --- a/libstdc++-v3/include/std/istream +++ b/libstdc++-v3/include/std/istream @@ -870,7 +870,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits, typename _Tp> inline basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x) - { return (__is >> __x); } + { + __is >> __x; + return __is; + } #endif // C++11 _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index e466b54e78a..f3581b8bb11 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -600,7 +600,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits, typename _Tp> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x) - { return (__os << __x); } + { + __os << __x; + return __os; + } #endif // C++11 _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/scoped_allocator b/libstdc++-v3/include/std/scoped_allocator index eeb1935eea6..0849cbb134e 100644 --- a/libstdc++-v3/include/std/scoped_allocator +++ b/libstdc++-v3/include/std/scoped_allocator @@ -105,6 +105,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __inner_type_impl() = default; __inner_type_impl(const __inner_type_impl&) = default; __inner_type_impl(__inner_type_impl&&) = default; + __inner_type_impl& operator=(const __inner_type_impl&) = default; + __inner_type_impl& operator=(__inner_type_impl&&) = default; template<typename _Alloc> __inner_type_impl(const __inner_type_impl<_Alloc>& __other) @@ -136,6 +138,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __inner_type_impl() = default; __inner_type_impl(const __inner_type_impl&) = default; __inner_type_impl(__inner_type_impl&&) = default; + __inner_type_impl& operator=(const __inner_type_impl&) = default; + __inner_type_impl& operator=(__inner_type_impl&&) = default; template<typename... _Allocs> __inner_type_impl(const __inner_type_impl<_Allocs...>& __other) @@ -310,6 +314,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_inner(std::move(__other._M_inner)) { } + scoped_allocator_adaptor& + operator=(const scoped_allocator_adaptor&) = default; + + scoped_allocator_adaptor& + operator=(scoped_allocator_adaptor&&) = default; + inner_allocator_type& inner_allocator() noexcept { return _M_inner._M_get(this); } diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/65279.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/65279.cc new file mode 100644 index 00000000000..786d4031cdb --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/65279.cc @@ -0,0 +1,54 @@ +// Copyright (C) 2015 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include <memory> +#include <type_traits> +#include <scoped_allocator> + +template<typename T> + struct Allocator : std::allocator<T> + { + template<typename U> + struct rebind { using other = Allocator<U>; }; + + using propagate_on_container_copy_assignment = std::true_type; + using propagate_on_container_move_assignment = std::true_type; + }; + +template<typename... T> + using alloc = std::scoped_allocator_adaptor<Allocator<T>...>; + +void +test01() +{ + // Test partial specialization for sizeof...(InnerAlloc) == 0 + alloc<int> a; + a = a; + a = std::move(a); +} + +void +test02() +{ + // Test partial specialization for sizeof...(InnerAlloc) >= 1 + alloc<int, char> a; + a = a; + a = std::move(a); +} diff --git a/libstdc++-v3/testsuite/27_io/rvalue_streams-2.cc b/libstdc++-v3/testsuite/27_io/rvalue_streams-2.cc new file mode 100644 index 00000000000..d9b61464b58 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/rvalue_streams-2.cc @@ -0,0 +1,35 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2015 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <sstream> + +struct A {}; + +void operator<<(std::ostream&, const A&) { } +void operator>>(std::istream&, A&) { } + +// PR libstdc++/65543 +int main() +{ + A a; + + std::ostringstream() << a; + std::istringstream() >> a; +} |