diff options
author | yroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-09-09 11:55:59 +0000 |
---|---|---|
committer | yroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-09-09 11:55:59 +0000 |
commit | ed8ed458cbe365cc1ad88c09f4a02bc24c0b1cef (patch) | |
tree | 74fc6192e0a1ecfa8b0e389cc1dab13806f1d921 | |
parent | 5d3882b936046af384ab4aeb5eeb535a19911de7 (diff) | |
download | linaro-gcc-ed8ed458cbe365cc1ad88c09f4a02bc24c0b1cef.tar.gz linaro-gcc-ed8ed458cbe365cc1ad88c09f4a02bc24c0b1cef.tar.bz2 linaro-gcc-ed8ed458cbe365cc1ad88c09f4a02bc24c0b1cef.zip |
Merge branches/gcc-4_9-branch rev 214896
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@215060 138bc75d-0d04-0410-961f-82ee72b054a4
134 files changed, 2821 insertions, 569 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index de2ef232724..fabb693341c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,431 @@ +2014-09-03 Martin Jambor <mjambor@suse.cz> + + PR ipa/62015 + * ipa-cp.c (intersect_aggregates_with_edge): Handle impermissible + pass-trough jump functions correctly. + +2014-09-03 Martin Jambor <mjambor@suse.cz> + + PR ipa/61986 + * ipa-cp.c (find_aggregate_values_for_callers_subset): Chain + created replacements in ascending order of offsets. + (known_aggs_to_agg_replacement_list): Likewise. + +2014-09-02 Kaz Kojima <kkojima@gcc.gnu.org> + + Backport from mainline + 2014-08-27 Kaz Kojima <kkojima@gcc.gnu.org> + + PR target/62261 + * config/sh/sh.md (ashlsi3): Handle negative shift count for + TARGET_SHMEDIA. + (ashldi3, ashrsi3, ashrdi3, lshrsi3, lshrdi3): Likewise. + +2014-09-02 Kaz Kojima <kkojima@gcc.gnu.org> + + Backport from mainline + 2014-08-25 Kaz Kojima <kkojima@gcc.gnu.org> + + PR target/62111 + * config/sh/predicates.md (general_extend_operand): Disable + TRUNCATE before reload completes. + +2014-09-01 Oleg Endo <olegendo@gcc.gnu.org> + + Backport from mainline + 2014-09-01 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/62312 + * config/sh/sh.md (*cmp_div0s_0): Add missing constraints. + +2014-09-01 Jakub Jelinek <jakub@redhat.com> + + PR target/62025 + * sched-deps.c (add_or_update_dep_1): If ask_dependency_caches + returned DEP_PRESENT, make sure to set DEP_MULTIPLE on present_dep. + (find_inc): Revert 2014-08-12 change. + + * config/gnu-user.h (LIBLSAN_EARLY_SPEC): Define. + * gcc.c (LIBLSAN_SPEC, LIBLSAN_EARLY_SPEC): Follow LIBTSAN*_SPEC. + (SANITIZER_EARLY_SPEC): Include LIBLSAN_EARLY_SPEC for -fsanitize=leak. + +2014-09-01 Marek Polacek <polacek@redhat.com> + + Backport from mainline + 2014-08-21 Marek Polacek <polacek@redhat.com> + + PR c/61271 + * expr.c (is_aligning_offset): Remove logical not. + +2014-09-01 Marek Polacek <polacek@redhat.com> + + Backport from mainline + 2014-08-19 Marek Polacek <polacek@redhat.com> + + PR c/61271 + * cgraphunit.c (handle_alias_pairs): Fix condition. + +2014-08-30 John David Anglin <danglin@gcc.gnu.org> + + * config/pa/pa.c (pa_assemble_integer): Don't add PLABEL relocation + prefix to function labels when generating fast indirect calls. + +2014-08-29 Yvan Roux <yvan.roux@linaro.org> + + Backport from mainline + 2014-08-27 Yvan Roux <yvan.roux@linaro.org> + + PR other/62248 + * config.gcc (arm*-*-*): Check --with-fpu against arm-fpus.def. + +2014-08-27 Guozhi Wei <carrot@google.com> + + PR target/62262 + * config/aarch64/aarch64.md (*andim_ashift<mode>_bfiz): Check the shift + amount before using it. + +2014-08-26 Joel Sherrill <joel.sherrill@oarcorp.com> + + * doc/invoke.texi: -fno-cxa-atexit should be -fno-use-cxa-atexit. + +2014-08-26 Marek Polacek <polacek@redhat.com> + + Backport from mainline + 2014-08-26 Marek Polacek <polacek@redhat.com> + + PR c/61271 + * tree-vectorizer.h (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT, + LOOP_REQUIRES_VERSIONING_FOR_ALIAS): Wrap in parens. + +2014-08-24 Oleg Endo <olegendo@gcc.gnu.org> + + Backport from mainline + 2014-08-24 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/61996 + * config/sh/sh.opt (musermode): Allow negative form. + * config/sh/sh.c (sh_option_override): Disable TARGET_USERMODE for + targets that don't support it. + * doc/invoke.texi (SH Options): Rename sh-*-linux* to sh*-*-linux*. + Document -mno-usermode option. + +2014-08-23 John David Anglin <danglin@gcc.gnu.org> + + PR target/62038 + * config/pa/pa.c (pa_output_function_epilogue): Don't set + last_address when the current function is a thunk. + (pa_asm_output_mi_thunk): When we don't have named sections or they + are not being used, check that thunk can reach the stub table with a + short branch. + +2014-08-22 Michael Meissner <meissner@linux.vnet.ibm.com> + + Backport from mainline + 2014-08-22 Michael Meissner <meissner@linux.vnet.ibm.com> + + PR target/62195 + * doc/md.texi (Machine Constraints): Update PowerPC wi constraint + documentation to state it is only for VSX operations. + + * config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): Make wi + constraint only active if VSX. + + * config/rs6000/rs6000.md (lfiwax): Use wj constraint instead of + wi cosntraint for ISA 2.07 lxsiwax/lxsiwzx instructions. + (lfiwzx): Likewise. + +2014-08-21 Uros Bizjak <ubizjak@gmail.com> + + Backport from mainline + 2014-08-19 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/i386.md (*ctz<mode>2_falsedep_1): Don't clear + destination if it is used in source. + (*clz<mode>2_lzcnt_falsedep_1): Likewise. + (*popcount<mode>2_falsedep_1): Likewise. + + Backport from mainline + 2014-08-18 Uros Bizjak <ubizjak@gmail.com> + + PR target/62011 + * config/i386/x86-tune.def (X86_TUNE_AVOID_FALSE_DEP_FOR_BMI): + New tune flag. + * config/i386/i386.h (TARGET_AVOID_FALSE_DEP_FOR_BMI): New define. + * config/i386/i386.md (unspec) <UNSPEC_INSN_FALSE_DEP>: New unspec. + (ffs<mode>2): Do not expand with tzcnt for + TARGET_AVOID_FALSE_DEP_FOR_BMI. + (ffssi2_no_cmove): Ditto. + (*tzcnt<mode>_1): Disable for TARGET_AVOID_FALSE_DEP_FOR_BMI. + (ctz<mode>2): New expander. + (*ctz<mode>2_falsedep_1): New insn_and_split pattern. + (*ctz<mode>2_falsedep): New insn. + (*ctz<mode>2): Rename from ctz<mode>2. + (clz<mode>2_lzcnt): New expander. + (*clz<mode>2_lzcnt_falsedep_1): New insn_and_split pattern. + (*clz<mode>2_lzcnt_falsedep): New insn. + (*clz<mode>2): Rename from ctz<mode>2. + (popcount<mode>2): New expander. + (*popcount<mode>2_falsedep_1): New insn_and_split pattern. + (*popcount<mode>2_falsedep): New insn. + (*popcount<mode>2): Rename from ctz<mode>2. + (*popcount<mode>2_cmp): Remove. + (*popcountsi2_cmp_zext): Ditto. + +2014-08-20 Martin Jambor <mjambor@suse.cz> + Wei Mi <wmi@google.com> + + PR ipa/60449 + PR middle-end/61776 + * tree-ssa-operands.c (update_stmt_operands): Remove + MODIFIED_NORETURN_CALLS. + * tree-cfgcleanup.c (cleanup_call_ctrl_altering_flag): New func. + (cleanup_control_flow_bb): Use cleanup_call_ctrl_altering_flag. + (split_bb_on_noreturn_calls): Renamed from split_bbs_on_noreturn_calls. + (cleanup_tree_cfg_1): Use split_bb_on_noreturn_calls. + * tree-ssanames.h: Remove MODIFIED_NORETURN_CALLS. + * gimple.h (enum gf_mask): Add GF_CALL_CTRL_ALTERING. + (gimple_call_set_ctrl_altering): New func. + (gimple_call_ctrl_altering_p): Ditto. + * tree-cfg.c (gimple_call_initialize_ctrl_altering): Ditto. + (make_blocks): Use gimple_call_initialize_ctrl_altering. + (is_ctrl_altering_stmt): Use gimple_call_ctrl_altering_p. + (execute_fixup_cfg): Use gimple_call_ctrl_altering_p and + remove MODIFIED_NORETURN_CALLS. + +2014-08-20 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + Backport from mainline. + 2014-08-12 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + PR target/62098 + * config/arm/vfp.md (*combine_vcvtf2i): Fix constraint. + Remove unnecessary attributes. + +2014-08-16 John David Anglin <danglin@gcc.gnu.org> + + PR target/61641 + * config/pa/pa-protos.h (pa_output_addr_vec, pa_output_addr_diff_vec): + Declare. + * config/pa/pa.c (pa_reorg): Remove code to insert brtab marker insns. + (pa_output_addr_vec, pa_output_addr_diff_vec): New. + * config/pa/pa.h (ASM_OUTPUT_ADDR_VEC, ASM_OUTPUT_ADDR_DIFF_VEC): + Define. + * config/pa/pa.md (begin_brtab): Delete insn. + (end_brtab): Likewise. + +2014-08-15 Oleg Endo <olegendo@gcc.gnu.org> + + Backport from mainline: + 2014-08-15 Oleg Endo <olegendo@gcc.gnu.org> + + * doc/invoke.texi (SH options): Document missing processor variant + options. Remove references to Hitachi. Undocument deprecated mspace + option. + +2014-08-15 Tom de Vries <tom@codesourcery.com> + + Backport from mainline: + 2014-08-14 Tom de Vries <tom@codesourcery.com> + + PR rtl-optimization/62004 + PR rtl-optimization/62030 + * ifcvt.c (rtx_interchangeable_p): New function. + (noce_try_move, noce_process_if_block): Use rtx_interchangeable_p. + + 2014-08-05 Richard Biener <rguenther@suse.de> + + * emit-rtl.h (mem_attrs_eq_p): Declare. + * emit-rtl.c (mem_attrs_eq_p): Export. + +2014-08-15 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/62092 + * gimplify.c (gimplify_adjust_omp_clauses_1): Don't remove + OMP_CLAUSE_SHARED for global vars if the global var is mentioned + in OMP_CLAUSE_MAP in some outer target region. + +2014-08-14 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + Backport from mainline + 2014-08-04 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + PR target/61713 + * gcc/optabs.c (expand_atomic_test_and_set): Do not try to emit + move to subtarget in serial version if result is ignored. + +2014-08-14 Thomas Preud'homme <thomas.preudhomme@arm.com> + + Backport from mainline + 2014-08-12 Thomas Preud'homme <thomas.preudhomme@arm.com> + + PR middle-end/62103 + * gimple-fold.c (fold_ctor_reference): Don't fold in presence of + bitfields, that is when size doesn't match the size of type or the + size of the constructor. + +2014-08-12 Felix Yang <fei.yang0953@gmail.com> + + PR tree-optimization/62073 + * tree-vect-loop.c (vect_is_simple_reduction_1): Check that DEF1 has + a basic block. + +2014-08-12 Jakub Jelinek <jakub@redhat.com> + + PR target/62025 + * sched-deps.c (find_inc): Check if inc_insn doesn't clobber + any registers that are used in mem_insn. + +2014-08-12 Michael Meissner <meissner@linux.vnet.ibm.com> + + Backport patch from mainline + 2014-08-11 Michael Meissner <meissner@linux.vnet.ibm.com> + + * config/rs6000/constraints.md (wh constraint): New constraint, + for FP registers if direct move is available. + (wi constraint): New constraint, for VSX/FP registers that can + handle 64-bit integers. + (wj constraint): New constraint for VSX/FP registers that can + handle 64-bit integers for direct moves. + (wk constraint): New constraint for VSX/FP registers that can + handle 64-bit doubles for direct moves. + (wy constraint): Make documentation match implementation. + + * config/rs6000/rs6000.c (struct rs6000_reg_addr): Add + scalar_in_vmx_p field to simplify tests of whether SFmode or + DFmode can go in the Altivec registers. + (rs6000_hard_regno_mode_ok): Use scalar_in_vmx_p field. + (rs6000_setup_reg_addr_masks): Likewise. + (rs6000_debug_print_mode): Add debug support for scalar_in_vmx_p + field, and wh/wi/wj/wk constraints. + (rs6000_init_hard_regno_mode_ok): Setup scalar_in_vmx_p field, and + the wh/wi/wj/wk constraints. + (rs6000_preferred_reload_class): If SFmode/DFmode can go in the + upper registers, prefer VSX registers unless the operation is a + memory operation with REG+OFFSET addressing. + + * config/rs6000/vsx.md (VSr mode attribute): Add support for + DImode. Change SFmode to use ww constraint instead of d to allow + SF registers in the upper registers. + (VSr2): Likewise. + (VSr3): Likewise. + (VSr5): Fix thinko in comment. + (VSa): New mode attribute that is an alternative to wa, that + returns the VSX register class that a mode can go in, but may not + be the preferred register class. + (VS_64dm): New mode attribute for appropriate register classes for + referencing 64-bit elements of vectors for direct moves and normal + moves. + (VS_64reg): Likewise. + (vsx_mov<mode>): Change wa constraint to <VSa> to limit the + register allocator to only registers the data type can handle. + (vsx_le_perm_load_<mode>): Likewise. + (vsx_le_perm_store_<mode>): Likewise. + (vsx_xxpermdi2_le_<mode>): Likewise. + (vsx_xxpermdi4_le_<mode>): Likewise. + (vsx_lxvd2x2_le_<mode>): Likewise. + (vsx_lxvd2x4_le_<mode>): Likewise. + (vsx_stxvd2x2_le_<mode>): Likewise. + (vsx_add<mode>3): Likewise. + (vsx_sub<mode>3): Likewise. + (vsx_mul<mode>3): Likewise. + (vsx_div<mode>3): Likewise. + (vsx_tdiv<mode>3_internal): Likewise. + (vsx_fre<mode>2): Likewise. + (vsx_neg<mode>2): Likewise. + (vsx_abs<mode>2): Likewise. + (vsx_nabs<mode>2): Likewise. + (vsx_smax<mode>3): Likewise. + (vsx_smin<mode>3): Likewise. + (vsx_sqrt<mode>2): Likewise. + (vsx_rsqrte<mode>2): Likewise. + (vsx_tsqrt<mode>2_internal): Likewise. + (vsx_fms<mode>4): Likewise. + (vsx_nfma<mode>4): Likewise. + (vsx_eq<mode>): Likewise. + (vsx_gt<mode>): Likewise. + (vsx_ge<mode>): Likewise. + (vsx_eq<mode>_p): Likewise. + (vsx_gt<mode>_p): Likewise. + (vsx_ge<mode>_p): Likewise. + (vsx_xxsel<mode>): Likewise. + (vsx_xxsel<mode>_uns): Likewise. + (vsx_copysign<mode>3): Likewise. + (vsx_float<VSi><mode>2): Likewise. + (vsx_floatuns<VSi><mode>2): Likewise. + (vsx_fix_trunc<mode><VSi>2): Likewise. + (vsx_fixuns_trunc<mode><VSi>2): Likewise. + (vsx_x<VSv>r<VSs>i): Likewise. + (vsx_x<VSv>r<VSs>ic): Likewise. + (vsx_btrunc<mode>2): Likewise. + (vsx_b2trunc<mode>2): Likewise. + (vsx_floor<mode>2): Likewise. + (vsx_ceil<mode>2): Likewise. + (vsx_<VS_spdp_insn>): Likewise. + (vsx_xscvspdp): Likewise. + (vsx_xvcvspuxds): Likewise. + (vsx_float_fix_<mode>2): Likewise. + (vsx_set_<mode>): Likewise. + (vsx_extract_<mode>_internal1): Likewise. + (vsx_extract_<mode>_internal2): Likewise. + (vsx_extract_<mode>_load): Likewise. + (vsx_extract_<mode>_store): Likewise. + (vsx_splat_<mode>): Likewise. + (vsx_xxspltw_<mode>): Likewise. + (vsx_xxspltw_<mode>_direct): Likewise. + (vsx_xxmrghw_<mode>): Likewise. + (vsx_xxmrglw_<mode>): Likewise. + (vsx_xxsldwi_<mode>): Likewise. + (vsx_xscvdpspn): Tighten constraints to only use register classes + the types use. + (vsx_xscvspdpn): Likewise. + (vsx_xscvdpspn_scalar): Likewise. + + * config/rs6000/rs6000.h (enum rs6000_reg_class_enum): Add wh, wi, + wj, and wk constraints. + (GPR_REG_CLASS_P): New helper macro for register classes targeting + general purpose registers. + + * config/rs6000/rs6000.md (f32_dm): Use wh constraint for SDmode + direct moves. + (zero_extendsidi2_lfiwz): Use wj constraint for direct move of + DImode instead of wm. Use wk constraint for direct move of DFmode + instead of wm. + (extendsidi2_lfiwax): Likewise. + (lfiwax): Likewise. + (lfiwzx): Likewise. + (movdi_internal64): Likewise. + + * doc/md.texi (PowerPC and IBM RS6000): Document wh, wi, wj, and + wk constraints. Make the wy constraint documentation match them + implementation. + +2014-08-12 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com> + + Backport from mainline + 2014-08-04 Ganesh Gopalasubramanian + <Ganesh.Gopalasubramanian@amd.com> + + * config/i386/i386.c (ix86_option_override_internal): Add + PTA_RDRND and PTA_MOVBE for bdver4. + +2014-08-12 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com> + + Backport from mainline + 2014-08-04 Ganesh Gopalasubramanian + <Ganesh.Gopalasubramanian@amd.com> + + * config/i386/driver-i386.c (host_detect_local_cpu): Handle AMD's extended + family information. Handle BTVER2 cpu with cpuid family value. + +2014-08-12 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com> + + Backport from mainline + 2014-06-16 Ganesh Gopalasubramanian + <Ganesh.Gopalasubramanian@amd.com> + + * config/i386/i386.c (ix86_expand_sse2_mulvxdi3): Issue + instructions "vpmuludq" and "vpaddq" instead of "vpmacsdql" for + handling 32-bit multiplication. + 2014-08-08 Guozhi Wei <carrot@google.com> * config/rs6000/rs6000.md (*movdi_internal64): Add a new constraint. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index fb37762b343..42c2c08a8bc 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20140811 +20140904 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 27d4ad7cbac..c8c4d807b94 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2014-08-12 Joel Sherrill <joel.sherrill@oarcorp.com> + + * socket.c: For RTEMS, use correct prototype of gethostbyname_r(). + * gsocket.h Add include of <unistd.h> on RTEMS. + +2014-08-11 Joel Sherrill <joel.sherrill@oarcorp.com> + + * s-osinte-rtems.adb: Correct formatting of line in license block. + 2014-07-16 Release Manager * GCC 4.9.1 released. diff --git a/gcc/ada/gsocket.h b/gcc/ada/gsocket.h index e21d7142701..1d9235f4ad8 100644 --- a/gcc/ada/gsocket.h +++ b/gcc/ada/gsocket.h @@ -183,6 +183,11 @@ #include <sys/time.h> #endif +#if defined(__rtems__) +#include <unistd.h> +/* Required, for read(), write(), and close() */ +#endif + /* * RTEMS has these .h files but not until you have built and installed RTEMS. * When building a C/C++ toolset, you also build the newlib C library, so the diff --git a/gcc/ada/s-osinte-rtems.adb b/gcc/ada/s-osinte-rtems.adb index de21785941a..9f01128c918 100644 --- a/gcc/ada/s-osinte-rtems.adb +++ b/gcc/ada/s-osinte-rtems.adb @@ -22,7 +22,7 @@ -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. +-- <http://www.gnu.org/licenses/>. -- -- -- -- GNARL was developed by the GNARL team at Florida State University. It is -- -- now maintained by Ada Core Technologies Inc. in cooperation with Florida -- diff --git a/gcc/ada/socket.c b/gcc/ada/socket.c index 18999b394ea..e65845628a1 100644 --- a/gcc/ada/socket.c +++ b/gcc/ada/socket.c @@ -212,7 +212,7 @@ __gnat_gethostbyname (const char *name, struct hostent *rh; int ri; -#if defined(__linux__) || defined(__GLIBC__) +#if defined(__linux__) || defined(__GLIBC__) || defined(__rtems__) (void) gethostbyname_r (name, ret, buf, buflen, &rh, h_errnop); #else rh = gethostbyname_r (name, ret, buf, buflen, h_errnop); diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 549cbe29e9a..e3c8c8300f9 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2014-08-12 Igor Zamyatin <igor.zamyatin@intel.com> + + PR other/61962 + * array-notation-common.c (find_rank): Added handling for other + types of references. + 2014-08-01 Igor Zamyatin <igor.zamyatin@intel.com> PR middle-end/61455 diff --git a/gcc/c-family/array-notation-common.c b/gcc/c-family/array-notation-common.c index 84f6f452799..f8bce04bbc1 100644 --- a/gcc/c-family/array-notation-common.c +++ b/gcc/c-family/array-notation-common.c @@ -221,11 +221,14 @@ find_rank (location_t loc, tree orig_expr, tree expr, bool ignore_builtin_fn, current_rank++; ii_tree = ARRAY_NOTATION_ARRAY (ii_tree); } - else if (TREE_CODE (ii_tree) == ARRAY_REF) + else if (handled_component_p (ii_tree) + || TREE_CODE (ii_tree) == INDIRECT_REF) ii_tree = TREE_OPERAND (ii_tree, 0); else if (TREE_CODE (ii_tree) == PARM_DECL || TREE_CODE (ii_tree) == VAR_DECL) break; + else + gcc_unreachable (); } if (*rank == 0) /* In this case, all the expressions this function has encountered thus diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index f475f7ea16e..4afd58170b3 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,18 @@ +2014-09-03 Marek Polacek <polacek@redhat.com> + + PR c/62294 + * c-typeck.c (convert_arguments): Get location of a parameter. Change + error and warning calls to error_at and warning_at. Pass location of + a parameter to it. + (convert_for_assignment): Add parameter to WARN_FOR_ASSIGNMENT and + WARN_FOR_QUALIFIERS. Pass expr_loc to those. + +2014-08-22 Igor Zamyatin <igor.zamyatin@intel.com> + + PR other/62008 + * c-parser.c (c_parser_array_notation): Check for correct + type of an array added. + 2014-08-01 Igor Zamyatin <igor.zamyatin@intel.com> PR middle-end/61455 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index ed5a40d0042..060233765c9 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -14077,6 +14077,13 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, array_type = TREE_TYPE (array_value); gcc_assert (array_type); + if (TREE_CODE (array_type) != ARRAY_TYPE + && TREE_CODE (array_type) != POINTER_TYPE) + { + error_at (loc, "base of array section must be pointer or array type"); + c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); + return error_mark_node; + } type = TREE_TYPE (array_type); token = c_parser_peek_token (parser); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index e24861f8355..d736fbc4cb0 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -3071,6 +3071,12 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, bool excess_precision = false; bool npc; tree parmval; + /* Some __atomic_* builtins have additional hidden argument at + position 0. */ + location_t ploc + = !arg_loc.is_empty () && values->length () == arg_loc.length () + ? expansion_point_location_if_in_system_header (arg_loc[parmnum]) + : input_location; if (type == void_type_node) { @@ -3113,7 +3119,8 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, if (type == error_mark_node || !COMPLETE_TYPE_P (type)) { - error ("type of formal parameter %d is incomplete", parmnum + 1); + error_at (ploc, "type of formal parameter %d is incomplete", + parmnum + 1); parmval = val; } else @@ -3128,34 +3135,34 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, if (INTEGRAL_TYPE_P (type) && TREE_CODE (valtype) == REAL_TYPE) - warning (0, "passing argument %d of %qE as integer " - "rather than floating due to prototype", - argnum, rname); + warning_at (ploc, 0, "passing argument %d of %qE as " + "integer rather than floating due to " + "prototype", argnum, rname); if (INTEGRAL_TYPE_P (type) && TREE_CODE (valtype) == COMPLEX_TYPE) - warning (0, "passing argument %d of %qE as integer " - "rather than complex due to prototype", - argnum, rname); + warning_at (ploc, 0, "passing argument %d of %qE as " + "integer rather than complex due to " + "prototype", argnum, rname); else if (TREE_CODE (type) == COMPLEX_TYPE && TREE_CODE (valtype) == REAL_TYPE) - warning (0, "passing argument %d of %qE as complex " - "rather than floating due to prototype", - argnum, rname); + warning_at (ploc, 0, "passing argument %d of %qE as " + "complex rather than floating due to " + "prototype", argnum, rname); else if (TREE_CODE (type) == REAL_TYPE && INTEGRAL_TYPE_P (valtype)) - warning (0, "passing argument %d of %qE as floating " - "rather than integer due to prototype", - argnum, rname); + warning_at (ploc, 0, "passing argument %d of %qE as " + "floating rather than integer due to " + "prototype", argnum, rname); else if (TREE_CODE (type) == COMPLEX_TYPE && INTEGRAL_TYPE_P (valtype)) - warning (0, "passing argument %d of %qE as complex " - "rather than integer due to prototype", - argnum, rname); + warning_at (ploc, 0, "passing argument %d of %qE as " + "complex rather than integer due to " + "prototype", argnum, rname); else if (TREE_CODE (type) == REAL_TYPE && TREE_CODE (valtype) == COMPLEX_TYPE) - warning (0, "passing argument %d of %qE as floating " - "rather than complex due to prototype", - argnum, rname); + warning_at (ploc, 0, "passing argument %d of %qE as " + "floating rather than complex due to " + "prototype", argnum, rname); /* ??? At some point, messages should be written about conversions between complex types, but that's too messy to do now. */ @@ -3166,9 +3173,10 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, since without a prototype it would be `double'. */ if (formal_prec == TYPE_PRECISION (float_type_node) && type != dfloat32_type_node) - warning (0, "passing argument %d of %qE as %<float%> " - "rather than %<double%> due to prototype", - argnum, rname); + warning_at (ploc, 0, + "passing argument %d of %qE as %<float%> " + "rather than %<double%> due to prototype", + argnum, rname); /* Warn if mismatch between argument and prototype for decimal float types. Warn of conversions with @@ -3191,9 +3199,10 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, || (type == dfloat64_type_node && (valtype != dfloat32_type_node)))) - warning (0, "passing argument %d of %qE as %qT " - "rather than %qT due to prototype", - argnum, rname, type, valtype); + warning_at (ploc, 0, + "passing argument %d of %qE as %qT " + "rather than %qT due to prototype", + argnum, rname, type, valtype); } /* Detect integer changing in width or signedness. @@ -3212,10 +3221,10 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, and the actual arg is that enum type. */ ; else if (formal_prec != TYPE_PRECISION (type1)) - warning (OPT_Wtraditional_conversion, - "passing argument %d of %qE " - "with different width due to prototype", - argnum, rname); + warning_at (ploc, OPT_Wtraditional_conversion, + "passing argument %d of %qE " + "with different width due to prototype", + argnum, rname); else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1)) ; /* Don't complain if the formal parameter type @@ -3236,14 +3245,15 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, && TYPE_UNSIGNED (valtype)) ; else if (TYPE_UNSIGNED (type)) - warning (OPT_Wtraditional_conversion, - "passing argument %d of %qE " - "as unsigned due to prototype", - argnum, rname); + warning_at (ploc, OPT_Wtraditional_conversion, + "passing argument %d of %qE " + "as unsigned due to prototype", + argnum, rname); else - warning (OPT_Wtraditional_conversion, - "passing argument %d of %qE " - "as signed due to prototype", argnum, rname); + warning_at (ploc, OPT_Wtraditional_conversion, + "passing argument %d of %qE " + "as signed due to prototype", + argnum, rname); } } @@ -3252,13 +3262,7 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, if (excess_precision) val = build1 (EXCESS_PRECISION_EXPR, valtype, val); origtype = (!origtypes) ? NULL_TREE : (*origtypes)[parmnum]; - bool arg_loc_ok = !arg_loc.is_empty () - /* Some __atomic_* builtins have additional - hidden argument at position 0. */ - && values->length () == arg_loc.length (); - parmval = convert_for_assignment (loc, - arg_loc_ok ? arg_loc[parmnum] - : UNKNOWN_LOCATION, type, + parmval = convert_for_assignment (loc, ploc, type, val, origtype, ic_argpass, npc, fundecl, function, parmnum + 1); @@ -3282,10 +3286,10 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, { /* Convert `float' to `double'. */ if (warn_double_promotion && !c_inhibit_evaluation_warnings) - warning_at (arg_loc[parmnum], OPT_Wdouble_promotion, - "implicit conversion from %qT to %qT when passing " - "argument to function", - valtype, double_type_node); + warning_at (ploc, OPT_Wdouble_promotion, + "implicit conversion from %qT to %qT when passing " + "argument to function", + valtype, double_type_node); parmval = convert (double_type_node, val); } } @@ -5591,14 +5595,14 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, /* This macro is used to emit diagnostics to ensure that all format strings are complete sentences, visible to gettext and checked at compile time. */ -#define WARN_FOR_ASSIGNMENT(LOCATION, OPT, AR, AS, IN, RE) \ +#define WARN_FOR_ASSIGNMENT(LOCATION, PLOC, OPT, AR, AS, IN, RE) \ do { \ switch (errtype) \ { \ case ic_argpass: \ - if (pedwarn (LOCATION, OPT, AR, parmnum, rname)) \ + if (pedwarn (PLOC, OPT, AR, parmnum, rname)) \ inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \ - ? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \ + ? DECL_SOURCE_LOCATION (fundecl) : PLOC, \ "expected %qT but argument is of type %qT", \ type, rhstype); \ break; \ @@ -5621,22 +5625,22 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, compile time. It is the same as WARN_FOR_ASSIGNMENT but with an extra parameter to enumerate qualifiers. */ -#define WARN_FOR_QUALIFIERS(LOCATION, OPT, AR, AS, IN, RE, QUALS) \ +#define WARN_FOR_QUALIFIERS(LOCATION, PLOC, OPT, AR, AS, IN, RE, QUALS) \ do { \ switch (errtype) \ { \ case ic_argpass: \ - if (pedwarn (LOCATION, OPT, AR, parmnum, rname, QUALS)) \ + if (pedwarn (PLOC, OPT, AR, parmnum, rname, QUALS)) \ inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \ - ? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \ + ? DECL_SOURCE_LOCATION (fundecl) : PLOC, \ "expected %qT but argument is of type %qT", \ type, rhstype); \ break; \ case ic_assign: \ - pedwarn (LOCATION, OPT, AS, QUALS); \ + pedwarn (LOCATION, OPT, AS, QUALS); \ break; \ case ic_init: \ - pedwarn (LOCATION, OPT, IN, QUALS); \ + pedwarn (LOCATION, OPT, IN, QUALS); \ break; \ case ic_return: \ pedwarn (LOCATION, OPT, RE, QUALS); \ @@ -5688,7 +5692,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, && TREE_CODE (type) == ENUMERAL_TYPE && TYPE_MAIN_VARIANT (checktype) != TYPE_MAIN_VARIANT (type)) { - WARN_FOR_ASSIGNMENT (input_location, OPT_Wc___compat, + WARN_FOR_ASSIGNMENT (input_location, expr_loc, OPT_Wc___compat, G_("enum conversion when passing argument " "%d of %qE is invalid in C++"), G_("enum conversion in assignment is " @@ -5851,7 +5855,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, vice-versa. */ if (TYPE_QUALS_NO_ADDR_SPACE (ttl) & ~TYPE_QUALS_NO_ADDR_SPACE (ttr)) - WARN_FOR_QUALIFIERS (location, 0, + WARN_FOR_QUALIFIERS (location, expr_loc, 0, G_("passing argument %d of %qE " "makes %q#v qualified function " "pointer from unqualified"), @@ -5867,7 +5871,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, } else if (TYPE_QUALS_NO_ADDR_SPACE (ttr) & ~TYPE_QUALS_NO_ADDR_SPACE (ttl)) - WARN_FOR_QUALIFIERS (location, 0, + WARN_FOR_QUALIFIERS (location, expr_loc, 0, G_("passing argument %d of %qE discards " "%qv qualifier from pointer target type"), G_("assignment discards %qv qualifier " @@ -6029,7 +6033,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, (VOID_TYPE_P (ttr) && !null_pointer_constant && TREE_CODE (ttl) == FUNCTION_TYPE))) - WARN_FOR_ASSIGNMENT (location, OPT_Wpedantic, + WARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wpedantic, G_("ISO C forbids passing argument %d of " "%qE between function pointer " "and %<void *%>"), @@ -6048,7 +6052,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, if (TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttr) & ~TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttl)) { - WARN_FOR_QUALIFIERS (location, 0, + WARN_FOR_QUALIFIERS (location, expr_loc, 0, G_("passing argument %d of %qE discards " "%qv qualifier from pointer target type"), G_("assignment discards %qv qualifier " @@ -6066,7 +6070,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, ; /* If there is a mismatch, do warn. */ else if (warn_pointer_sign) - WARN_FOR_ASSIGNMENT (location, OPT_Wpointer_sign, + WARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wpointer_sign, G_("pointer targets in passing argument " "%d of %qE differ in signedness"), G_("pointer targets in assignment " @@ -6085,7 +6089,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, where an ordinary one is wanted, but not vice-versa. */ if (TYPE_QUALS_NO_ADDR_SPACE (ttl) & ~TYPE_QUALS_NO_ADDR_SPACE (ttr)) - WARN_FOR_QUALIFIERS (location, 0, + WARN_FOR_QUALIFIERS (location, expr_loc, 0, G_("passing argument %d of %qE makes " "%q#v qualified function pointer " "from unqualified"), @@ -6101,7 +6105,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, else /* Avoid warning about the volatile ObjC EH puts on decls. */ if (!objc_ok) - WARN_FOR_ASSIGNMENT (location, 0, + WARN_FOR_ASSIGNMENT (location, expr_loc, 0, G_("passing argument %d of %qE from " "incompatible pointer type"), G_("assignment from incompatible pointer type"), @@ -6124,7 +6128,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, or one that results from arithmetic, even including a cast to integer type. */ if (!null_pointer_constant) - WARN_FOR_ASSIGNMENT (location, 0, + WARN_FOR_ASSIGNMENT (location, expr_loc, 0, G_("passing argument %d of %qE makes " "pointer from integer without a cast"), G_("assignment makes pointer from integer " @@ -6138,7 +6142,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, } else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) { - WARN_FOR_ASSIGNMENT (location, 0, + WARN_FOR_ASSIGNMENT (location, expr_loc, 0, G_("passing argument %d of %qE makes integer " "from pointer without a cast"), G_("assignment makes integer from pointer " diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 04ef6faec44..8abdc5d3f8e 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1170,7 +1170,7 @@ handle_alias_pairs (void) /* We use local aliases for C++ thunks to force the tailcall to bind locally. This is a hack - to keep it working do the following (which is not strictly correct). */ - && (! TREE_CODE (target_node->decl) == FUNCTION_DECL + && (TREE_CODE (target_node->decl) != FUNCTION_DECL || ! DECL_VIRTUAL_P (target_node->decl)) && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))) { diff --git a/gcc/config.gcc b/gcc/config.gcc index 5b9645036cb..e6fd076a10d 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -3534,20 +3534,17 @@ case "${target}" in ;; esac - case "$with_fpu" in - "" \ - | vfp | vfp3 | vfpv3 \ - | vfpv3-fp16 | vfpv3-d16 | vfpv3-d16-fp16 | vfpv3xd \ - | vfpv3xd-fp16 | neon | neon-fp16 | vfpv4 | vfpv4-d16 \ - | fpv4-sp-d16 | neon-vfpv4 | fp-arm-v8 | neon-fp-armv8 \ - | crypto-neon-fp-armv8) - # OK - ;; - *) - echo "Unknown fpu used in --with-fpu=$with_fpu" 2>&1 - exit 1 - ;; - esac + # see if it matches any of the entries in arm-fpus.def + if [ x"$with_fpu" = x ] \ + || grep "^ARM_FPU(\"$with_fpu\"," \ + ${srcdir}/config/arm/arm-fpus.def \ + > /dev/null; then + # OK + true + else + echo "Unknown fpu used in --with-fpu=$with_fpu" 1>&2 + exit 1 + fi case "$with_abi" in "" \ diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index be1206dccf7..74d271aeadf 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -3372,7 +3372,8 @@ (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r") (match_operand 2 "const_int_operand" "n")) (match_operand 3 "const_int_operand" "n")))] - "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0 + "(INTVAL (operands[2]) < (<GPI:sizen>)) + && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0" "ubfiz\\t%<w>0, %<w>1, %2, %P3" [(set_attr "type" "bfm")] diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index 9962bd3ba97..af75f9d9287 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -1254,17 +1254,15 @@ ) (define_insn "*combine_vcvtf2i" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (fix:SI (fix:SF (mult:SF (match_operand:SF 1 "s_register_operand" "t") + [(set (match_operand:SI 0 "s_register_operand" "=t") + (fix:SI (fix:SF (mult:SF (match_operand:SF 1 "s_register_operand" "0") (match_operand 2 "const_double_vcvt_power_of_two" "Dp")))))] "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math" - "vcvt%?.s32.f32\\t%1, %1, %v2\;vmov%?\\t%0, %1" + "vcvt%?.s32.f32\\t%0, %1, %v2" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "ce_count" "2") - (set_attr "type" "f_cvtf2i") - (set_attr "length" "8")] + (set_attr "type" "f_cvtf2i")] ) ;; Store multiple insn used in function prologue. diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h index a1955a7e7f7..9b466212009 100644 --- a/gcc/config/gnu-user.h +++ b/gcc/config/gnu-user.h @@ -114,7 +114,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Link -lasan early on the command line. For -static-libasan, don't link it for -shared link, the executable should be compiled with -static-libasan in that case, and for executable link link with --{,no-}whole-archive around - it to force everything into the executable. And similarly for -ltsan. */ + it to force everything into the executable. And similarly for -ltsan + and -llsan. */ #if defined(HAVE_LD_STATIC_DYNAMIC) #undef LIBASAN_EARLY_SPEC #define LIBASAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \ @@ -125,4 +126,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define LIBTSAN_EARLY_SPEC "%{static-libtsan:%{!shared:" \ LD_STATIC_OPTION " --whole-archive -ltsan --no-whole-archive " \ LD_DYNAMIC_OPTION "}}%{!static-libtsan:-ltsan}" +#undef LIBLSAN_EARLY_SPEC +#define LIBLSAN_EARLY_SPEC "%{static-liblsan:%{!shared:" \ + LD_STATIC_OPTION " --whole-archive -llsan --no-whole-archive " \ + LD_DYNAMIC_OPTION "}}%{!static-liblsan:-llsan}" #endif diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index 80f6a087925..722c5469255 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -431,7 +431,8 @@ const char *host_detect_local_cpu (int argc, const char **argv) model = (eax >> 4) & 0x0f; family = (eax >> 8) & 0x0f; - if (vendor == signature_INTEL_ebx) + if (vendor == signature_INTEL_ebx + || vendor == signature_AMD_ebx) { unsigned int extended_model, extended_family; @@ -570,7 +571,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) if (name == signature_NSC_ebx) processor = PROCESSOR_GEODE; - else if (has_movbe) + else if (has_movbe && family == 22) processor = PROCESSOR_BTVER2; else if (has_avx2) processor = PROCESSOR_BDVER4; diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 034ca414c98..c7c504c35e1 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3258,12 +3258,13 @@ ix86_option_override_internal (bool main_args_p, | PTA_FMA | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE}, {"bdver4", PROCESSOR_BDVER4, CPU_BDVER4, - PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 - | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 - | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_AVX2 + PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 + | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 + | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_AVX2 | PTA_FMA4 | PTA_XOP | PTA_LWP | PTA_BMI | PTA_BMI2 | PTA_TBM | PTA_F16C | PTA_FMA | PTA_PRFCHW | PTA_FXSR - | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE}, + | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE | PTA_RDRND + | PTA_MOVBE}, {"btver1", PROCESSOR_BTVER1, CPU_GENERIC, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_PRFCHW @@ -45095,8 +45096,10 @@ ix86_expand_sse2_mulvxdi3 (rtx op0, rtx op1, rtx op2) /* t4: ((B*E)+(A*F))<<32, ((D*G)+(C*H))<<32 */ emit_insn (gen_ashlv2di3 (t4, t3, GEN_INT (32))); - /* op0: (((B*E)+(A*F))<<32)+(B*F), (((D*G)+(C*H))<<32)+(D*H) */ - emit_insn (gen_xop_pmacsdql (op0, op1, op2, t4)); + /* Multiply lower parts and add all */ + t5 = gen_reg_rtx (V2DImode); + emit_insn (gen_vec_widen_umult_even_v4si (t5, gen_lowpart (V4SImode, op1), gen_lowpart (V4SImode, op2))); + op0 = expand_binop (mode, add_optab, t5, t4, op0, 1, OPTAB_DIRECT); } else { diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 51659deb309..b3b7c8d3090 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -457,6 +457,8 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST]; ix86_tune_features[X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS] #define TARGET_ADJUST_UNROLL \ ix86_tune_features[X86_TUNE_ADJUST_UNROLL] +#define TARGET_AVOID_FALSE_DEP_FOR_BMI \ + ix86_tune_features[X86_TUNE_AVOID_FALSE_DEP_FOR_BMI] /* Feature tests against the various architecture variations. */ enum ix86_arch_indices { diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index f677a7ef05a..e63be9bf7fe 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -111,6 +111,7 @@ UNSPEC_LEA_ADDR UNSPEC_XBEGIN_ABORT UNSPEC_STOS + UNSPEC_INSN_FALSE_DEP ;; For SSE/MMX support: UNSPEC_FIX_NOTRUNC @@ -11856,7 +11857,8 @@ DONE; } - flags_mode = TARGET_BMI ? CCCmode : CCZmode; + flags_mode + = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode; operands[2] = gen_reg_rtx (<MODE>mode); operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG); @@ -11882,7 +11884,8 @@ (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) (clobber (reg:CC FLAGS_REG))])] { - enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode; + enum machine_mode flags_mode + = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode; operands[3] = gen_lowpart (QImode, operands[2]); operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG); @@ -11897,7 +11900,7 @@ (const_int 0))) (set (match_operand:SWI48 0 "register_operand" "=r") (ctz:SWI48 (match_dup 1)))] - "TARGET_BMI" + "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI" "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" [(set_attr "type" "alu1") (set_attr "prefix_0f" "1") @@ -11918,7 +11921,58 @@ (set_attr "btver2_decode" "double") (set_attr "mode" "<MODE>")]) -(define_insn "ctz<mode>2" +(define_expand "ctz<mode>2" + [(parallel + [(set (match_operand:SWI248 0 "register_operand") + (ctz:SWI248 + (match_operand:SWI248 1 "nonimmediate_operand"))) + (clobber (reg:CC FLAGS_REG))])]) + +; False dependency happens when destination is only updated by tzcnt, +; lzcnt or popcnt. There is no false dependency when destination is +; also used in source. +(define_insn_and_split "*ctz<mode>2_falsedep_1" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (ctz:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) + (clobber (reg:CC FLAGS_REG))] + "(TARGET_BMI || TARGET_GENERIC) + && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (ctz:SWI48 (match_dup 1))) + (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) + (clobber (reg:CC FLAGS_REG))])] +{ + if (!reg_mentioned_p (operands[0], operands[1])) + ix86_expand_clear (operands[0]); +}) + +(define_insn "*ctz<mode>2_falsedep" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (ctz:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) + (unspec [(match_operand:SWI48 2 "register_operand" "0")] + UNSPEC_INSN_FALSE_DEP) + (clobber (reg:CC FLAGS_REG))] + "" +{ + if (TARGET_BMI) + return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; + else if (TARGET_GENERIC) + /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ + return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; + else + gcc_unreachable (); +} + [(set_attr "type" "alu1") + (set_attr "prefix_0f" "1") + (set_attr "prefix_rep" "1") + (set_attr "mode" "<MODE>")]) + +(define_insn "*ctz<mode>2" [(set (match_operand:SWI248 0 "register_operand" "=r") (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] @@ -11965,7 +12019,47 @@ operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); }) -(define_insn "clz<mode>2_lzcnt" +(define_expand "clz<mode>2_lzcnt" + [(parallel + [(set (match_operand:SWI248 0 "register_operand") + (clz:SWI248 + (match_operand:SWI248 1 "nonimmediate_operand"))) + (clobber (reg:CC FLAGS_REG))])] + "TARGET_LZCNT") + +(define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (clz:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_LZCNT + && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (clz:SWI48 (match_dup 1))) + (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) + (clobber (reg:CC FLAGS_REG))])] +{ + if (!reg_mentioned_p (operands[0], operands[1])) + ix86_expand_clear (operands[0]); +}) + +(define_insn "*clz<mode>2_lzcnt_falsedep" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (clz:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) + (unspec [(match_operand:SWI48 2 "register_operand" "0")] + UNSPEC_INSN_FALSE_DEP) + (clobber (reg:CC FLAGS_REG))] + "TARGET_LZCNT" + "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" + [(set_attr "prefix_rep" "1") + (set_attr "type" "bitmanip") + (set_attr "mode" "<MODE>")]) + +(define_insn "*clz<mode>2_lzcnt" [(set (match_operand:SWI248 0 "register_operand" "=r") (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] @@ -12248,10 +12342,39 @@ (set_attr "prefix_0f" "1") (set_attr "mode" "HI")]) -(define_insn "popcount<mode>2" - [(set (match_operand:SWI248 0 "register_operand" "=r") - (popcount:SWI248 - (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) +(define_expand "popcount<mode>2" + [(parallel + [(set (match_operand:SWI248 0 "register_operand") + (popcount:SWI248 + (match_operand:SWI248 1 "nonimmediate_operand"))) + (clobber (reg:CC FLAGS_REG))])] + "TARGET_POPCNT") + +(define_insn_and_split "*popcount<mode>2_falsedep_1" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (popcount:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_POPCNT + && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (popcount:SWI48 (match_dup 1))) + (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) + (clobber (reg:CC FLAGS_REG))])] +{ + if (!reg_mentioned_p (operands[0], operands[1])) + ix86_expand_clear (operands[0]); +}) + +(define_insn "*popcount<mode>2_falsedep" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (popcount:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) + (unspec [(match_operand:SWI48 2 "register_operand" "0")] + UNSPEC_INSN_FALSE_DEP) (clobber (reg:CC FLAGS_REG))] "TARGET_POPCNT" { @@ -12265,15 +12388,12 @@ (set_attr "type" "bitmanip") (set_attr "mode" "<MODE>")]) -(define_insn "*popcount<mode>2_cmp" - [(set (reg FLAGS_REG) - (compare - (popcount:SWI248 - (match_operand:SWI248 1 "nonimmediate_operand" "rm")) - (const_int 0))) - (set (match_operand:SWI248 0 "register_operand" "=r") - (popcount:SWI248 (match_dup 1)))] - "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" +(define_insn "*popcount<mode>2" + [(set (match_operand:SWI248 0 "register_operand" "=r") + (popcount:SWI248 + (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_POPCNT" { #if TARGET_MACHO return "popcnt\t{%1, %0|%0, %1}"; @@ -12285,25 +12405,6 @@ (set_attr "type" "bitmanip") (set_attr "mode" "<MODE>")]) -(define_insn "*popcountsi2_cmp_zext" - [(set (reg FLAGS_REG) - (compare - (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")) - (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI(popcount:SI (match_dup 1))))] - "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" -{ -#if TARGET_MACHO - return "popcnt\t{%1, %0|%0, %1}"; -#else - return "popcnt{l}\t{%1, %0|%0, %1}"; -#endif -} - [(set_attr "prefix_rep" "1") - (set_attr "type" "bitmanip") - (set_attr "mode" "SI")]) - (define_expand "bswapdi2" [(set (match_operand:DI 0 "register_operand") (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))] diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def index 8399102671c..c36174855cb 100644 --- a/gcc/config/i386/x86-tune.def +++ b/gcc/config/i386/x86-tune.def @@ -500,6 +500,11 @@ DEF_TUNE (X86_TUNE_NOT_VECTORMODE, "not_vectormode", m_K6) DEF_TUNE (X86_TUNE_AVOID_VECTOR_DECODE, "avoid_vector_decode", m_K8) +/* X86_TUNE_AVOID_FALSE_DEP_FOR_BMI: Avoid false dependency + for bit-manipulation instructions. */ +DEF_TUNE (X86_TUNE_AVOID_FALSE_DEP_FOR_BMI, "avoid_false_dep_for_bmi", + m_SANDYBRIDGE | m_HASWELL | m_INTEL | m_GENERIC) + /*****************************************************************************/ /* This never worked well before. */ /*****************************************************************************/ diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h index 2659dcdf06a..1e48da51258 100644 --- a/gcc/config/pa/pa-protos.h +++ b/gcc/config/pa/pa-protos.h @@ -49,6 +49,8 @@ extern const char *pa_output_mul_insn (int, rtx); extern const char *pa_output_div_insn (rtx *, int, rtx); extern const char *pa_output_mod_insn (int, rtx); extern const char *pa_singlemove_string (rtx *); +extern void pa_output_addr_vec (rtx, rtx); +extern void pa_output_addr_diff_vec (rtx, rtx); extern void pa_output_arg_descriptor (rtx); extern void pa_output_global_address (FILE *, rtx, int); extern void pa_print_operand (FILE *, rtx, int); diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 871e4e5c6e8..28978bb1684 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -3235,7 +3235,12 @@ pa_assemble_integer (rtx x, unsigned int size, int aligned_p) && aligned_p && function_label_operand (x, VOIDmode)) { - fputs (size == 8? "\t.dword\tP%" : "\t.word\tP%", asm_out_file); + fputs (size == 8? "\t.dword\t" : "\t.word\t", asm_out_file); + + /* We don't want an OPD when generating fast indirect calls. */ + if (!TARGET_FAST_INDIRECT_CALLS) + fputs ("P%", asm_out_file); + output_addr_const (asm_out_file, x); fputc ('\n', asm_out_file); return true; @@ -4155,8 +4160,7 @@ static void pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) { rtx insn = get_last_insn (); - - last_address = 0; + bool extra_nop; /* pa_expand_epilogue does the dirty work now. We just need to output the assembler directives which denote the end @@ -4180,8 +4184,10 @@ pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) if (insn && CALL_P (insn)) { fputs ("\tnop\n", file); - last_address += 4; + extra_nop = true; } + else + extra_nop = false; fputs ("\t.EXIT\n\t.PROCEND\n", file); @@ -4194,12 +4200,13 @@ pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) cfun->machine->in_nsubspa = 2; } - /* Thunks do their own accounting. */ + /* Thunks do their own insn accounting. */ if (cfun->is_thunk) return; if (INSN_ADDRESSES_SET_P ()) { + last_address = extra_nop ? 4 : 0; insn = get_last_nonnote_insn (); last_address += INSN_ADDRESSES (INSN_UID (insn)); if (INSN_P (insn)) @@ -8293,12 +8300,16 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta, || ((DECL_SECTION_NAME (thunk_fndecl) == DECL_SECTION_NAME (function)) && last_address < 262132))) + /* In this case, we need to be able to reach the start of + the stub table even though the function is likely closer + and can be jumped to directly. */ || (targetm_common.have_named_sections && DECL_SECTION_NAME (thunk_fndecl) == NULL && DECL_SECTION_NAME (function) == NULL - && last_address < 262132) + && total_code_bytes < MAX_PCREL17F_OFFSET) + /* Likewise. */ || (!targetm_common.have_named_sections - && last_address < 262132)))) + && total_code_bytes < MAX_PCREL17F_OFFSET)))) { if (!val_14) output_asm_insn ("addil L'%2,%%r26", xoperands); @@ -8944,40 +8955,15 @@ pa_following_call (rtx insn) } /* We use this hook to perform a PA specific optimization which is difficult - to do in earlier passes. - - We surround the jump table itself with BEGIN_BRTAB and END_BRTAB - insns. Those insns mark where we should emit .begin_brtab and - .end_brtab directives when using GAS. This allows for better link - time optimizations. */ + to do in earlier passes. */ static void pa_reorg (void) { - rtx insn; - remove_useless_addtr_insns (1); if (pa_cpu < PROCESSOR_8000) pa_combine_instructions (); - - /* Still need brtab marker insns. FIXME: the presence of these - markers disables output of the branch table to readonly memory, - and any alignment directives that might be needed. Possibly, - the begin_brtab insn should be output before the label for the - table. This doesn't matter at the moment since the tables are - always output in the text section. */ - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - { - /* Find an ADDR_VEC insn. */ - if (! JUMP_TABLE_DATA_P (insn)) - continue; - - /* Now generate markers for the beginning and end of the - branch table. */ - emit_insn_before (gen_begin_brtab (), insn); - emit_insn_after (gen_end_brtab (), insn); - } } /* The PA has a number of odd instructions which can perform multiple @@ -10572,4 +10558,46 @@ pa_legitimize_reload_address (rtx ad, enum machine_mode mode, return NULL_RTX; } +/* Output address vector. */ + +void +pa_output_addr_vec (rtx lab, rtx body) +{ + int idx, vlen = XVECLEN (body, 0); + + targetm.asm_out.internal_label (asm_out_file, "L", CODE_LABEL_NUMBER (lab)); + if (TARGET_GAS) + fputs ("\t.begin_brtab\n", asm_out_file); + for (idx = 0; idx < vlen; idx++) + { + ASM_OUTPUT_ADDR_VEC_ELT + (asm_out_file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0))); + } + if (TARGET_GAS) + fputs ("\t.end_brtab\n", asm_out_file); +} + +/* Output address difference vector. */ + +void +pa_output_addr_diff_vec (rtx lab, rtx body) +{ + rtx base = XEXP (XEXP (body, 0), 0); + int idx, vlen = XVECLEN (body, 1); + + targetm.asm_out.internal_label (asm_out_file, "L", CODE_LABEL_NUMBER (lab)); + if (TARGET_GAS) + fputs ("\t.begin_brtab\n", asm_out_file); + for (idx = 0; idx < vlen; idx++) + { + ASM_OUTPUT_ADDR_DIFF_ELT + (asm_out_file, + body, + CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)), + CODE_LABEL_NUMBER (base)); + } + if (TARGET_GAS) + fputs ("\t.end_brtab\n", asm_out_file); +} + #include "gt-pa.h" diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index ac3f0ebe74e..f6c9751a252 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -1193,6 +1193,16 @@ do { \ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ fprintf (FILE, "\t.word L$%04d-L$%04d\n", VALUE, REL) +/* This is how to output an absolute case-vector. */ + +#define ASM_OUTPUT_ADDR_VEC(LAB,BODY) \ + pa_output_addr_vec ((LAB),(BODY)) + +/* This is how to output a relative case-vector. */ + +#define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,BODY) \ + pa_output_addr_diff_vec ((LAB),(BODY)) + /* This is how to output an assembler line that says to advance the location counter to a multiple of 2**LOG bytes. */ diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index e55d0b86b90..a9421ac2e61 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -8508,36 +8508,6 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" [(set_attr "type" "move") (set_attr "length" "4")]) -;; These are just placeholders so we know where branch tables -;; begin and end. -(define_insn "begin_brtab" - [(const_int 1)] - "" - "* -{ - /* Only GAS actually supports this pseudo-op. */ - if (TARGET_GAS) - return \".begin_brtab\"; - else - return \"\"; -}" - [(set_attr "type" "move") - (set_attr "length" "0")]) - -(define_insn "end_brtab" - [(const_int 2)] - "" - "* -{ - /* Only GAS actually supports this pseudo-op. */ - if (TARGET_GAS) - return \".end_brtab\"; - else - return \"\"; -}" - [(set_attr "type" "move") - (set_attr "length" "0")]) - ;;; EH does longjmp's from and within the data section. Thus, ;;; an interspace branch is required for the longjmp implementation. ;;; Registers r1 and r2 are used as scratch registers for the jump diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md index 9d6a3bbe7c8..78a3ff0d2c2 100644 --- a/gcc/config/rs6000/constraints.md +++ b/gcc/config/rs6000/constraints.md @@ -68,6 +68,20 @@ (define_register_constraint "wg" "rs6000_constraints[RS6000_CONSTRAINT_wg]" "If -mmfpgpr was used, a floating point register or NO_REGS.") +(define_register_constraint "wh" "rs6000_constraints[RS6000_CONSTRAINT_wh]" + "Floating point register if direct moves are available, or NO_REGS.") + +;; At present, DImode is not allowed in the Altivec registers. If in the +;; future it is allowed, wi/wj can be set to VSX_REGS instead of FLOAT_REGS. +(define_register_constraint "wi" "rs6000_constraints[RS6000_CONSTRAINT_wi]" + "FP or VSX register to hold 64-bit integers for VSX insns or NO_REGS.") + +(define_register_constraint "wj" "rs6000_constraints[RS6000_CONSTRAINT_wj]" + "FP or VSX register to hold 64-bit integers for direct moves or NO_REGS.") + +(define_register_constraint "wk" "rs6000_constraints[RS6000_CONSTRAINT_wk]" + "FP or VSX register to hold 64-bit doubles for direct moves or NO_REGS.") + (define_register_constraint "wl" "rs6000_constraints[RS6000_CONSTRAINT_wl]" "Floating point register if the LFIWAX instruction is enabled or NO_REGS.") @@ -101,7 +115,7 @@ "Floating point register if the STFIWX instruction is enabled or NO_REGS.") (define_register_constraint "wy" "rs6000_constraints[RS6000_CONSTRAINT_wy]" - "VSX vector register to hold scalar float values or NO_REGS.") + "FP or VSX register to perform ISA 2.07 float ops or NO_REGS.") (define_register_constraint "wz" "rs6000_constraints[RS6000_CONSTRAINT_wz]" "Floating point register if the LFIWZX instruction is enabled or NO_REGS.") diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6894205fa5e..28ccf86df19 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -388,6 +388,7 @@ struct rs6000_reg_addr { enum insn_code reload_gpr_vsx; /* INSN to move from GPR to VSX. */ enum insn_code reload_vsx_gpr; /* INSN to move from VSX to GPR. */ addr_mask_type addr_mask[(int)N_RELOAD_REG]; /* Valid address masks. */ + bool scalar_in_vmx_p; /* Scalar value can go in VMX. */ }; static struct rs6000_reg_addr reg_addr[NUM_MACHINE_MODES]; @@ -1733,8 +1734,7 @@ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode) asked for it. */ if (TARGET_VSX && VSX_REGNO_P (regno) && (VECTOR_MEM_VSX_P (mode) - || (TARGET_VSX_SCALAR_FLOAT && mode == SFmode) - || (TARGET_VSX_SCALAR_DOUBLE && (mode == DFmode || mode == DImode)) + || reg_addr[mode].scalar_in_vmx_p || (TARGET_VSX_TIMODE && mode == TImode) || (TARGET_VADDUQM && mode == V1TImode))) { @@ -1743,10 +1743,7 @@ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode) if (ALTIVEC_REGNO_P (regno)) { - if (mode == SFmode && !TARGET_UPPER_REGS_SF) - return 0; - - if ((mode == DFmode || mode == DImode) && !TARGET_UPPER_REGS_DF) + if (GET_MODE_SIZE (mode) != 16 && !reg_addr[mode].scalar_in_vmx_p) return 0; return ALTIVEC_REGNO_P (last_regno); @@ -1926,14 +1923,16 @@ rs6000_debug_print_mode (ssize_t m) if (rs6000_vector_unit[m] != VECTOR_NONE || rs6000_vector_mem[m] != VECTOR_NONE || (reg_addr[m].reload_store != CODE_FOR_nothing) - || (reg_addr[m].reload_load != CODE_FOR_nothing)) + || (reg_addr[m].reload_load != CODE_FOR_nothing) + || reg_addr[m].scalar_in_vmx_p) { fprintf (stderr, - " Vector-arith=%-10s Vector-mem=%-10s Reload=%c%c", + " Vector-arith=%-10s Vector-mem=%-10s Reload=%c%c Upper=%c", rs6000_debug_vector_unit (rs6000_vector_unit[m]), rs6000_debug_vector_unit (rs6000_vector_mem[m]), (reg_addr[m].reload_store != CODE_FOR_nothing) ? 's' : '*', - (reg_addr[m].reload_load != CODE_FOR_nothing) ? 'l' : '*'); + (reg_addr[m].reload_load != CODE_FOR_nothing) ? 'l' : '*', + (reg_addr[m].scalar_in_vmx_p) ? 'y' : 'n'); } fputs ("\n", stderr); @@ -2050,6 +2049,10 @@ rs6000_debug_reg_global (void) "wd reg_class = %s\n" "wf reg_class = %s\n" "wg reg_class = %s\n" + "wh reg_class = %s\n" + "wi reg_class = %s\n" + "wj reg_class = %s\n" + "wk reg_class = %s\n" "wl reg_class = %s\n" "wm reg_class = %s\n" "wr reg_class = %s\n" @@ -2069,6 +2072,10 @@ rs6000_debug_reg_global (void) reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wg]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wh]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wi]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wj]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wk]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wl]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wm]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wr]], @@ -2357,6 +2364,8 @@ rs6000_setup_reg_addr_masks (void) for (m = 0; m < NUM_MACHINE_MODES; ++m) { + enum machine_mode m2 = (enum machine_mode)m; + /* SDmode is special in that we want to access it only via REG+REG addressing on power7 and above, since we want to use the LFIWZX and STFIWZX instructions to load it. */ @@ -2391,13 +2400,12 @@ rs6000_setup_reg_addr_masks (void) if (TARGET_UPDATE && (rc == RELOAD_REG_GPR || rc == RELOAD_REG_FPR) - && GET_MODE_SIZE (m) <= 8 - && !VECTOR_MODE_P (m) - && !COMPLEX_MODE_P (m) + && GET_MODE_SIZE (m2) <= 8 + && !VECTOR_MODE_P (m2) + && !COMPLEX_MODE_P (m2) && !indexed_only_p - && !(TARGET_E500_DOUBLE && GET_MODE_SIZE (m) == 8) - && !(m == DFmode && TARGET_UPPER_REGS_DF) - && !(m == SFmode && TARGET_UPPER_REGS_SF)) + && !(TARGET_E500_DOUBLE && GET_MODE_SIZE (m2) == 8) + && !reg_addr[m2].scalar_in_vmx_p) { addr_mask |= RELOAD_REG_PRE_INCDEC; @@ -2628,37 +2636,44 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) f - Register class to use with traditional SFmode instructions. v - Altivec register. wa - Any VSX register. + wc - Reserved to represent individual CR bits (used in LLVM). wd - Preferred register class for V2DFmode. wf - Preferred register class for V4SFmode. wg - Float register for power6x move insns. + wh - FP register for direct move instructions. + wi - FP or VSX register to hold 64-bit integers for VSX insns. + wj - FP or VSX register to hold 64-bit integers for direct moves. + wk - FP or VSX register to hold 64-bit doubles for direct moves. wl - Float register if we can do 32-bit signed int loads. wm - VSX register for ISA 2.07 direct move operations. + wn - always NO_REGS. wr - GPR if 64-bit mode is permitted. ws - Register class to do ISA 2.06 DF operations. + wt - VSX register for TImode in VSX registers. wu - Altivec register for ISA 2.07 VSX SF/SI load/stores. wv - Altivec register for ISA 2.06 VSX DF/DI load/stores. - wt - VSX register for TImode in VSX registers. ww - Register class to do SF conversions in with VSX operations. wx - Float register if we can do 32-bit int stores. wy - Register class to do ISA 2.07 SF operations. wz - Float register if we can do 32-bit unsigned int loads. */ if (TARGET_HARD_FLOAT && TARGET_FPRS) - rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS; + rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS; /* SFmode */ if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) - rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS; + rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS; /* DFmode */ if (TARGET_VSX) { rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS; - rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS; - rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS; /* V2DFmode */ + rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS; /* V4SFmode */ + rs6000_constraints[RS6000_CONSTRAINT_wi] = FLOAT_REGS; /* DImode */ if (TARGET_VSX_TIMODE) - rs6000_constraints[RS6000_CONSTRAINT_wt] = VSX_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wt] = VSX_REGS; /* TImode */ - if (TARGET_UPPER_REGS_DF) + if (TARGET_UPPER_REGS_DF) /* DFmode */ { rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS; rs6000_constraints[RS6000_CONSTRAINT_wv] = ALTIVEC_REGS; @@ -2672,19 +2687,26 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) if (TARGET_ALTIVEC) rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS; - if (TARGET_MFPGPR) + if (TARGET_MFPGPR) /* DFmode */ rs6000_constraints[RS6000_CONSTRAINT_wg] = FLOAT_REGS; if (TARGET_LFIWAX) - rs6000_constraints[RS6000_CONSTRAINT_wl] = FLOAT_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wl] = FLOAT_REGS; /* DImode */ if (TARGET_DIRECT_MOVE) - rs6000_constraints[RS6000_CONSTRAINT_wm] = VSX_REGS; + { + rs6000_constraints[RS6000_CONSTRAINT_wh] = FLOAT_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wj] /* DImode */ + = rs6000_constraints[RS6000_CONSTRAINT_wi]; + rs6000_constraints[RS6000_CONSTRAINT_wk] /* DFmode */ + = rs6000_constraints[RS6000_CONSTRAINT_ws]; + rs6000_constraints[RS6000_CONSTRAINT_wm] = VSX_REGS; + } if (TARGET_POWERPC64) rs6000_constraints[RS6000_CONSTRAINT_wr] = GENERAL_REGS; - if (TARGET_P8_VECTOR && TARGET_UPPER_REGS_SF) + if (TARGET_P8_VECTOR && TARGET_UPPER_REGS_SF) /* SFmode */ { rs6000_constraints[RS6000_CONSTRAINT_wu] = ALTIVEC_REGS; rs6000_constraints[RS6000_CONSTRAINT_wy] = VSX_REGS; @@ -2699,10 +2721,10 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) rs6000_constraints[RS6000_CONSTRAINT_ww] = FLOAT_REGS; if (TARGET_STFIWX) - rs6000_constraints[RS6000_CONSTRAINT_wx] = FLOAT_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wx] = FLOAT_REGS; /* DImode */ if (TARGET_LFIWZX) - rs6000_constraints[RS6000_CONSTRAINT_wz] = FLOAT_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wz] = FLOAT_REGS; /* DImode */ /* Set up the reload helper and direct move functions. */ if (TARGET_VSX || TARGET_ALTIVEC) @@ -2725,10 +2747,11 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) reg_addr[V2DFmode].reload_load = CODE_FOR_reload_v2df_di_load; if (TARGET_VSX && TARGET_UPPER_REGS_DF) { - reg_addr[DFmode].reload_store = CODE_FOR_reload_df_di_store; - reg_addr[DFmode].reload_load = CODE_FOR_reload_df_di_load; - reg_addr[DDmode].reload_store = CODE_FOR_reload_dd_di_store; - reg_addr[DDmode].reload_load = CODE_FOR_reload_dd_di_load; + reg_addr[DFmode].reload_store = CODE_FOR_reload_df_di_store; + reg_addr[DFmode].reload_load = CODE_FOR_reload_df_di_load; + reg_addr[DFmode].scalar_in_vmx_p = true; + reg_addr[DDmode].reload_store = CODE_FOR_reload_dd_di_store; + reg_addr[DDmode].reload_load = CODE_FOR_reload_dd_di_load; } if (TARGET_P8_VECTOR) { @@ -2736,6 +2759,8 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) reg_addr[SFmode].reload_load = CODE_FOR_reload_sf_di_load; reg_addr[SDmode].reload_store = CODE_FOR_reload_sd_di_store; reg_addr[SDmode].reload_load = CODE_FOR_reload_sd_di_load; + if (TARGET_UPPER_REGS_SF) + reg_addr[SFmode].scalar_in_vmx_p = true; } if (TARGET_VSX_TIMODE) { @@ -2792,10 +2817,11 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) reg_addr[V2DFmode].reload_load = CODE_FOR_reload_v2df_si_load; if (TARGET_VSX && TARGET_UPPER_REGS_DF) { - reg_addr[DFmode].reload_store = CODE_FOR_reload_df_si_store; - reg_addr[DFmode].reload_load = CODE_FOR_reload_df_si_load; - reg_addr[DDmode].reload_store = CODE_FOR_reload_dd_si_store; - reg_addr[DDmode].reload_load = CODE_FOR_reload_dd_si_load; + reg_addr[DFmode].reload_store = CODE_FOR_reload_df_si_store; + reg_addr[DFmode].reload_load = CODE_FOR_reload_df_si_load; + reg_addr[DFmode].scalar_in_vmx_p = true; + reg_addr[DDmode].reload_store = CODE_FOR_reload_dd_si_store; + reg_addr[DDmode].reload_load = CODE_FOR_reload_dd_si_load; } if (TARGET_P8_VECTOR) { @@ -2803,6 +2829,8 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) reg_addr[SFmode].reload_load = CODE_FOR_reload_sf_si_load; reg_addr[SDmode].reload_store = CODE_FOR_reload_sd_si_store; reg_addr[SDmode].reload_load = CODE_FOR_reload_sd_si_load; + if (TARGET_UPPER_REGS_SF) + reg_addr[SFmode].scalar_in_vmx_p = true; } if (TARGET_VSX_TIMODE) { @@ -2843,6 +2871,7 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) for (m = 0; m < NUM_MACHINE_MODES; ++m) { + enum machine_mode m2 = (enum machine_mode)m; int reg_size2 = reg_size; /* TFmode/TDmode always takes 2 registers, even in VSX. */ @@ -2851,7 +2880,7 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) reg_size2 = UNITS_PER_FP_WORD; rs6000_class_max_nregs[m][c] - = (GET_MODE_SIZE (m) + reg_size2 - 1) / reg_size2; + = (GET_MODE_SIZE (m2) + reg_size2 - 1) / reg_size2; } } @@ -17177,7 +17206,14 @@ rs6000_preferred_reload_class (rtx x, enum reg_class rclass) prefer Altivec loads.. */ if (rclass == VSX_REGS) { - if (GET_MODE_SIZE (mode) <= 8) + if (MEM_P (x) && reg_addr[mode].scalar_in_vmx_p) + { + rtx addr = XEXP (x, 0); + if (rs6000_legitimate_offset_address_p (mode, addr, false, true) + || legitimate_lo_sum_address_p (mode, addr, false)) + return FLOAT_REGS; + } + else if (GET_MODE_SIZE (mode) <= 8 && !reg_addr[mode].scalar_in_vmx_p) return FLOAT_REGS; if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 102191da692..f36386770d7 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1478,6 +1478,10 @@ enum r6000_reg_class_enum { RS6000_CONSTRAINT_wd, /* VSX register for V2DF */ RS6000_CONSTRAINT_wf, /* VSX register for V4SF */ RS6000_CONSTRAINT_wg, /* FPR register for -mmfpgpr */ + RS6000_CONSTRAINT_wh, /* FPR register for direct moves. */ + RS6000_CONSTRAINT_wi, /* FPR/VSX register to hold DImode */ + RS6000_CONSTRAINT_wj, /* FPR/VSX register for DImode direct moves. */ + RS6000_CONSTRAINT_wk, /* FPR/VSX register for DFmode direct moves. */ RS6000_CONSTRAINT_wl, /* FPR register for LFIWAX */ RS6000_CONSTRAINT_wm, /* VSX register for direct move */ RS6000_CONSTRAINT_wr, /* GPR register if 64-bit */ @@ -1502,6 +1506,9 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; #define VSX_REG_CLASS_P(CLASS) \ ((CLASS) == VSX_REGS || (CLASS) == FLOAT_REGS || (CLASS) == ALTIVEC_REGS) +/* Return whether a given register class targets general purpose registers. */ +#define GPR_REG_CLASS_P(CLASS) ((CLASS) == GENERAL_REGS || (CLASS) == BASE_REGS) + /* Given an rtx X being reloaded into a reg required to be in class CLASS, return the class of reg to actually use. In general this is just CLASS; but on some machines diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index bc494476c5c..d078491e1f2 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -328,7 +328,7 @@ (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")]) ; Definitions for 32-bit fpr direct move -(define_mode_attr f32_dm [(SF "wn") (SD "wm")]) +(define_mode_attr f32_dm [(SF "wn") (SD "wh")]) ; These modes do not fit in integer registers in 32-bit mode. ; but on e500v2, the gpr are 64 bit registers @@ -577,7 +577,7 @@ "") (define_insn "*zero_extendsidi2_lfiwzx" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,??wm,!wz,!wu") + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu") (zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))] "TARGET_POWERPC64 && TARGET_LFIWZX" "@ @@ -747,7 +747,7 @@ "") (define_insn "*extendsidi2_lfiwax" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,??wm,!wl,!wu") + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu") (sign_extend:DI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))] "TARGET_POWERPC64 && TARGET_LFIWAX" "@ @@ -5625,7 +5625,7 @@ ; We don't define lfiwax/lfiwzx with the normal definition, because we ; don't want to support putting SImode in FPR registers. (define_insn "lfiwax" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wm,!wm") + [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj") (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")] UNSPEC_LFIWAX))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX" @@ -5705,7 +5705,7 @@ (set_attr "type" "fpload")]) (define_insn "lfiwzx" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wm,!wm") + [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj") (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")] UNSPEC_LFIWZX))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX" @@ -9459,8 +9459,8 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*mov<mode>_hardfloat64" - [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,wv,Z,wa,wa,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,wm") - (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,wv,wa,j,r,Y,r,r,h,0,G,H,F,wg,r,wm,r"))] + [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,wv,Z,wa,wa,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,wk") + (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,wv,wa,j,r,Y,r,r,h,0,G,H,F,wg,r,wk,r"))] "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" @@ -10239,8 +10239,8 @@ { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_insn "*movdi_internal64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wm,?*wm") - (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wm,r,O"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi") + (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))] "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 6d20eab111b..2cf5e7a9490 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -86,19 +86,26 @@ (V4SF "wf") (V2DI "wd") (V2DF "wd") + (DI "wi") (DF "ws") - (SF "d") + (SF "ww") (V1TI "v") (TI "wt")]) -;; Map the register class used for float<->int conversions +;; Map the register class used for float<->int conversions (floating point side) +;; VSr2 is the preferred register class, VSr3 is any register class that will +;; hold the data (define_mode_attr VSr2 [(V2DF "wd") (V4SF "wf") - (DF "ws")]) + (DF "ws") + (SF "ww") + (DI "wi")]) (define_mode_attr VSr3 [(V2DF "wa") (V4SF "wa") - (DF "ws")]) + (DF "ws") + (SF "ww") + (DI "wi")]) ;; Map the register class for sp<->dp float conversions, destination (define_mode_attr VSr4 [(SF "ws") @@ -106,12 +113,27 @@ (V2DF "wd") (V4SF "v")]) -;; Map the register class for sp<->dp float conversions, destination +;; Map the register class for sp<->dp float conversions, source (define_mode_attr VSr5 [(SF "ws") (DF "f") (V2DF "v") (V4SF "wd")]) +;; The VSX register class that a type can occupy, even if it is not the +;; preferred register class (VSr is the preferred register class that will get +;; allocated first). +(define_mode_attr VSa [(V16QI "wa") + (V8HI "wa") + (V4SI "wa") + (V4SF "wa") + (V2DI "wa") + (V2DF "wa") + (DI "wi") + (DF "ws") + (SF "ww") + (V1TI "wa") + (TI "wt")]) + ;; Same size integer type for floating point data (define_mode_attr VSi [(V4SF "v4si") (V2DF "v2di") @@ -207,6 +229,16 @@ (V2DF "V4DF") (V1TI "V2TI")]) +;; Map register class for 64-bit element in 128-bit vector for direct moves +;; to/from gprs +(define_mode_attr VS_64dm [(V2DF "wk") + (V2DI "wj")]) + +;; Map register class for 64-bit element in 128-bit vector for normal register +;; to register moves +(define_mode_attr VS_64reg [(V2DF "ws") + (V2DI "wi")]) + ;; Constants for creating unspecs (define_c_enum "unspec" [UNSPEC_VSX_CONCAT @@ -235,7 +267,7 @@ ;; The patterns for LE permuted loads and stores come before the general ;; VSX moves so they match first. (define_insn_and_split "*vsx_le_perm_load_<mode>" - [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=wa") + [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=<VSa>") (match_operand:VSX_LE 1 "memory_operand" "Z"))] "!BYTES_BIG_ENDIAN && TARGET_VSX" "#" @@ -258,7 +290,7 @@ (set_attr "length" "8")]) (define_insn_and_split "*vsx_le_perm_load_<mode>" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wa") + [(set (match_operand:VSX_W 0 "vsx_register_operand" "=<VSa>") (match_operand:VSX_W 1 "memory_operand" "Z"))] "!BYTES_BIG_ENDIAN && TARGET_VSX" "#" @@ -350,7 +382,7 @@ (define_insn "*vsx_le_perm_store_<mode>" [(set (match_operand:VSX_LE 0 "memory_operand" "=Z") - (match_operand:VSX_LE 1 "vsx_register_operand" "+wa"))] + (match_operand:VSX_LE 1 "vsx_register_operand" "+<VSa>"))] "!BYTES_BIG_ENDIAN && TARGET_VSX" "#" [(set_attr "type" "vecstore") @@ -395,7 +427,7 @@ (define_insn "*vsx_le_perm_store_<mode>" [(set (match_operand:VSX_W 0 "memory_operand" "=Z") - (match_operand:VSX_W 1 "vsx_register_operand" "+wa"))] + (match_operand:VSX_W 1 "vsx_register_operand" "+<VSa>"))] "!BYTES_BIG_ENDIAN && TARGET_VSX" "#" [(set_attr "type" "vecstore") @@ -585,8 +617,8 @@ (define_insn "*vsx_mov<mode>" - [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=Z,<VSr>,<VSr>,?Z,?wa,?wa,wQ,?&r,??Y,??r,??r,<VSr>,?wa,*r,v,wZ, v") - (match_operand:VSX_M 1 "input_operand" "<VSr>,Z,<VSr>,wa,Z,wa,r,wQ,r,Y,r,j,j,j,W,v,wZ"))] + [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=Z,<VSr>,<VSr>,?Z,?<VSa>,?<VSa>,wQ,?&r,??Y,??r,??r,<VSr>,?<VSa>,*r,v,wZ, v") + (match_operand:VSX_M 1 "input_operand" "<VSr>,Z,<VSr>,<VSa>,Z,<VSa>,r,wQ,r,Y,r,j,j,j,W,v,wZ"))] "VECTOR_MEM_VSX_P (<MODE>mode) && (register_operand (operands[0], <MODE>mode) || register_operand (operands[1], <MODE>mode))" @@ -688,36 +720,36 @@ ;; instructions are now combined with the insn for the traditional floating ;; point unit. (define_insn "*vsx_add<mode>3" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (plus:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (plus:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvadd<VSs> %x0,%x1,%x2" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "*vsx_sub<mode>3" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (minus:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (minus:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvsub<VSs> %x0,%x1,%x2" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "*vsx_mul<mode>3" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (mult:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (mult:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvmul<VSs> %x0,%x1,%x2" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_mul>")]) (define_insn "*vsx_div<mode>3" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (div:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (div:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvdiv<VSs> %x0,%x1,%x2" [(set_attr "type" "<VStype_div>") @@ -753,8 +785,8 @@ (define_insn "*vsx_tdiv<mode>3_internal" [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x") - (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")] + (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,<VSa>")] UNSPEC_VSX_TDIV))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "x<VSv>tdiv<VSs> %0,%x1,%x2" @@ -762,8 +794,8 @@ (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "vsx_fre<mode>2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")] UNSPEC_FRES))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvre<VSs> %x0,%x1" @@ -771,60 +803,60 @@ (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "*vsx_neg<mode>2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (neg:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (neg:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvneg<VSs> %x0,%x1" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "*vsx_abs<mode>2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (abs:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (abs:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvabs<VSs> %x0,%x1" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "vsx_nabs<mode>2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") (neg:VSX_F (abs:VSX_F - (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa"))))] + (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>"))))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvnabs<VSs> %x0,%x1" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "vsx_smax<mode>3" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (smax:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (smax:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvmax<VSs> %x0,%x1,%x2" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "*vsx_smin<mode>3" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (smin:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (smin:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvmin<VSs> %x0,%x1,%x2" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "*vsx_sqrt<mode>2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (sqrt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (sqrt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvsqrt<VSs> %x0,%x1" [(set_attr "type" "<VStype_sqrt>") (set_attr "fp_type" "<VSfptype_sqrt>")]) (define_insn "*vsx_rsqrte<mode>2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")] UNSPEC_RSQRT))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvrsqrte<VSs> %x0,%x1" @@ -859,7 +891,7 @@ (define_insn "*vsx_tsqrt<mode>2_internal" [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x") - (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSa>")] UNSPEC_VSX_TSQRT))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "x<VSv>tsqrt<VSs> %0,%x1" @@ -901,12 +933,12 @@ [(set_attr "type" "vecdouble")]) (define_insn "*vsx_fms<mode>4" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,<VSr>,?<VSa>,?<VSa>") (fma:VSX_F - (match_operand:VSX_F 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,0,wa,0") + (match_operand:VSX_F 1 "vsx_register_operand" "%<VSr>,<VSr>,<VSa>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,0,<VSa>,0") (neg:VSX_F - (match_operand:VSX_F 3 "vsx_register_operand" "0,<VSr>,0,wa"))))] + (match_operand:VSX_F 3 "vsx_register_operand" "0,<VSr>,0,<VSa>"))))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "@ xvmsuba<VSs> %x0,%x1,%x2 @@ -916,12 +948,12 @@ [(set_attr "type" "<VStype_mul>")]) (define_insn "*vsx_nfma<mode>4" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,<VSr>,?<VSa>,?<VSa>") (neg:VSX_F (fma:VSX_F - (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSr>,wa,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,0,wa,0") - (match_operand:VSX_F 3 "vsx_register_operand" "0,<VSr>,0,wa"))))] + (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSr>,<VSa>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,0,<VSa>,0") + (match_operand:VSX_F 3 "vsx_register_operand" "0,<VSr>,0,<VSa>"))))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "@ xvnmadda<VSs> %x0,%x1,%x2 @@ -966,27 +998,27 @@ ;; Vector conditional expressions (no scalar version for these instructions) (define_insn "vsx_eq<mode>" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (eq:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (eq:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvcmpeq<VSs> %x0,%x1,%x2" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "vsx_gt<mode>" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (gt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (gt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvcmpgt<VSs> %x0,%x1,%x2" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "*vsx_ge<mode>" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (ge:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (ge:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvcmpge<VSs> %x0,%x1,%x2" [(set_attr "type" "<VStype_simple>") @@ -997,10 +1029,10 @@ (define_insn "*vsx_eq_<mode>_p" [(set (reg:CC 74) (unspec:CC - [(eq:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?wa"))] + [(eq:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?<VSa>"))] UNSPEC_PREDICATE)) - (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") (eq:VSX_F (match_dup 1) (match_dup 2)))] "VECTOR_UNIT_VSX_P (<MODE>mode)" @@ -1010,10 +1042,10 @@ (define_insn "*vsx_gt_<mode>_p" [(set (reg:CC 74) (unspec:CC - [(gt:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?wa"))] + [(gt:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?<VSa>"))] UNSPEC_PREDICATE)) - (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") (gt:VSX_F (match_dup 1) (match_dup 2)))] "VECTOR_UNIT_VSX_P (<MODE>mode)" @@ -1023,10 +1055,10 @@ (define_insn "*vsx_ge_<mode>_p" [(set (reg:CC 74) (unspec:CC - [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?wa"))] + [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?<VSa>"))] UNSPEC_PREDICATE)) - (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") (ge:VSX_F (match_dup 1) (match_dup 2)))] "VECTOR_UNIT_VSX_P (<MODE>mode)" @@ -1035,33 +1067,33 @@ ;; Vector select (define_insn "*vsx_xxsel<mode>" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?<VSa>") (if_then_else:VSX_L - (ne:CC (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,wa") + (ne:CC (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,<VSa>") (match_operand:VSX_L 4 "zero_constant" "")) - (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,wa")))] + (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_MEM_VSX_P (<MODE>mode)" "xxsel %x0,%x3,%x2,%x1" [(set_attr "type" "vecperm")]) (define_insn "*vsx_xxsel<mode>_uns" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?<VSa>") (if_then_else:VSX_L - (ne:CCUNS (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,wa") + (ne:CCUNS (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,<VSa>") (match_operand:VSX_L 4 "zero_constant" "")) - (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,wa")))] + (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_MEM_VSX_P (<MODE>mode)" "xxsel %x0,%x3,%x2,%x1" [(set_attr "type" "vecperm")]) ;; Copy sign (define_insn "vsx_copysign<mode>3" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") (unspec:VSX_F - [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")] + [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>") + (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")] UNSPEC_COPYSIGN))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvcpsgn<VSs> %x0,%x2,%x1" @@ -1074,7 +1106,7 @@ ;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX. ;; Don't use vsx_register_operand here, use gpc_reg_operand to match rs6000.md. (define_insn "vsx_float<VSi><mode>2" - [(set (match_operand:VSX_B 0 "gpc_reg_operand" "=<VSr>,?wa") + [(set (match_operand:VSX_B 0 "gpc_reg_operand" "=<VSr>,?<VSa>") (float:VSX_B (match_operand:<VSI> 1 "gpc_reg_operand" "<VSr2>,<VSr3>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "x<VSv>cvsx<VSc><VSs> %x0,%x1" @@ -1082,7 +1114,7 @@ (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "vsx_floatuns<VSi><mode>2" - [(set (match_operand:VSX_B 0 "gpc_reg_operand" "=<VSr>,?wa") + [(set (match_operand:VSX_B 0 "gpc_reg_operand" "=<VSr>,?<VSa>") (unsigned_float:VSX_B (match_operand:<VSI> 1 "gpc_reg_operand" "<VSr2>,<VSr3>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "x<VSv>cvux<VSc><VSs> %x0,%x1" @@ -1091,7 +1123,7 @@ (define_insn "vsx_fix_trunc<mode><VSi>2" [(set (match_operand:<VSI> 0 "gpc_reg_operand" "=<VSr2>,?<VSr3>") - (fix:<VSI> (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,wa")))] + (fix:<VSI> (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "x<VSv>cv<VSs>sx<VSc>s %x0,%x1" [(set_attr "type" "<VStype_simple>") @@ -1099,7 +1131,7 @@ (define_insn "vsx_fixuns_trunc<mode><VSi>2" [(set (match_operand:<VSI> 0 "gpc_reg_operand" "=<VSr2>,?<VSr3>") - (unsigned_fix:<VSI> (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,wa")))] + (unsigned_fix:<VSI> (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "x<VSv>cv<VSs>ux<VSc>s %x0,%x1" [(set_attr "type" "<VStype_simple>") @@ -1107,8 +1139,8 @@ ;; Math rounding functions (define_insn "vsx_x<VSv>r<VSs>i" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSa>")] UNSPEC_VSX_ROUND_I))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "x<VSv>r<VSs>i %x0,%x1" @@ -1116,8 +1148,8 @@ (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "vsx_x<VSv>r<VSs>ic" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSa>")] UNSPEC_VSX_ROUND_IC))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "x<VSv>r<VSs>ic %x0,%x1" @@ -1125,16 +1157,16 @@ (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "vsx_btrunc<mode>2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (fix:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")))] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (fix:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvr<VSs>iz %x0,%x1" [(set_attr "type" "<VStype_simple>") (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "*vsx_b2trunc<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] + [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSa>")] UNSPEC_FRIZ))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "x<VSv>r<VSs>iz %x0,%x1" @@ -1142,8 +1174,8 @@ (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "vsx_floor<mode>2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")] UNSPEC_FRIM))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvr<VSs>im %x0,%x1" @@ -1151,8 +1183,8 @@ (set_attr "fp_type" "<VSfptype_simple>")]) (define_insn "vsx_ceil<mode>2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")] + [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>") + (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")] UNSPEC_FRIP))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "xvr<VSs>ip %x0,%x1" @@ -1167,8 +1199,8 @@ ;; scalar single precision instructions internally use the double format. ;; Prefer the altivec registers, since we likely will need to do a vperm (define_insn "vsx_<VS_spdp_insn>" - [(set (match_operand:<VS_spdp_res> 0 "vsx_register_operand" "=<VSr4>,?wa") - (unspec:<VS_spdp_res> [(match_operand:VSX_SPDP 1 "vsx_register_operand" "<VSr5>,wa")] + [(set (match_operand:<VS_spdp_res> 0 "vsx_register_operand" "=<VSr4>,?<VSa>") + (unspec:<VS_spdp_res> [(match_operand:VSX_SPDP 1 "vsx_register_operand" "<VSr5>,<VSa>")] UNSPEC_VSX_CVSPDP))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "<VS_spdp_insn> %x0,%x1" @@ -1176,8 +1208,8 @@ ;; xscvspdp, represent the scalar SF type as V4SF (define_insn "vsx_xscvspdp" - [(set (match_operand:DF 0 "vsx_register_operand" "=ws,?wa") - (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")] + [(set (match_operand:DF 0 "vsx_register_operand" "=ws") + (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wa")] UNSPEC_VSX_CVSPDP))] "VECTOR_UNIT_VSX_P (V4SFmode)" "xscvspdp %x0,%x1" @@ -1204,7 +1236,7 @@ ;; ISA 2.07 xscvdpspn/xscvspdpn that does not raise an error on signalling NaNs (define_insn "vsx_xscvdpspn" - [(set (match_operand:V4SF 0 "vsx_register_operand" "=ws,?wa") + [(set (match_operand:V4SF 0 "vsx_register_operand" "=ww,?ww") (unspec:V4SF [(match_operand:DF 1 "vsx_register_operand" "wd,wa")] UNSPEC_VSX_CVDPSPN))] "TARGET_XSCVDPSPN" @@ -1212,16 +1244,16 @@ [(set_attr "type" "fp")]) (define_insn "vsx_xscvspdpn" - [(set (match_operand:DF 0 "vsx_register_operand" "=ws,?wa") - (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")] + [(set (match_operand:DF 0 "vsx_register_operand" "=ws,?ws") + (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wf,wa")] UNSPEC_VSX_CVSPDPN))] "TARGET_XSCVSPDPN" "xscvspdpn %x0,%x1" [(set_attr "type" "fp")]) (define_insn "vsx_xscvdpspn_scalar" - [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa") - (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "f")] + [(set (match_operand:V4SF 0 "vsx_register_operand" "=wf,?wa") + (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "ww,ww")] UNSPEC_VSX_CVDPSPN))] "TARGET_XSCVDPSPN" "xscvdpspn %x0,%x1" @@ -1309,10 +1341,10 @@ ;; since the xsrdpiz instruction does not truncate the value if the floating ;; point value is < LONG_MIN or > LONG_MAX. (define_insn "*vsx_float_fix_<mode>2" - [(set (match_operand:VSX_DF 0 "vsx_register_operand" "=<VSr>,?wa") + [(set (match_operand:VSX_DF 0 "vsx_register_operand" "=<VSr>,?<VSa>") (float:VSX_DF (fix:<VSI> - (match_operand:VSX_DF 1 "vsx_register_operand" "<VSr>,?wa"))))] + (match_operand:VSX_DF 1 "vsx_register_operand" "<VSr>,?<VSa>"))))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && VECTOR_UNIT_VSX_P (<MODE>mode) && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ" @@ -1325,10 +1357,10 @@ ;; Build a V2DF/V2DI vector from two scalars (define_insn "vsx_concat_<mode>" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "=<VSr>,?wa") + [(set (match_operand:VSX_D 0 "vsx_register_operand" "=<VSr>,?<VSa>") (vec_concat:VSX_D - (match_operand:<VS_scalar> 1 "vsx_register_operand" "ws,wa") - (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,wa")))] + (match_operand:<VS_scalar> 1 "vsx_register_operand" "ws,<VSa>") + (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,<VSa>")))] "VECTOR_MEM_VSX_P (<MODE>mode)" { if (BYTES_BIG_ENDIAN) @@ -1359,18 +1391,18 @@ ;; xxpermdi for little endian loads and stores. We need several of ;; these since the form of the PARALLEL differs by mode. (define_insn "*vsx_xxpermdi2_le_<mode>" - [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=wa") + [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=<VSa>") (vec_select:VSX_LE - (match_operand:VSX_LE 1 "vsx_register_operand" "wa") + (match_operand:VSX_LE 1 "vsx_register_operand" "<VSa>") (parallel [(const_int 1) (const_int 0)])))] "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode)" "xxpermdi %x0,%x1,%x1,2" [(set_attr "type" "vecperm")]) (define_insn "*vsx_xxpermdi4_le_<mode>" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wa") + [(set (match_operand:VSX_W 0 "vsx_register_operand" "=<VSa>") (vec_select:VSX_W - (match_operand:VSX_W 1 "vsx_register_operand" "wa") + (match_operand:VSX_W 1 "vsx_register_operand" "<VSa>") (parallel [(const_int 2) (const_int 3) (const_int 0) (const_int 1)])))] "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode)" @@ -1408,7 +1440,7 @@ ;; lxvd2x for little endian loads. We need several of ;; these since the form of the PARALLEL differs by mode. (define_insn "*vsx_lxvd2x2_le_<mode>" - [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=wa") + [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=<VSa>") (vec_select:VSX_LE (match_operand:VSX_LE 1 "memory_operand" "Z") (parallel [(const_int 1) (const_int 0)])))] @@ -1417,7 +1449,7 @@ [(set_attr "type" "vecload")]) (define_insn "*vsx_lxvd2x4_le_<mode>" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wa") + [(set (match_operand:VSX_W 0 "vsx_register_operand" "=<VSa>") (vec_select:VSX_W (match_operand:VSX_W 1 "memory_operand" "Z") (parallel [(const_int 2) (const_int 3) @@ -1459,7 +1491,7 @@ (define_insn "*vsx_stxvd2x2_le_<mode>" [(set (match_operand:VSX_LE 0 "memory_operand" "=Z") (vec_select:VSX_LE - (match_operand:VSX_LE 1 "vsx_register_operand" "wa") + (match_operand:VSX_LE 1 "vsx_register_operand" "<VSa>") (parallel [(const_int 1) (const_int 0)])))] "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode)" "stxvd2x %x1,%y0" @@ -1468,7 +1500,7 @@ (define_insn "*vsx_stxvd2x4_le_<mode>" [(set (match_operand:VSX_W 0 "memory_operand" "=Z") (vec_select:VSX_W - (match_operand:VSX_W 1 "vsx_register_operand" "wa") + (match_operand:VSX_W 1 "vsx_register_operand" "<VSa>") (parallel [(const_int 2) (const_int 3) (const_int 0) (const_int 1)])))] "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode)" @@ -1520,11 +1552,12 @@ ;; Set the element of a V2DI/VD2F mode (define_insn "vsx_set_<mode>" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa") - (unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wd,wa") - (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,wa") - (match_operand:QI 3 "u5bit_cint_operand" "i,i")] - UNSPEC_VSX_SET))] + [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?<VSa>") + (unspec:VSX_D + [(match_operand:VSX_D 1 "vsx_register_operand" "wd,<VSa>") + (match_operand:<VS_scalar> 2 "vsx_register_operand" "<VS_64reg>,<VSa>") + (match_operand:QI 3 "u5bit_cint_operand" "i,i")] + UNSPEC_VSX_SET))] "VECTOR_MEM_VSX_P (<MODE>mode)" { int idx_first = BYTES_BIG_ENDIAN ? 0 : 1; @@ -1549,11 +1582,11 @@ ;; Optimize cases were we can do a simple or direct move. ;; Or see if we can avoid doing the move at all (define_insn "*vsx_extract_<mode>_internal1" - [(set (match_operand:<VS_scalar> 0 "register_operand" "=d,ws,?wa,r") + [(set (match_operand:<VS_scalar> 0 "register_operand" "=d,<VS_64reg>,r") (vec_select:<VS_scalar> - (match_operand:VSX_D 1 "register_operand" "d,wd,wa,wm") + (match_operand:VSX_D 1 "register_operand" "d,<VS_64reg>,<VS_64dm>") (parallel - [(match_operand:QI 2 "vsx_scalar_64bit" "wD,wD,wD,wD")])))] + [(match_operand:QI 2 "vsx_scalar_64bit" "wD,wD,wD")])))] "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE" { int op0_regno = REGNO (operands[0]); @@ -1570,14 +1603,14 @@ return "xxlor %x0,%x1,%x1"; } - [(set_attr "type" "fp,vecsimple,vecsimple,mftgpr") + [(set_attr "type" "fp,vecsimple,mftgpr") (set_attr "length" "4")]) (define_insn "*vsx_extract_<mode>_internal2" - [(set (match_operand:<VS_scalar> 0 "vsx_register_operand" "=d,ws,ws,?wa") + [(set (match_operand:<VS_scalar> 0 "vsx_register_operand" "=d,<VS_64reg>,<VS_64reg>") (vec_select:<VS_scalar> - (match_operand:VSX_D 1 "vsx_register_operand" "d,wd,wd,wa") - (parallel [(match_operand:QI 2 "u5bit_cint_operand" "wD,wD,i,i")])))] + (match_operand:VSX_D 1 "vsx_register_operand" "d,wd,wd") + (parallel [(match_operand:QI 2 "u5bit_cint_operand" "wD,wD,i")])))] "VECTOR_MEM_VSX_P (<MODE>mode) && (!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE || INTVAL (operands[2]) != VECTOR_ELEMENT_SCALAR_64BIT)" @@ -1605,7 +1638,7 @@ operands[3] = GEN_INT (fldDM); return "xxpermdi %x0,%x1,%x1,%3"; } - [(set_attr "type" "fp,vecsimple,vecperm,vecperm") + [(set_attr "type" "fp,vecsimple,vecperm") (set_attr "length" "4")]) ;; Optimize extracting a single scalar element from memory if the scalar is in @@ -1643,7 +1676,7 @@ (define_insn "*vsx_extract_<mode>_store" [(set (match_operand:<VS_scalar> 0 "memory_operand" "=m,Z,?Z") (vec_select:<VS_scalar> - (match_operand:VSX_D 1 "register_operand" "d,wd,wa") + (match_operand:VSX_D 1 "register_operand" "d,wd,<VSa>") (parallel [(match_operand:QI 2 "vsx_scalar_64bit" "wD,wD,wD")])))] "VECTOR_MEM_VSX_P (<MODE>mode)" "@ @@ -1666,7 +1699,7 @@ (define_insn_and_split "vsx_extract_v4sf" [(set (match_operand:SF 0 "vsx_register_operand" "=f,f") (vec_select:SF - (match_operand:V4SF 1 "vsx_register_operand" "wa,wa") + (match_operand:V4SF 1 "vsx_register_operand" "<VSa>,<VSa>") (parallel [(match_operand:QI 2 "u5bit_cint_operand" "O,i")]))) (clobber (match_scratch:V4SF 3 "=X,0"))] "VECTOR_UNIT_VSX_P (V4SFmode)" @@ -1849,9 +1882,9 @@ ;; V2DF/V2DI splat (define_insn "vsx_splat_<mode>" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,wd,wd,?wa,?wa,?wa") + [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,wd,wd,?<VSa>,?<VSa>,?<VSa>") (vec_duplicate:VSX_D - (match_operand:<VS_scalar> 1 "splat_input_operand" "ws,f,Z,wa,wa,Z")))] + (match_operand:<VS_scalar> 1 "splat_input_operand" "<VS_64reg>,f,Z,<VSa>,<VSa>,Z")))] "VECTOR_MEM_VSX_P (<MODE>mode)" "@ xxpermdi %x0,%x1,%x1,0 @@ -1864,10 +1897,10 @@ ;; V4SF/V4SI splat (define_insn "vsx_xxspltw_<mode>" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa") + [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?<VSa>") (vec_duplicate:VSX_W (vec_select:<VS_scalar> - (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa") + (match_operand:VSX_W 1 "vsx_register_operand" "wf,<VSa>") (parallel [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))] "VECTOR_MEM_VSX_P (<MODE>mode)" @@ -1880,8 +1913,8 @@ [(set_attr "type" "vecperm")]) (define_insn "vsx_xxspltw_<mode>_direct" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa") - (unspec:VSX_W [(match_operand:VSX_W 1 "vsx_register_operand" "wf,wa") + [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?<VSa>") + (unspec:VSX_W [(match_operand:VSX_W 1 "vsx_register_operand" "wf,<VSa>") (match_operand:QI 2 "u5bit_cint_operand" "i,i")] UNSPEC_VSX_XXSPLTW))] "VECTOR_MEM_VSX_P (<MODE>mode)" @@ -1890,11 +1923,11 @@ ;; V4SF/V4SI interleave (define_insn "vsx_xxmrghw_<mode>" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa") + [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?<VSa>") (vec_select:VSX_W (vec_concat:<VS_double> - (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa") - (match_operand:VSX_W 2 "vsx_register_operand" "wf,wa")) + (match_operand:VSX_W 1 "vsx_register_operand" "wf,<VSa>") + (match_operand:VSX_W 2 "vsx_register_operand" "wf,<VSa>")) (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))] "VECTOR_MEM_VSX_P (<MODE>mode)" @@ -1907,11 +1940,11 @@ [(set_attr "type" "vecperm")]) (define_insn "vsx_xxmrglw_<mode>" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa") + [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?<VSa>") (vec_select:VSX_W (vec_concat:<VS_double> - (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa") - (match_operand:VSX_W 2 "vsx_register_operand" "wf,?wa")) + (match_operand:VSX_W 1 "vsx_register_operand" "wf,<VSa>") + (match_operand:VSX_W 2 "vsx_register_operand" "wf,?<VSa>")) (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))] "VECTOR_MEM_VSX_P (<MODE>mode)" @@ -1925,9 +1958,9 @@ ;; Shift left double by word immediate (define_insn "vsx_xxsldwi_<mode>" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wa") - (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wa") - (match_operand:VSX_L 2 "vsx_register_operand" "wa") + [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSa>") + (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "<VSa>") + (match_operand:VSX_L 2 "vsx_register_operand" "<VSa>") (match_operand:QI 3 "u5bit_cint_operand" "i")] UNSPEC_VSX_SLDWI))] "VECTOR_MEM_VSX_P (<MODE>mode)" diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md index 73bb880d6f3..3af1f8a1494 100644 --- a/gcc/config/sh/predicates.md +++ b/gcc/config/sh/predicates.md @@ -398,7 +398,7 @@ (define_predicate "general_extend_operand" (match_code "subreg,reg,mem,truncate") { - if (GET_CODE (op) == TRUNCATE) + if (reload_completed && GET_CODE (op) == TRUNCATE) return arith_operand (op, mode); if (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))) diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 62dcf0cb334..3d4553a6e61 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -861,6 +861,12 @@ sh_option_override (void) targetm.asm_out.aligned_op.di = NULL; targetm.asm_out.unaligned_op.di = NULL; } + + /* User/priviledged mode is supported only on SH3*, SH4* and SH5*. + Disable it for everything else. */ + if (! (TARGET_SH3 || TARGET_SH5) && TARGET_USERMODE) + TARGET_USERMODE = false; + if (TARGET_SH1) { if (! strcmp (sh_div_str, "call-div1")) diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index ab1f0a51c22..7978be4e4bf 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -868,9 +868,9 @@ (define_insn "*cmp_div0s_0" [(set (reg:SI T_REG) - (eq:SI (lshiftrt:SI (match_operand:SI 0 "arith_reg_operand") + (eq:SI (lshiftrt:SI (match_operand:SI 0 "arith_reg_operand" "%r") (const_int 31)) - (ge:SI (match_operand:SI 1 "arith_reg_operand") + (ge:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0))))] "TARGET_SH1" "div0s %0,%1" @@ -4563,6 +4563,12 @@ label: { if (TARGET_SHMEDIA) { + if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2])); + DONE; + } emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2])); DONE; } @@ -4803,6 +4809,12 @@ label: { if (TARGET_SHMEDIA) { + if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2])); + DONE; + } emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2])); DONE; } @@ -4896,6 +4908,12 @@ label: { if (TARGET_SHMEDIA) { + if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2])); + DONE; + } emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2])); DONE; } @@ -4995,6 +5013,12 @@ label: { if (TARGET_SHMEDIA) { + if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2])); + DONE; + } emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2])); DONE; } @@ -5069,6 +5093,12 @@ label: { if (TARGET_SHMEDIA) { + if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2])); + DONE; + } emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2])); DONE; } @@ -5263,6 +5293,12 @@ label: { if (TARGET_SHMEDIA) { + if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2])); + DONE; + } emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2])); DONE; } diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt index 1834c6bde97..bb6d3958135 100644 --- a/gcc/config/sh/sh.opt +++ b/gcc/config/sh/sh.opt @@ -343,7 +343,7 @@ Target RejectNegative Joined UInteger Var(sh_multcost) Init(-1) Cost to assume for a multiply insn musermode -Target Report RejectNegative Var(TARGET_USERMODE) +Target Var(TARGET_USERMODE) Don't generate privileged-mode only code; implies -mno-inline-ic_invalidate if the inline code would not work in user mode. ;; We might want to enable this by default for TARGET_HARD_SH4, because diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 297f2afd1ad..0c7ab3320dc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,46 @@ +2014-08-26 Jason Merrill <jason@redhat.com> + + PR c++/58624 + * pt.c (tsubst_copy_and_build) [VAR_DECL]: Use TLS wrapper. + * semantics.c (finish_id_expression): Don't call TLS wrapper in a + template. + +2014-08-25 Jason Merrill <jason@redhat.com> + + PR c++/62129 + * class.c (outermost_open_class): New. + * cp-tree.h: Declare it. + * decl.c (maybe_register_incomplete_var): Use it. + (complete_vars): Handle any constant variable. + * expr.c (cplus_expand_constant): Handle CONSTRUCTOR. + +2014-08-22 Igor Zamyatin <igor.zamyatin@intel.com> + + PR other/62008 + * cp-array-notation.c (build_array_notation_ref): Added correct + handling of case with incorrect array. + +2014-08-19 Jason Merrill <jason@redhat.com> + + PR c++/61214 + PR tree-optimization/62091 + * decl2.c (decl_needed_p): Return true for virtual functions when + devirtualizing. + + Backport: + PR c++/61566 + * pt.c (instantiate_class_template_1): Ignore lambda on + CLASSTYPE_DECL_LIST. + (push_template_decl_real): A lambda is not primary. + * lambda.c (maybe_add_lambda_conv_op): Distinguish between being + currently in a function and the lambda living in a function. + + Backport: + PR c++/60417 + * init.c (build_vec_init): Set CONSTRUCTOR_IS_DIRECT_INIT on + init-list for trailing elements. + * typeck2.c (process_init_constructor_array): Likewise. + 2014-08-07 Jason Merrill <jason@redhat.com> PR c++/61959 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index f4fb4c97290..042a43d2875 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -7251,6 +7251,29 @@ currently_open_derived_class (tree t) return NULL_TREE; } +/* Return the outermost enclosing class type that is still open, or + NULL_TREE. */ + +tree +outermost_open_class (void) +{ + if (!current_class_type) + return NULL_TREE; + tree r = NULL_TREE; + if (TYPE_BEING_DEFINED (current_class_type)) + r = current_class_type; + for (int i = current_class_depth - 1; i > 0; --i) + { + if (current_class_stack[i].hidden) + break; + tree t = current_class_stack[i].type; + if (!TYPE_BEING_DEFINED (t)) + break; + r = t; + } + return r; +} + /* Returns the innermost class type which is not a lambda closure type. */ tree diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c index de9cc401249..a50ff1dc9af 100644 --- a/gcc/cp/cp-array-notation.c +++ b/gcc/cp/cp-array-notation.c @@ -1403,7 +1403,10 @@ build_array_notation_ref (location_t loc, tree array, tree start, tree length, if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == POINTER_TYPE) TREE_TYPE (array_ntn_expr) = TREE_TYPE (type); else - gcc_unreachable (); + { + error_at (loc, "base of array section must be pointer or array type"); + return error_mark_node; + } SET_EXPR_LOCATION (array_ntn_expr, loc); return array_ntn_expr; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 26a63d0b270..0b52dff3fdb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5112,6 +5112,7 @@ extern void resort_type_method_vec (void *, void *, extern bool add_method (tree, tree, tree); extern bool currently_open_class (tree); extern tree currently_open_derived_class (tree); +extern tree outermost_open_class (void); extern tree current_nonlambda_class_type (void); extern tree finish_struct (tree, tree); extern void finish_struct_1 (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 19944abd186..1f3a552f94f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -14177,8 +14177,8 @@ grokmethod (cp_decl_specifier_seq *declspecs, /* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that we can lay it out later, when and if its type becomes complete. - Also handle constexpr pointer to member variables where the initializer - is an unlowered PTRMEM_CST because the class isn't complete yet. */ + Also handle constexpr variables where the initializer involves + an unlowered PTRMEM_CST because the class isn't complete yet. */ void maybe_register_incomplete_var (tree var) @@ -14203,12 +14203,13 @@ maybe_register_incomplete_var (tree var) incomplete_var iv = {var, inner_type}; vec_safe_push (incomplete_vars, iv); } - else if (TYPE_PTRMEM_P (inner_type) - && DECL_INITIAL (var) - && TREE_CODE (DECL_INITIAL (var)) == PTRMEM_CST) + else if (!(DECL_LANG_SPECIFIC (var) && DECL_TEMPLATE_INFO (var)) + && decl_constant_var_p (var) + && (TYPE_PTRMEM_P (inner_type) || CLASS_TYPE_P (inner_type))) { - tree context = TYPE_PTRMEM_CLASS_TYPE (inner_type); - gcc_assert (TYPE_BEING_DEFINED (context)); + /* When the outermost open class is complete we can resolve any + pointers-to-members. */ + tree context = outermost_open_class (); incomplete_var iv = {var, context}; vec_safe_push (incomplete_vars, iv); } @@ -14232,9 +14233,8 @@ complete_vars (tree type) tree var = iv->decl; tree type = TREE_TYPE (var); - if (TYPE_PTRMEM_P (type)) - DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var)); - else + if (TYPE_MAIN_VARIANT (strip_array_types (type)) + == iv->incomplete_type) { /* Complete the type of the variable. The VAR_DECL itself will be laid out in expand_expr. */ @@ -14242,6 +14242,10 @@ complete_vars (tree type) cp_apply_type_quals_to_decl (cp_type_quals (type), var); } + if (DECL_INITIAL (var) + && decl_constant_var_p (var)) + DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var)); + /* Remove this entry from the list. */ incomplete_vars->unordered_remove (ix); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 6c52e53bca0..77ab5fbdfd1 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1934,6 +1934,11 @@ decl_needed_p (tree decl) if (flag_keep_inline_dllexport && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) return true; + /* Virtual functions might be needed for devirtualization. */ + if (flag_devirtualize + && TREE_CODE (decl) == FUNCTION_DECL + && DECL_VIRTUAL_P (decl)) + return true; /* Otherwise, DECL does not need to be emitted -- yet. A subsequent reference to DECL might cause it to be emitted later. */ return false; diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index a62e0f9b5df..99f8006fbd8 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -74,6 +74,14 @@ cplus_expand_constant (tree cst) } break; + case CONSTRUCTOR: + { + constructor_elt *elt; + unsigned HOST_WIDE_INT idx; + FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (cst), idx, elt) + elt->value = cplus_expand_constant (elt->value); + } + default: /* There's nothing to do. */ break; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index e772164eefd..bf9c538b37a 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3557,19 +3557,11 @@ build_vec_init (tree base, tree maxindex, tree init, try_block = begin_try_block (); } - /* If the initializer is {}, then all elements are initialized from {}. - But for non-classes, that's the same as value-initialization. */ + bool empty_list = false; if (init && BRACE_ENCLOSED_INITIALIZER_P (init) && CONSTRUCTOR_NELTS (init) == 0) - { - if (CLASS_TYPE_P (type)) - /* Leave init alone. */; - else - { - init = NULL_TREE; - explicit_value_init_p = true; - } - } + /* Skip over the handling of non-empty init lists. */ + empty_list = true; /* Maybe pull out constant value when from_array? */ @@ -3689,14 +3681,8 @@ build_vec_init (tree base, tree maxindex, tree init, vec_free (new_vec); } - /* Any elements without explicit initializers get {}. */ - if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type)) - init = build_constructor (init_list_type_node, NULL); - else - { - init = NULL_TREE; - explicit_value_init_p = true; - } + /* Any elements without explicit initializers get T{}. */ + empty_list = true; } else if (from_array) { @@ -3742,6 +3728,26 @@ build_vec_init (tree base, tree maxindex, tree init, to = build1 (INDIRECT_REF, type, base); + /* If the initializer is {}, then all elements are initialized from T{}. + But for non-classes, that's the same as value-initialization. */ + if (empty_list) + { + if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type)) + { + if (BRACE_ENCLOSED_INITIALIZER_P (init) + && CONSTRUCTOR_NELTS (init) == 0) + /* Reuse it. */; + else + init = build_constructor (init_list_type_node, NULL); + CONSTRUCTOR_IS_DIRECT_INIT (init) = true; + } + else + { + init = NULL_TREE; + explicit_value_init_p = true; + } + } + if (from_array) { tree from; diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 7bd0de15fdf..6acbdd9ee2b 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -820,6 +820,7 @@ void maybe_add_lambda_conv_op (tree type) { bool nested = (current_function_decl != NULL_TREE); + bool nested_def = decl_function_context (TYPE_MAIN_DECL (type)); tree callop = lambda_function (type); if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE) @@ -972,7 +973,7 @@ maybe_add_lambda_conv_op (tree type) DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; DECL_ARGUMENTS (fn) = build_this_parm (fntype, TYPE_QUAL_CONST); - if (nested) + if (nested_def) DECL_INTERFACE_KNOWN (fn) = 1; if (generic_lambda_p) @@ -1012,7 +1013,7 @@ maybe_add_lambda_conv_op (tree type) DECL_NAME (arg) = NULL_TREE; DECL_CONTEXT (arg) = fn; } - if (nested) + if (nested_def) DECL_INTERFACE_KNOWN (fn) = 1; if (generic_lambda_p) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 05ae382e093..3296fda4734 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4697,6 +4697,9 @@ push_template_decl_real (tree decl, bool is_friend) template <typename T> friend void A<T>::f(); is not primary. */ is_primary = false; + else if (TREE_CODE (decl) == TYPE_DECL + && LAMBDA_TYPE_P (TREE_TYPE (decl))) + is_primary = false; else is_primary = template_parm_scope_p (); @@ -9135,6 +9138,11 @@ instantiate_class_template_1 (tree type) && DECL_OMP_DECLARE_REDUCTION_P (r)) cp_check_omp_declare_reduction (r); } + else if (DECL_CLASS_TEMPLATE_P (t) + && LAMBDA_TYPE_P (TREE_TYPE (t))) + /* A closure type for a lambda in a default argument for a + member template. Ignore it; it will be instantiated with + the default argument. */; else { /* Build new TYPE_FIELDS. */ @@ -15185,6 +15193,16 @@ tsubst_copy_and_build (tree t, case PARM_DECL: { tree r = tsubst_copy (t, args, complain, in_decl); + if (TREE_CODE (r) == VAR_DECL + && !processing_template_decl + && !cp_unevaluated_operand + && DECL_THREAD_LOCAL_P (r)) + { + if (tree wrap = get_tls_wrapper_fn (r)) + /* Replace an evaluated use of the thread_local variable with + a call to its wrapper. */ + r = build_cxx_call (wrap, 0, NULL, tf_warning_or_error); + } if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE) /* If the original type was a reference, we'll be wrapped in diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 352fe3ce15d..f38b5ba034e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3490,6 +3490,7 @@ finish_id_expression (tree id_expression, tree wrap; if (VAR_P (decl) && !cp_unevaluated_operand + && !processing_template_decl && DECL_THREAD_LOCAL_P (decl) && (wrap = get_tls_wrapper_fn (decl))) { diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 0bdad2a51f0..f8af0964c5b 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1237,8 +1237,9 @@ process_init_constructor_array (tree type, tree init, { /* If this type needs constructors run for default-initialization, we can't rely on the back end to do it for us, so make the - initialization explicit by list-initializing from {}. */ + initialization explicit by list-initializing from T{}. */ next = build_constructor (init_list_type_node, NULL); + CONSTRUCTOR_IS_DIRECT_INIT (next) = true; next = massage_init_elt (TREE_TYPE (type), next, complain); if (initializer_zerop (next)) /* The default zero-initialization is fine for us; don't diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9d8ffc0da30..d94e373bac6 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -13516,7 +13516,7 @@ are compatible with as many systems and code bases as possible. @item -mkernel @opindex mkernel Enable kernel development mode. The @option{-mkernel} option sets -@option{-static}, @option{-fno-common}, @option{-fno-cxa-atexit}, +@option{-static}, @option{-fno-common}, @option{-fno-use-cxa-atexit}, @option{-fno-exceptions}, @option{-fno-non-call-exceptions}, @option{-fapple-kext}, @option{-fno-weak} and @option{-fno-rtti} where applicable. This mode also sets @option{-mno-altivec}, @@ -20402,6 +20402,72 @@ single-precision mode by default. @opindex m4 Generate code for the SH4. +@item -m4-100 +@opindex m4-100 +Generate code for SH4-100. + +@item -m4-100-nofpu +@opindex m4-100-nofpu +Generate code for SH4-100 in such a way that the +floating-point unit is not used. + +@item -m4-100-single +@opindex m4-100-single +Generate code for SH4-100 assuming the floating-point unit is in +single-precision mode by default. + +@item -m4-100-single-only +@opindex m4-100-single-only +Generate code for SH4-100 in such a way that no double-precision +floating-point operations are used. + +@item -m4-200 +@opindex m4-200 +Generate code for SH4-200. + +@item -m4-200-nofpu +@opindex m4-200-nofpu +Generate code for SH4-200 without in such a way that the +floating-point unit is not used. + +@item -m4-200-single +@opindex m4-200-single +Generate code for SH4-200 assuming the floating-point unit is in +single-precision mode by default. + +@item -m4-200-single-only +@opindex m4-200-single-only +Generate code for SH4-200 in such a way that no double-precision +floating-point operations are used. + +@item -m4-300 +@opindex m4-300 +Generate code for SH4-300. + +@item -m4-300-nofpu +@opindex m4-300-nofpu +Generate code for SH4-300 without in such a way that the +floating-point unit is not used. + +@item -m4-300-single +@opindex m4-300-single +Generate code for SH4-300 in such a way that no double-precision +floating-point operations are used. + +@item -m4-300-single-only +@opindex m4-300-single-only +Generate code for SH4-300 in such a way that no double-precision +floating-point operations are used. + +@item -m4-340 +@opindex m4-340 +Generate code for SH4-340 (no MMU, no FPU). + +@item -m4-500 +@opindex m4-500 +Generate code for SH4-500 (no FPU). Passes @option{-isa=sh4-nofpu} to the +assembler. + @item -m4a-nofpu @opindex m4a-nofpu Generate code for the SH4al-dsp, or for a SH4a in such a way that the @@ -20427,6 +20493,33 @@ Same as @option{-m4a-nofpu}, except that it implicitly passes @option{-dsp} to the assembler. GCC doesn't generate any DSP instructions at the moment. +@item -m5-32media +@opindex m5-32media +Generate 32-bit code for SHmedia. + +@item -m5-32media-nofpu +@opindex m5-32media-nofpu +Generate 32-bit code for SHmedia in such a way that the +floating-point unit is not used. + +@item -m5-64media +@opindex m5-64media +Generate 64-bit code for SHmedia. + +@item -m5-64media-nofpu +@opindex m5-64media-nofpu +Generate 64-bit code for SHmedia in such a way that the +floating-point unit is not used. + +@item -m5-compact +@opindex m5-compact +Generate code for SHcompact. + +@item -m5-compact-nofpu +@opindex m5-compact-nofpu +Generate code for SHcompact in such a way that the +floating-point unit is not used. + @item -mb @opindex mb Compile code for the processor in big-endian mode. @@ -20460,16 +20553,12 @@ Enable the use of bit manipulation instructions on SH2A. Enable the use of the instruction @code{fmovd}. Check @option{-mdalign} for alignment constraints. -@item -mhitachi -@opindex mhitachi -Comply with the calling conventions defined by Renesas. - @item -mrenesas -@opindex mhitachi +@opindex mrenesas Comply with the calling conventions defined by Renesas. @item -mno-renesas -@opindex mhitachi +@opindex mno-renesas Comply with the calling conventions defined for GCC before the Renesas conventions were available. This option is the default for all targets of the SH toolchain. @@ -20477,12 +20566,12 @@ targets of the SH toolchain. @item -mnomacsave @opindex mnomacsave Mark the @code{MAC} register as call-clobbered, even if -@option{-mhitachi} is given. +@option{-mrenesas} is given. @item -mieee @itemx -mno-ieee @opindex mieee -@opindex mnoieee +@opindex mno-ieee Control the IEEE compliance of floating-point comparisons, which affects the handling of cases where the result of a comparison is unordered. By default @option{-mieee} is implicitly enabled. If @option{-ffinite-math-only} is @@ -20522,14 +20611,14 @@ separated list. For details on the atomic built-in functions see @item none Disable compiler generated atomic sequences and emit library calls for atomic -operations. This is the default if the target is not @code{sh-*-linux*}. +operations. This is the default if the target is not @code{sh*-*-linux*}. @item soft-gusa Generate GNU/Linux compatible gUSA software atomic sequences for the atomic built-in functions. The generated atomic sequences require additional support from the interrupt/exception handling code of the system and are only suitable for SH3* and SH4* single-core systems. This option is enabled by default when -the target is @code{sh-*-linux*} and SH3* or SH4*. When the target is SH4A, +the target is @code{sh*-*-linux*} and SH3* or SH4*. When the target is SH4A, this option will also partially utilize the hardware atomic instructions @code{movli.l} and @code{movco.l} to create more efficient code, unless @samp{strict} is specified. @@ -20548,7 +20637,7 @@ setting @code{SR.IMASK = 1111}. This model works only when the program runs in privileged mode and is only suitable for single-core systems. Additional support from the interrupt/exception handling code of the system is not required. This model is enabled by default when the target is -@code{sh-*-linux*} and SH1* or SH2*. +@code{sh*-*-linux*} and SH1* or SH2*. @item hard-llcs Generate hardware atomic sequences using the @code{movli.l} and @code{movco.l} @@ -20583,21 +20672,20 @@ that are implied by the @code{tas.b} instruction. On multi-core SH4A processors the @code{tas.b} instruction must be used with caution since it can result in data corruption for certain cache configurations. -@item -mspace -@opindex mspace -Optimize for space instead of speed. Implied by @option{-Os}. - @item -mprefergot @opindex mprefergot When generating position-independent code, emit function calls using the Global Offset Table instead of the Procedure Linkage Table. @item -musermode +@itemx -mno-usermode @opindex musermode -Don't generate privileged mode only code. This option -implies @option{-mno-inline-ic_invalidate} -if the inlined code would not work in user mode. -This is the default when the target is @code{sh-*-linux*}. +@opindex mno-usermode +Don't allow (allow) the compiler generating privileged mode code. Specifying +@option{-musermode} also implies @option{-mno-inline-ic_invalidate} if the +inlined code would not work in user mode. @option{-musermode} is the default +when the target is @code{sh*-*-linux*}. If the target is SH1* or SH2* +@option{-musermode} has no effect, since there is no user mode. @item -multcost=@var{number} @opindex multcost=@var{number} diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index f6a710df7cf..98c1c8da5ec 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -2126,6 +2126,18 @@ VSX vector register to hold vector float data or NO_REGS. @item wg If @option{-mmfpgpr} was used, a floating point register or NO_REGS. +@item wh +Floating point register if direct moves are available, or NO_REGS. + +@item wi +FP or VSX register to hold 64-bit integers for VSX insns or NO_REGS. + +@item wj +FP or VSX register to hold 64-bit integers for direct moves or NO_REGS. + +@item wk +FP or VSX register to hold 64-bit doubles for direct moves or NO_REGS. + @item wl Floating point register if the LFIWAX instruction is enabled or NO_REGS. @@ -2157,7 +2169,7 @@ FP or VSX register to perform float operations under @option{-mvsx} or NO_REGS. Floating point register if the STFIWX instruction is enabled or NO_REGS. @item wy -VSX vector register to hold scalar float values or NO_REGS. +FP or VSX register to perform ISA 2.07 float ops or NO_REGS. @item wz Floating point register if the LFIWZX instruction is enabled or NO_REGS. diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 4736f8d0dcc..89b676837b2 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -245,7 +245,7 @@ const_fixed_htab_eq (const void *x, const void *y) /* Return true if the given memory attributes are equal. */ -static bool +bool mem_attrs_eq_p (const struct mem_attrs *p, const struct mem_attrs *q) { return (p->alias == q->alias diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h index fe68de94756..36eb0c8b1da 100644 --- a/gcc/emit-rtl.h +++ b/gcc/emit-rtl.h @@ -20,6 +20,9 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_EMIT_RTL_H #define GCC_EMIT_RTL_H +/* Return whether two MEM_ATTRs are equal. */ +bool mem_attrs_eq_p (const struct mem_attrs *, const struct mem_attrs *); + /* Set the alias set of MEM to SET. */ extern void set_mem_alias_set (rtx, alias_set_type); diff --git a/gcc/expr.c b/gcc/expr.c index b3b7ad26cd4..02cde311a4c 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -10647,7 +10647,7 @@ is_aligning_offset (const_tree offset, const_tree exp) || !tree_fits_uhwi_p (TREE_OPERAND (offset, 1)) || compare_tree_int (TREE_OPERAND (offset, 1), BIGGEST_ALIGNMENT / BITS_PER_UNIT) <= 0 - || !exact_log2 (tree_to_uhwi (TREE_OPERAND (offset, 1)) + 1) < 0) + || exact_log2 (tree_to_uhwi (TREE_OPERAND (offset, 1)) + 1) < 0) return 0; /* Look at the first operand of BIT_AND_EXPR and strip any conversion. diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b6a26513c58..6a47227acd3 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,66 @@ +2014-09-03 Marek Polacek <polacek@redhat.com> + + Backport from trunk + PR fortran/62270 + * interface.c (compare_parameter): Fix condition. + * trans-expr.c (gfc_conv_procedure_call): Likewise. + +2014-08-29 Jeffrey Armstrong <jeffrey.armstrong@approximatrix.com> + + Backport from trunk + PR fortran/62215 + * module.c (gfc_dump_module): Unlink old module file before + renaming new one. + +2014-08-21 Thomas Koenig <tkoenig@gcc.gnu.org> + + Backport from trunk + PR fortran/62214 + * frontend-passes.c (optimize_binop_array_assignment): + Do not try to optimize the array assignment for string + concatenation. + +2014-08-16 Thomas Koenig <tkoenig@gcc.gnu.org> + + Backport from trunk + PR fortran/62142 + * trans-expr.c (is_runtime_conformable): Add NULL pointer checks. + +2014-08-15 Thomas Koenig <tkoenig@gcc.gnu.org> + + Backport from trunk + PR fortran/62106 + * gfortran.h (symbol_attribute): Add fe_temp flag. + * frontend-passes.c (is_fe_temp): New function. + (create_var): Don't add a temporary for an already + created variable or for a constant. + (combine_ARRAY_constructor): Remove special handling + for constants. + +2014-08-15 Jakub Jelinek <jakub@redhat.com> + Tobias Burnus <burnus@net-b.de> + + PR fortran/62131 + * openmp.c (resolve_omp_atomic): Only complain if code->expr1's attr + is allocatable, rather than whenever var->attr.allocatable. + +2014-08-15 Jakub Jelinek <jakub@redhat.com> + + PR fortran/62107 + * trans-openmp.c (gfc_omp_finish_clause): Handle scalar pointer + or allocatable passed by reference. + (gfc_trans_omp_clauses) <case OMP_LIST_MAP>: Likewise. + +2014-08-14 Jakub Jelinek <jakub@redhat.com> + + PR fortran/62076 + * openmp.c (gfc_match_omp_clauses): When failed to match + operator name, defined op name or name, set buffer to + empty string. Don't call gfc_find_omp_udr if buffer is empty + string. + (gfc_match_omp_declare_reduction): Call gfc_undo_symbols () + before calling gfc_free_omp_udr. + 2014-08-10 Thomas Koenig <tkoenig@gcc.gnu.org> Backport from trunk diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 4646cc33fd3..23a8ece17ee 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -430,11 +430,26 @@ cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, return 0; } +/* Auxiliary function to check if an expression is a temporary created by + create var. */ + +static bool +is_fe_temp (gfc_expr *e) +{ + if (e->expr_type != EXPR_VARIABLE) + return false; + + return e->symtree->n.sym->attr.fe_temp; +} + + /* Returns a new expression (a variable) to be used in place of the old one, with an assignment statement before the current statement to set the value of the variable. Creates a new BLOCK for the statement if that hasn't already been done and puts the statement, plus the - newly created variables, in that block. */ + newly created variables, in that block. Special cases: If the + expression is constant or a temporary which has already + been created, just copy it. */ static gfc_expr* create_var (gfc_expr * e) @@ -448,6 +463,9 @@ create_var (gfc_expr * e) gfc_namespace *ns; int i; + if (e->expr_type == EXPR_CONSTANT || is_fe_temp (e)) + return gfc_copy_expr (e); + /* If the block hasn't already been created, do so. */ if (inserted_block == NULL) { @@ -522,6 +540,7 @@ create_var (gfc_expr * e) symbol->attr.flavor = FL_VARIABLE; symbol->attr.referenced = 1; symbol->attr.dimension = e->rank > 0; + symbol->attr.fe_temp = 1; gfc_commit_symbol (symbol); result = gfc_get_expr (); @@ -884,6 +903,10 @@ optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op) return true; break; + case INTRINSIC_CONCAT: + /* Do not do string concatenations. */ + break; + default: /* Binary operators. */ if (optimize_binop_array_assignment (c, &e->value.op.op1, true)) @@ -1082,10 +1105,7 @@ combine_array_constructor (gfc_expr *e) if (op2->ts.type == BT_CHARACTER) return false; - if (op2->expr_type == EXPR_CONSTANT) - scalar = gfc_copy_expr (op2); - else - scalar = create_var (gfc_copy_expr (op2)); + scalar = create_var (gfc_copy_expr (op2)); oldbase = op1->value.constructor; newbase = NULL; diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 6b88aec384a..a193f53febd 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -724,7 +724,7 @@ typedef struct optional:1, pointer:1, target:1, value:1, volatile_:1, temporary:1, dummy:1, result:1, assign:1, threadprivate:1, not_always_present:1, implied_index:1, subref_array_pointer:1, proc_pointer:1, asynchronous:1, - contiguous:1; + contiguous:1, fe_temp: 1; /* For CLASS containers, the pointer attribute is sometimes set internally even though it was not directly specified. In this case, keep the diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 67548c062eb..21af23b7f57 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -2014,7 +2014,7 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, if (formal->ts.type == BT_CLASS && formal->attr.class_ok && actual->expr_type != EXPR_NULL && ((CLASS_DATA (formal)->attr.class_pointer - && !formal->attr.intent == INTENT_IN) + && formal->attr.intent != INTENT_IN) || CLASS_DATA (formal)->attr.allocatable)) { if (actual->ts.type != BT_CLASS) diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index 2bfe1778433..f50c5b74040 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -6072,7 +6072,10 @@ gfc_dump_module (const char *name, int dump_flag) || crc_old != crc) { /* Module file have changed, replace the old one. */ - if (rename (filename_tmp, filename)) + if (unlink (filename) && errno != ENOENT) + gfc_fatal_error ("Can't delete module file '%s': %s", filename, + xstrerror (errno)); + if (rename (filename_tmp, filename)) gfc_fatal_error ("Can't rename module file '%s' to '%s': %s", filename_tmp, filename, xstrerror (errno)); } diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 68ba70f7ebe..58aaf6623c1 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -464,7 +464,11 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, unsigned int mask, || !gfc_add_intrinsic (&sym->attr, NULL))) rop = OMP_REDUCTION_NONE; } - gfc_omp_udr *udr = gfc_find_omp_udr (gfc_current_ns, buffer, NULL); + else + buffer[0] = '\0'; + gfc_omp_udr *udr + = (buffer[0] + ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL) : NULL); gfc_omp_namelist **head = NULL; if (rop == OMP_REDUCTION_NONE && udr) rop = OMP_REDUCTION_USER; @@ -1240,6 +1244,7 @@ gfc_match_omp_declare_reduction (void) syntax: gfc_current_locus = old_loc; gfc_current_ns = combiner_ns->parent; + gfc_undo_symbols (); gfc_free_omp_udr (omp_udr); return MATCH_ERROR; } @@ -2739,7 +2744,7 @@ resolve_omp_atomic (gfc_code *code) break; } - if (var->attr.allocatable) + if (gfc_expr_attr (code->expr1).allocatable) { gfc_error ("!$OMP ATOMIC with ALLOCATABLE variable at %L", &code->loc); diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index dbfde1bdce3..2b06304cb08 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -4409,7 +4409,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, && e->expr_type == EXPR_VARIABLE && (!e->ref || (e->ref->type == REF_ARRAY - && !e->ref->u.ar.type != AR_FULL)) + && e->ref->u.ar.type != AR_FULL)) && e->symtree->n.sym->attr.optional) { tmp = fold_build3_loc (input_location, COND_EXPR, @@ -7842,7 +7842,7 @@ is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2) for (a = expr2->value.function.actual; a != NULL; a = a->next) { e1 = a->expr; - if (e1->rank > 0 && !is_runtime_conformable (expr1, e1)) + if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1)) return false; } return true; @@ -7853,7 +7853,7 @@ is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2) for (a = expr2->value.function.actual; a != NULL; a = a->next) { e1 = a->expr; - if (e1->rank > 0 && !is_runtime_conformable (expr1, e1)) + if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1)) return false; } return true; diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index da01a9034cb..548b5d3a485 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -1022,6 +1022,7 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p) && !GFC_DECL_CRAY_POINTEE (decl) && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))) return; + tree orig_decl = decl; c4 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); OMP_CLAUSE_MAP_KIND (c4) = OMP_CLAUSE_MAP_POINTER; OMP_CLAUSE_DECL (c4) = decl; @@ -1029,6 +1030,17 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p) decl = build_fold_indirect_ref (decl); OMP_CLAUSE_DECL (c) = decl; OMP_CLAUSE_SIZE (c) = NULL_TREE; + if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE + && (GFC_DECL_GET_SCALAR_POINTER (orig_decl) + || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl))) + { + c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); + OMP_CLAUSE_MAP_KIND (c3) = OMP_CLAUSE_MAP_POINTER; + OMP_CLAUSE_DECL (c3) = unshare_expr (decl); + OMP_CLAUSE_SIZE (c3) = size_int (0); + decl = build_fold_indirect_ref (decl); + OMP_CLAUSE_DECL (c) = decl; + } } if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) { @@ -1884,14 +1896,32 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, TREE_ADDRESSABLE (decl) = 1; if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL) { - if (POINTER_TYPE_P (TREE_TYPE (decl))) + if (POINTER_TYPE_P (TREE_TYPE (decl)) + && (gfc_omp_privatize_by_reference (decl) + || GFC_DECL_GET_SCALAR_POINTER (decl) + || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl) + || GFC_DECL_CRAY_POINTEE (decl) + || GFC_DESCRIPTOR_TYPE_P + (TREE_TYPE (TREE_TYPE (decl))))) { + tree orig_decl = decl; node4 = build_omp_clause (input_location, OMP_CLAUSE_MAP); OMP_CLAUSE_MAP_KIND (node4) = OMP_CLAUSE_MAP_POINTER; OMP_CLAUSE_DECL (node4) = decl; OMP_CLAUSE_SIZE (node4) = size_int (0); decl = build_fold_indirect_ref (decl); + if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE + && (GFC_DECL_GET_SCALAR_POINTER (orig_decl) + || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl))) + { + node3 = build_omp_clause (input_location, + OMP_CLAUSE_MAP); + OMP_CLAUSE_MAP_KIND (node3) = OMP_CLAUSE_MAP_POINTER; + OMP_CLAUSE_DECL (node3) = decl; + OMP_CLAUSE_SIZE (node3) = size_int (0); + decl = build_fold_indirect_ref (decl); + } } if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) { diff --git a/gcc/gcc.c b/gcc/gcc.c index 5cb485acbd3..9c4c40c7118 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -576,15 +576,21 @@ proper position among the other output files. */ #ifndef LIBLSAN_SPEC #define STATIC_LIBLSAN_LIBS \ " %{static-liblsan:%:include(libsanitizer.spec)%(link_liblsan)}" -#ifdef HAVE_LD_STATIC_DYNAMIC -#define LIBLSAN_SPEC "%{!shared:%{static-liblsan:" LD_STATIC_OPTION \ +#ifdef LIBLSAN_EARLY_SPEC +#define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS +#elif defined(HAVE_LD_STATIC_DYNAMIC) +#define LIBLSAN_SPEC "%{static-liblsan:" LD_STATIC_OPTION \ "} -llsan %{static-liblsan:" LD_DYNAMIC_OPTION "}" \ - STATIC_LIBLSAN_LIBS "}" + STATIC_LIBLSAN_LIBS #else -#define LIBLSAN_SPEC "%{!shared:-llsan" STATIC_LIBLSAN_LIBS "}" +#define LIBLSAN_SPEC "-llsan" STATIC_LIBLSAN_LIBS #endif #endif +#ifndef LIBLSAN_EARLY_SPEC +#define LIBLSAN_EARLY_SPEC "" +#endif + #ifndef LIBUBSAN_SPEC #define STATIC_LIBUBSAN_LIBS \ " %{static-libubsan:%:include(libsanitizer.spec)%(link_libubsan)}" @@ -720,7 +726,8 @@ proper position among the other output files. */ #ifndef SANITIZER_EARLY_SPEC #define SANITIZER_EARLY_SPEC "\ %{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \ - %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "}}}" + %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \ + %{%:sanitize(leak):" LIBLSAN_EARLY_SPEC "}}}" #endif /* Linker command line options for -fsanitize= late on the command line. */ diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 6402cce2f3f..c6aea6529ef 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -3104,8 +3104,8 @@ fold_ctor_reference (tree type, tree ctor, unsigned HOST_WIDE_INT offset, result. */ if (!AGGREGATE_TYPE_P (TREE_TYPE (ctor)) && !offset /* VIEW_CONVERT_EXPR is defined only for matching sizes. */ - && operand_equal_p (TYPE_SIZE (type), - TYPE_SIZE (TREE_TYPE (ctor)), 0)) + && !compare_tree_int (TYPE_SIZE (type), size) + && !compare_tree_int (TYPE_SIZE (TREE_TYPE (ctor)), size)) { ret = canonicalize_constructor_val (unshare_expr (ctor), from_decl); ret = fold_unary (VIEW_CONVERT_EXPR, type, ret); diff --git a/gcc/gimple.h b/gcc/gimple.h index 11959a82e62..50a5a8620c3 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -90,6 +90,7 @@ enum gf_mask { GF_CALL_NOTHROW = 1 << 4, GF_CALL_ALLOCA_FOR_VAR = 1 << 5, GF_CALL_INTERNAL = 1 << 6, + GF_CALL_CTRL_ALTERING = 1 << 7, GF_OMP_PARALLEL_COMBINED = 1 << 0, GF_OMP_FOR_KIND_MASK = 3 << 0, GF_OMP_FOR_KIND_FOR = 0 << 0, @@ -2447,6 +2448,29 @@ gimple_call_internal_fn (const_gimple gs) return static_cast <const gimple_statement_call *> (gs)->u.internal_fn; } +/* If CTRL_ALTERING_P is true, mark GIMPLE_CALL S to be a stmt + that could alter control flow. */ + +static inline void +gimple_call_set_ctrl_altering (gimple s, bool ctrl_altering_p) +{ + GIMPLE_CHECK (s, GIMPLE_CALL); + if (ctrl_altering_p) + s->subcode |= GF_CALL_CTRL_ALTERING; + else + s->subcode &= ~GF_CALL_CTRL_ALTERING; +} + +/* Return true if call GS calls an func whose GF_CALL_CTRL_ALTERING + flag is set. Such call could not be a stmt in the middle of a bb. */ + +static inline bool +gimple_call_ctrl_altering_p (const_gimple gs) +{ + GIMPLE_CHECK (gs, GIMPLE_CALL); + return (gs->subcode & GF_CALL_CTRL_ALTERING) != 0; +} + /* Return the function type of the function called by GS. */ diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 4121bf3cff4..89e7334e8cd 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -6263,7 +6263,7 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE | GOVD_PRIVATE | GOVD_REDUCTION - | GOVD_LINEAR)) != 0) + | GOVD_LINEAR | GOVD_MAP)) != 0) break; ctx = ctx->outer_context; } diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index f45b4a22709..b0b8e39e96e 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -5341,10 +5341,13 @@ Binary_expression::do_lower(Gogo* gogo, Named_object*, // Lower struct, array, and some interface comparisons. if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ) { - if (left->type()->struct_type() != NULL) + if (left->type()->struct_type() != NULL + && right->type()->struct_type() != NULL) return this->lower_struct_comparison(gogo, inserter); else if (left->type()->array_type() != NULL - && !left->type()->is_slice_type()) + && !left->type()->is_slice_type() + && right->type()->array_type() != NULL + && !right->type()->is_slice_type()) return this->lower_array_comparison(gogo, inserter); else if ((left->type()->interface_type() != NULL && right->type()->interface_type() == NULL) diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 0d1adce952e..49ff85c7f53 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -306,6 +306,28 @@ block_fallthru (basic_block bb) return (e) ? e->dest : NULL_BLOCK; } + +/* Return true if RTXs A and B can be safely interchanged. */ + +static bool +rtx_interchangeable_p (const_rtx a, const_rtx b) +{ + if (!rtx_equal_p (a, b)) + return false; + + if (GET_CODE (a) != MEM) + return true; + + /* A dead type-unsafe memory reference is legal, but a live type-unsafe memory + reference is not. Interchanging a dead type-unsafe memory reference with + a live type-safe one creates a live type-unsafe memory reference, in other + words, it makes the program illegal. + We check here conservatively whether the two memory references have equal + memory attributes. */ + + return mem_attrs_eq_p (get_mem_attrs (a), get_mem_attrs (b)); +} + /* Go through a bunch of insns, converting them to conditional execution format if possible. Return TRUE if all of the non-note @@ -1034,6 +1056,9 @@ noce_try_move (struct noce_if_info *if_info) || (rtx_equal_p (if_info->a, XEXP (cond, 1)) && rtx_equal_p (if_info->b, XEXP (cond, 0)))) { + if (!rtx_interchangeable_p (if_info->a, if_info->b)) + return FALSE; + y = (code == EQ) ? if_info->a : if_info->b; /* Avoid generating the move if the source is the destination. */ @@ -2504,7 +2529,7 @@ noce_process_if_block (struct noce_if_info *if_info) if (! insn_b || insn_b != last_active_insn (else_bb, FALSE) || (set_b = single_set (insn_b)) == NULL_RTX - || ! rtx_equal_p (x, SET_DEST (set_b))) + || ! rtx_interchangeable_p (x, SET_DEST (set_b))) return FALSE; } else @@ -2517,7 +2542,7 @@ noce_process_if_block (struct noce_if_info *if_info) || BLOCK_FOR_INSN (insn_b) != BLOCK_FOR_INSN (if_info->cond_earliest) || !NONJUMP_INSN_P (insn_b) || (set_b = single_set (insn_b)) == NULL_RTX - || ! rtx_equal_p (x, SET_DEST (set_b)) + || ! rtx_interchangeable_p (x, SET_DEST (set_b)) || ! noce_operand_ok (SET_SRC (set_b)) || reg_overlap_mentioned_p (x, SET_SRC (set_b)) || modified_between_p (SET_SRC (set_b), insn_b, jump) @@ -2583,7 +2608,7 @@ noce_process_if_block (struct noce_if_info *if_info) /* Look and see if A and B are really the same. Avoid creating silly cmove constructs that no one will fix up later. */ - if (rtx_equal_p (a, b)) + if (rtx_interchangeable_p (a, b)) { /* If we have an INSN_B, we don't have to create any new rtl. Just move the instruction that we already have. If we don't have an diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 52d37fb3bdf..a6818ba8da1 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -3032,6 +3032,11 @@ intersect_aggregates_with_edge (struct cgraph_edge *cs, int index, intersect_with_agg_replacements (cs->caller, src_idx, &inter, 0); } + else + { + inter.release (); + return vNULL; + } } else { @@ -3047,6 +3052,11 @@ intersect_aggregates_with_edge (struct cgraph_edge *cs, int index, else intersect_with_plats (src_plats, &inter, 0); } + else + { + inter.release (); + return vNULL; + } } } else if (jfunc->type == IPA_JF_ANCESTOR @@ -3130,7 +3140,8 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node, vec<cgraph_edge_p> callers) { struct ipa_node_params *dest_info = IPA_NODE_REF (node); - struct ipa_agg_replacement_value *res = NULL; + struct ipa_agg_replacement_value *res; + struct ipa_agg_replacement_value **tail = &res; struct cgraph_edge *cs; int i, j, count = ipa_get_param_count (dest_info); @@ -3174,14 +3185,15 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node, v->offset = item->offset; v->value = item->value; v->by_ref = plats->aggs_by_ref; - v->next = res; - res = v; + *tail = v; + tail = &v->next; } next_param: if (inter.exists ()) inter.release (); } + *tail = NULL; return res; } @@ -3190,7 +3202,8 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node, static struct ipa_agg_replacement_value * known_aggs_to_agg_replacement_list (vec<ipa_agg_jump_function> known_aggs) { - struct ipa_agg_replacement_value *res = NULL; + struct ipa_agg_replacement_value *res; + struct ipa_agg_replacement_value **tail = &res; struct ipa_agg_jump_function *aggjf; struct ipa_agg_jf_item *item; int i, j; @@ -3204,9 +3217,10 @@ known_aggs_to_agg_replacement_list (vec<ipa_agg_jump_function> known_aggs) v->offset = item->offset; v->value = item->value; v->by_ref = aggjf->by_ref; - v->next = res; - res = v; + *tail = v; + tail = &v->next; } + *tail = NULL; return res; } diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index c029da671a2..6c6ea2bdd2b 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,11 @@ +2014-08-15 Bin Cheng <bin.cheng@arm.com> + + Backport from mainline + 2014-08-08 Bin Cheng <bin.cheng@arm.com> + + PR lto/62032 + * lto-lang.c (lto_init): Switch mis-matched arguments. + 2014-07-16 Release Manager * GCC 4.9.1 released. diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index f60d2127b36..1a4da916ff1 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -1186,10 +1186,10 @@ lto_init (void) } else { - lto_define_builtins (va_list_type_node, - build_reference_type (va_list_type_node)); + lto_define_builtins (build_reference_type (va_list_type_node), + va_list_type_node); } - + if (flag_cilkplus) cilk_init_builtins (); diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 35c1d7519e4..b7e14e4d0d1 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -1233,6 +1233,13 @@ add_or_update_dep_1 (dep_t new_dep, bool resolved_p, switch (ask_dependency_caches (new_dep)) { case DEP_PRESENT: + dep_t present_dep; + sd_iterator_def sd_it; + + present_dep = sd_find_dep_between_no_cache (DEP_PRO (new_dep), + DEP_CON (new_dep), + resolved_p, &sd_it); + DEP_MULTIPLE (present_dep) = 1; return DEP_PRESENT; case DEP_CHANGED: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7a351f2032c..0200c69a518 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,187 @@ +2014-09-03 Martin Jambor <mjambor@suse.cz> + + PR ipa/62015 + * g++.dg/ipa/pr62015.C: New test. + +2014-09-03 Martin Jambor <mjambor@suse.cz> + + PR ipa/61986 + * gcc.dg/ipa/pr61986.c: New test. + +2014-09-03 Marek Polacek <polacek@redhat.com> + + Backport from mainline + 2014-09-02 Marek Polacek <polacek@redhat.com> + + PR fortran/62270 + * gfortran.dg/pointer_intent_7.f90: Adjust dg-error. + +2014-09-03 Marek Polacek <polacek@redhat.com> + + PR c/62294 + * gcc.dg/pr56724-1.c: New test. + * gcc.dg/pr56724-2.c: New test. + * gcc.dg/pr62294.c: New test. + * gcc.dg/pr62294.h: New file. + +2014-09-01 Oleg Endo <olegendo@gcc.gnu.org> + + Backport from mainline + 2014-09-01 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/62312 + * gcc.c-torture/compile/pr62312.c: New. + +2014-09-01 Maciej W. Rozycki <macro@codesourcery.com> + + Backport from mainline + 2014-09-01 Maciej W. Rozycki <macro@codesourcery.com> + + * gcc.dg/tree-ssa/loop-19.c: Exclude classic FPU Power targets. + +2014-08-27 Guozhi Wei <carrot@google.com> + + PR target/62262 + * gcc.target/aarch64/pr62262.c: New test. + +2014-08-26 Dominik Vogt <vogt@linux.vnet.ibm.com> + + * gfortran.dg/bessel_7.f90: Bump allowed precision to avoid + failure on s390*-*-linux-gnu. + +2014-08-24 Oleg Endo <olegendo@gcc.gnu.org> + + Backport from mainline + 2014-08-24 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/61996 + * gcc.target/sh/pr61996.c: New. + +2014-08-22 Igor Zamyatin <igor.zamyatin@intel.com> + + PR other/62008 + * c-c++-common/cilk-plus/AN/pr62008.c: New test. + +2014-08-21 Thomas Koenig <tkoenig@gcc.gnu.org> + + Backport from trunk + PR fortran/62214 + * gfortran.dg/array_assignment_5.f90: New test. + +2014-08-20 Martin Jambor <mjambor@suse.cz> + Wei Mi <wmi@google.com> + + PR ipa/60449 + PR middle-end/61776 + * testsuite/gcc.dg/lto/pr60449_1.c: New test. + * testsuite/gcc.dg/lto/pr60449_0.c: New test. + * testsuite/gcc.dg/pr61776.c: New test. + +2014-08-19 Janis Johnson <janisjo@codesourcery.com> + + Backport from mainline: + 2014-08-19 Janis Johnson <janisjo@codesourcery.com> + + * lib/target-supports.exp + (check_effective_target_arm_v8_neon_ok_nocache): Add + "-march-armv8-a" to compile flags. + +2014-08-15 Thomas Koenig <tkoenig@gcc.gnu.org> + + Backport from trunk + PR fortran/62142 + * gfortran.dg/realloc_on_assign_24.f90: New test. + +2014-08-15 Tom de Vries <tom@codesourcery.com> + + Backport from mainline: + 2014-08-14 Tom de Vries <tom@codesourcery.com> + + PR rtl-optimization/62004 + PR rtl-optimization/62030 + * gcc.dg/pr62004.c: New test. + * gcc.dg/pr62030.c: Same. + * gcc.target/mips/pr62030-octeon.c: Same. + +2014-08-15 Thomas Koenig <tkoenig@gcc.gnu.org> + + Backport from trunk + PR fortran/62106 + * gfortran.dg/array_constructor_49.f90: New test. + +2014-08-15 Jakub Jelinek <jakub@redhat.com> + Tobias Burnus <burnus@net-b.de> + + PR fortran/62131 + * gfortran.dg/gomp/pr62131.f90: New test. + +2014-08-14 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + Backport from mainline + 2014-08-04 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + PR target/61713 + * gcc.dg/pr61756.c: New test. + +2014-08-14 Thomas Preud'homme <thomas.preudhomme@arm.com> + + Backport from mainline + 2014-08-12 Thomas Preud'homme <thomas.preudhomme@arm.com> + + PR middle-end/62103 + * gcc.c-torture/execute/bitfld-6.c: New test. + +2014-08-12 Felix Yang <fei.yang0953@gmail.com> + + PR tree-optimization/62073 + * gcc.dg/vect/pr62073.c: New test. + +2014-08-12 Janis Johnson <janisjo@codesourcery.com> + + Backport from mainline + 2014-08-12 Janis Johnson <janisjo@codesourcery.com> + + * lib/target/supports.exp + (check_effective_target_arm_v8_neon_ok_nocache): Check for armv8 + or later. + + * gcc.dg/pr59418.c: Don't add ARM options for a Thumb1 multilib. + + * gcc.target/arm/neon-vext-execute.c: Skip if the test won't run + on Neon hardware. + + * gcc.target/arm/pr48784.c: Skip for thumb1 multilib. + * gcc.target/arm/pr59985.c: Likewise. + +2014-08-12 Igor Zamyatin <igor.zamyatin@intel.com> + + PR other/61962 + * c-c++-common/cilk-plus/AN/pr61962.c: New test. + +2014-08-12 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com> + + Backport from mainline + 2014-06-16 Ganesh Gopalasubramanian + <Ganesh.Gopalasubramanian@amd.com> + + * gcc.target/i386/xop-imul64-vector.c: Remove the check for + vpmacsdql instruction. + +2014-08-11 Janis Johnson <janisjo@codesourcery.com> + + Backport from mainline + 2014-08-11 Janis Johnson <janisjo@codesourcery.com> + + * lib/target-supports.exp (check_effective_target_arm_thumb1_ok, + check_effective_target_arm_thumb2_ok): Test with code that passes + an argument and returns a result. + + * gcc.target/arm/frame-pointer-1.c: Skip if Thumb is not supported. + * gcc.target/arm/pr56184.C: Likewise. + * gcc.target/arm/pr59896.c: Likewise. + * gcc.target/arm/stack-red-zone.c: Likewise. + * gcc.target/arm/thumb-find-work-register.c: Likewise. + 2014-08-10 Thomas Koenig <tkoenig@gcc.gnu.org> Backport from trunk diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/pr61962.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr61962.c new file mode 100644 index 00000000000..08d4fe23628 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr61962.c @@ -0,0 +1,14 @@ +/* PR other/61962 */ +/* { dg-do compile } */ +/* { dg-options "-fcilkplus" } */ + +struct FloatStruct +{ + float *f; +}; + +/* Either SRC or DST must be a struct, otherwise the bug does not occur. */ +void f (struct FloatStruct* dst, float *src, unsigned int length) +{ + dst->f[0:length] = src[0:length]; +} diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/pr62008.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr62008.c new file mode 100644 index 00000000000..05734c56017 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr62008.c @@ -0,0 +1,10 @@ +/* PR other/62008 */ +/* { dg-do compile } */ +/* { dg-options "-fcilkplus" } */ + +void f(int *a, int w, int h) +{ + int tmp[w][h]; + tmp[:][:] = a[0:w][0:h]; /* { dg-error "base of array section must be pointer or array type" } */ + /* { dg-error "start-index and length fields necessary" "" { target c } 8 } */ +} diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem3.C new file mode 100644 index 00000000000..c5e2101c0e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem3.C @@ -0,0 +1,16 @@ +// PR c++/62129 +// { dg-do compile { target c++11 } } + +class Evaluator +{ + int MakeChangelist (); + typedef int (Evaluator::*fac_t)(); + struct CreatorEntry + { + const char *type; + fac_t factory; + }; + static constexpr CreatorEntry kCreators[] = { "", &Evaluator::MakeChangelist }; +}; + +constexpr Evaluator::CreatorEntry Evaluator::kCreators[]; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C index adbb4dbcaac..79ab4107dda 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C @@ -1,5 +1,6 @@ // PR c++/61566 // { dg-do compile { target c++11 } } +// { dg-options "-fabi-version=0" } struct function { @@ -7,6 +8,7 @@ struct function function (_Functor); }; +template <class U> struct C { template <typename T> @@ -15,6 +17,9 @@ struct C void bar () { - C c; + C<int> c; c.foo (1); } + +// { dg-final { scan-assembler "_ZN8functionC1IZN1CIiE3fooIiEEvT_S_Ed_UlvE_EET_" } } +// { dg-final { scan-assembler-not "_ZZN1CIiE3fooIiEEvT_8functionEd_NKUlvE_clEv" } } diff --git a/gcc/testsuite/g++.dg/init/explicit2.C b/gcc/testsuite/g++.dg/init/explicit2.C new file mode 100644 index 00000000000..d1dbb39fc61 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/explicit2.C @@ -0,0 +1,8 @@ +// PR c++/60417 + +struct A { explicit A(int = 0); }; + +int main() +{ + A a[1] = { }; +} diff --git a/gcc/testsuite/g++.dg/ipa/devirt-39.C b/gcc/testsuite/g++.dg/ipa/devirt-39.C new file mode 100644 index 00000000000..fbeea126e19 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-39.C @@ -0,0 +1,28 @@ +// PR c++/61214 +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +struct Base +{ + virtual ~Base(); + virtual Base* clone() { + return 0; + } +}; + +struct Foo : Base +{ + virtual ~Foo(); + virtual Base* clone() { + return new Foo(); + } +}; + +int main() +{ + Base* f = new Foo(); + f->clone(); + return 0; +} + +/* { dg-final { scan-tree-dump-not "OBJ_TYPE_REF" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/pr62015.C b/gcc/testsuite/g++.dg/ipa/pr62015.C new file mode 100644 index 00000000000..950b46e759b --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr62015.C @@ -0,0 +1,55 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -std=c++11" } */ + + +extern "C" int printf(const char *fmt, ...); +extern "C" void abort(void); + +struct Side { + enum _Value { Left, Right, Invalid }; + + constexpr Side() : _value(Invalid) {} + constexpr Side(_Value value) : _value(value) {} + operator _Value() const { return (_Value)_value; } + + private: + char _value; +}; + +struct A { + void init(); + void adjust(Side side, bool final); + void move(Side side); +}; + +void A::init() +{ + adjust(Side::Invalid, false); +} + +static void __attribute__((noinline)) +check (int v, int final) +{ + if (v != 0) + abort(); +} + + +__attribute__((noinline)) +void A::adjust(Side side, bool final) +{ + check ((int)side, final); +} + +void A::move(Side side) +{ + adjust(side, false); + adjust(side, true); +} + +int main() +{ + A t; + t.move(Side::Left); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tls/thread_local10.C b/gcc/testsuite/g++.dg/tls/thread_local10.C new file mode 100644 index 00000000000..48c1b861c78 --- /dev/null +++ b/gcc/testsuite/g++.dg/tls/thread_local10.C @@ -0,0 +1,23 @@ +// PR c++/58624 + +// { dg-do run { target c++11 } } +// { dg-add-options tls } +// { dg-require-effective-target tls_runtime } + +int i; + +template <typename> struct A +{ + static thread_local int s; + + A () { i = s; } +}; + +int f() { return 42; } +template <typename T> thread_local int A<T>::s = f(); + +int main () { + A<void> a; + if (i != 42) + __builtin_abort(); +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr62312.c b/gcc/testsuite/gcc.c-torture/compile/pr62312.c new file mode 100644 index 00000000000..2e87bb9bd93 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr62312.c @@ -0,0 +1,23 @@ +/* PR target/62312 */ + +typedef struct { unsigned int arg[100]; } *FunctionCallInfo; +typedef struct { int day; int month; } Interval; +void* palloc (unsigned int); +int bar (void); +void baz (void); + +void +interval_pl (FunctionCallInfo fcinfo) +{ + Interval *span1 = ((Interval *) ((char *) ((fcinfo->arg[0])))); + Interval *span2 = ((Interval *) ((char *) ((fcinfo->arg[1])))); + Interval *result = (Interval *) palloc (sizeof (Interval)); + + if ((((span1->month) < 0) == ((span2->month) < 0)) + && !(((result->month) < 0) == ((span1->month) < 0))) + do { + if (bar ()) + baz (); + } while(0); + result->day = span1->day + span2->day; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/bitfld-6.c b/gcc/testsuite/gcc.c-torture/execute/bitfld-6.c new file mode 100644 index 00000000000..50927dc1d53 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/bitfld-6.c @@ -0,0 +1,23 @@ +union U +{ + const int a; + unsigned b : 20; +}; + +static union U u = { 0x12345678 }; + +/* Constant folding used to fail to account for endianness when folding a + union. */ + +int +main (void) +{ +#ifdef __BYTE_ORDER__ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + return u.b - 0x45678; +#else + return u.b - 0x12345; +#endif +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ipa/pr61986.c b/gcc/testsuite/gcc.dg/ipa/pr61986.c new file mode 100644 index 00000000000..8d2f658b87c --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr61986.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int a, b, c; + +struct S +{ + int f0; + int f1; +} d; + +static int fn2 (struct S); +void fn3 (struct S); + +void +fn1 (struct S p) +{ + struct S h = { 0, 0 }; + fn3 (p); + fn2 (h); +} + +int +fn2 (struct S p) +{ + struct S j = { 0, 0 }; + fn3 (p); + fn2 (j); + return 0; +} + +void +fn3 (struct S p) +{ + for (; b; a++) + c = p.f0; + fn1 (d); +} + +void +fn4 () +{ + for (;;) + { + struct S f = { 0, 0 }; + fn1 (f); + } +} diff --git a/gcc/testsuite/gcc.dg/lto/pr60449_0.c b/gcc/testsuite/gcc.dg/lto/pr60449_0.c new file mode 100644 index 00000000000..a430830cbed --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr60449_0.c @@ -0,0 +1,30 @@ +/* { dg-lto-do link } */ + +extern int printf (const char *__restrict __format, ...); +typedef long int __time_t; +typedef long int __suseconds_t; + +struct timeval + { + __time_t tv_sec; + __suseconds_t tv_usec; + }; + +struct timezone + { + int tz_minuteswest; + int tz_dsttime; + }; +typedef struct timezone *__restrict __timezone_ptr_t; + +extern int gettimeofday (struct timeval *__restrict __tv, __timezone_ptr_t __tz); + +int bar (void) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday (&tv, &tz); + printf ("This is from bar %i\n", tz.tz_dsttime); + return 5; +} diff --git a/gcc/testsuite/gcc.dg/lto/pr60449_1.c b/gcc/testsuite/gcc.dg/lto/pr60449_1.c new file mode 100644 index 00000000000..ddc25296d8a --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr60449_1.c @@ -0,0 +1,76 @@ +extern int printf (const char *__restrict __format, ...); +typedef long int __time_t; +typedef long int __suseconds_t; +struct timeval + { + __time_t tv_sec; + __suseconds_t tv_usec; + }; +struct timezone + { + int tz_minuteswest; + int tz_dsttime; + }; +typedef struct timezone *__restrict __timezone_ptr_t; +extern int gettimeofday (struct timeval *__restrict __tv, + __timezone_ptr_t __tz) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); + +typedef long int __jmp_buf[8]; +typedef struct + { + unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))]; + } __sigset_t; +struct __jmp_buf_tag + { + __jmp_buf __jmpbuf; + int __mask_was_saved; + __sigset_t __saved_mask; + }; +typedef struct __jmp_buf_tag jmp_buf[1]; + +extern int setjmp (jmp_buf __env) __attribute__ ((__nothrow__)); +extern void longjmp (struct __jmp_buf_tag __env[1], int __val) + __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__)); + +extern int bar (void); + +int __attribute__ ((noinline, noclone)) +get_input (void) +{ + return 0; +} + +static jmp_buf buf; + +int foo (void) +{ + if (get_input ()) + longjmp(buf, 1); + return 0; +} + +volatile int z; + + +int main (void) +{ + struct timeval tv; + struct timezone tz; + + bar(); + if (setjmp (buf)) + return 1; + + if (!get_input ()) + { + gettimeofday (&tv, &tz); + z = 0; + printf ("This is from main %i\n", tz.tz_dsttime); + } + + foo (); + bar (); + bar (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr56724-1.c b/gcc/testsuite/gcc.dg/pr56724-1.c new file mode 100644 index 00000000000..4276c3f154b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr56724-1.c @@ -0,0 +1,33 @@ +/* PR c/56724 */ +/* { dg-do compile } */ +/* { dg-options "-Wtraditional-conversion" } */ + +extern void foo (int p[2][]); /* { dg-error "array type has incomplete element type" } */ +extern void foo_i (int, int); +extern void foo_u (unsigned int); +extern void foo_f (int, float); +extern void foo_ll (long long); +extern void foo_cd (int, int, __complex__ double); +extern signed char sc; +extern int i; +extern unsigned int u; +extern float f; +extern double d; +extern __complex__ double cd; + +void +fn () +{ + int p[1][1]; + foo (p); /* { dg-error "8:type of formal parameter" } */ + foo_i (1, f); /* { dg-warning "13:passing argument" } */ + foo_i (1, cd); /* { dg-warning "13:passing argument" } */ + foo_cd (1, 2, f); /* { dg-warning "17:passing argument" } */ + foo_f (9, i); /* { dg-warning "13:passing argument" } */ + foo_cd (2, 2, i); /* { dg-warning "17:passing argument" } */ + foo_f (2, cd); /* { dg-warning "13:passing argument" } */ + foo_f (2, d); /* { dg-warning "13:passing argument" } */ + foo_ll (sc); /* { dg-warning "11:passing argument" } */ + foo_u (i); /* { dg-warning "10:passing argument" } */ + foo_i (1, u); /* { dg-warning "13:passing argument" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr56724-2.c b/gcc/testsuite/gcc.dg/pr56724-2.c new file mode 100644 index 00000000000..4abb7d899e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr56724-2.c @@ -0,0 +1,31 @@ +/* PR c/56724 */ +/* { dg-do compile } */ +/* { dg-options "-Wc++-compat -Wpedantic" } */ + +enum E1 { A }; +enum E2 { B }; +extern void foo_E (enum E1); +extern void foo_v (void *p); +extern void foo_sc (int, int, signed char *); +extern unsigned char *uc; +extern signed char sc; +extern const signed char *csc; +extern float *f; + +void +foo (void) +{ + void (*fp)(void); + const void (*ffp)(void); + foo_v (fp); /* { dg-warning "10:ISO C forbids passing argument" } */ + foo_E (B); /* { dg-warning "10:enum conversion when passing argument" } */ + foo_sc (1, 2, uc); /* { dg-warning "17:pointer targets in passing argument" } */ + foo_sc (1, 2, f); /* { dg-warning "17:passing argument" } */ + foo_sc (1, 2, sc); /* { dg-warning "17:passing argument" } */ + foo_sc (uc, 2, &sc); /* { dg-warning "11:passing argument" } */ + foo_sc (1, 2, csc); /* { dg-warning "17:passing argument" } */ +} + +typedef void (*fp)(void); +typedef void (*nrfp)(void) __attribute__((noreturn)); +void f1 (nrfp); void f2 (fp x) { f1 (x); } extern int e; /* { dg-warning "38:passing argument" } */ diff --git a/gcc/testsuite/gcc.dg/pr59418.c b/gcc/testsuite/gcc.dg/pr59418.c index 114c1d383c4..257ce79f199 100644 --- a/gcc/testsuite/gcc.dg/pr59418.c +++ b/gcc/testsuite/gcc.dg/pr59418.c @@ -3,7 +3,7 @@ /* { dg-do compile } */ /* { dg-options "-Os -g" } */ -/* { dg-options "-march=armv7-a -mfloat-abi=hard -Os -g" { target arm*-*-* } } */ +/* { dg-options "-march=armv7-a -mfloat-abi=hard -Os -g" { target { arm*-*-* && { ! arm_thumb1 } } } } */ extern int printf (const char *__format, ...); diff --git a/gcc/testsuite/gcc.dg/pr61776.c b/gcc/testsuite/gcc.dg/pr61776.c new file mode 100644 index 00000000000..8768c546bda --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr61776.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fprofile-generate" } */ + +#include <setjmp.h> + +int cond1, cond2; + +int goo() __attribute__((noinline)); + +int goo() { + if (cond1) + return 1; + else + return 2; +} + +jmp_buf env; +int foo() { + int a; + + setjmp(env); + if (cond2) + a = goo(); + else + a = 3; + return a; +} diff --git a/gcc/testsuite/gcc.dg/pr62004.c b/gcc/testsuite/gcc.dg/pr62004.c new file mode 100644 index 00000000000..c994a411b3b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr62004.c @@ -0,0 +1,47 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-tree-tail-merge" } */ + +struct node +{ + struct node *next; + struct node *prev; +}; + +struct node node; + +struct head +{ + struct node *first; +}; + +struct head heads[5]; + +int k = 2; + +struct head *head = &heads[2]; + +int +main () +{ + struct node *p; + + node.next = (void*)0; + + node.prev = (void *)head; + + head->first = &node; + + struct node *n = head->first; + + struct head *h = &heads[k]; + + heads[2].first = n->next; + + if ((void*)n->prev == (void *)h) + p = h->first; + else + /* Dead tbaa-unsafe load from ((struct node *)&heads[2])->next. */ + p = n->prev->next; + + return !(p == (void*)0); +} diff --git a/gcc/testsuite/gcc.dg/pr62030.c b/gcc/testsuite/gcc.dg/pr62030.c new file mode 100644 index 00000000000..b8baf934354 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr62030.c @@ -0,0 +1,50 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); + +struct node +{ + struct node *next; + struct node *prev; +}; + +struct node node; + +struct head +{ + struct node *first; +}; + +struct head heads[5]; + +int k = 2; + +struct head *head = &heads[2]; + +static int __attribute__((noinline)) +foo (void) +{ + node.prev = (void *)head; + head->first = &node; + + struct node *n = head->first; + struct head *h = &heads[k]; + struct node *next = n->next; + + if (n->prev == (void *)h) + h->first = next; + else + n->prev->next = next; + + n->next = h->first; + return n->next == &node; +} + +int +main (void) +{ + if (foo ()) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr62294.c b/gcc/testsuite/gcc.dg/pr62294.c new file mode 100644 index 00000000000..c6ec5a75369 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr62294.c @@ -0,0 +1,10 @@ +/* PR c/62294 */ +/* { dg-do compile } */ + +#include "pr62294.h" + +void +fn (int *u) +{ + foo (u); /* { dg-error "passing argument 1 of .bar. from incompatible pointer type" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr62294.h b/gcc/testsuite/gcc.dg/pr62294.h new file mode 100644 index 00000000000..9be45adeabd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr62294.h @@ -0,0 +1,3 @@ +#pragma GCC system_header +#define foo bar +extern void foo (float *); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c index 74b60a054b7..49163c2431b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c @@ -4,7 +4,7 @@ The testcase comes from PR 29256 (and originally, the stream benchmark). */ -/* { dg-do compile { target { i?86-*-* || { x86_64-*-* || powerpc_hard_double } } } } */ +/* { dg-do compile { target { i?86-*-* || { x86_64-*-* || { powerpc_hard_double && { ! powerpc_fprs } } } } } } */ /* { dg-require-effective-target nonpic } */ /* { dg-options "-O3 -fno-tree-loop-distribute-patterns -fno-prefetch-loop-arrays -fdump-tree-optimized -fno-common" } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr62073.c b/gcc/testsuite/gcc.dg/vect/pr62073.c new file mode 100644 index 00000000000..15f2ad66b0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr62073.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O1" } */ + +struct S0 +{ + int f7; +}; +struct S0 g_50; +int g_70; +int g_76; + +int foo (long long p_56, int * p_57) +{ + int *l_77; + int l_101; + + for (; g_70;) + { + int **l_78 = &l_77; + if (g_50.f7) + continue; + *l_78 = 0; + } + for (g_76 = 1; g_76 >= 0; g_76--) + { + int *l_90; + for (l_101 = 4; l_101 >= 0; l_101--) + if (l_101) + *l_90 = 0; + else + { + int **l_113 = &l_77; + *l_113 = p_57; + } + } + + return *l_77; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/pr62262.c b/gcc/testsuite/gcc.target/aarch64/pr62262.c new file mode 100644 index 00000000000..5bf90bf7fe3 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr62262.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fprofile-use" } */ + +static inline int CLZ(int mask) { + return mask ? __builtin_clz(mask) : 32; +} + +int foo(int value) +{ + if (value == 0) + return 0; + + int bias = CLZ(value); + value >>= bias; + int zeros = CLZ(value << 1); + value <<= zeros; + + int packed = (unsigned)(value << 9) >> 9; + return packed; +} diff --git a/gcc/testsuite/gcc.target/arm/frame-pointer-1.c b/gcc/testsuite/gcc.target/arm/frame-pointer-1.c index bb1888e389e..c288fef83b0 100644 --- a/gcc/testsuite/gcc.target/arm/frame-pointer-1.c +++ b/gcc/testsuite/gcc.target/arm/frame-pointer-1.c @@ -1,6 +1,7 @@ /* Check local register variables using a register conventionally used as the frame pointer aren't clobbered under high register pressure. */ /* { dg-do run } */ +/* { dg-skip-if "incompatible options" { ! { arm_thumb1_ok || arm_thumb2_ok } } { "*" } { "" } } */ /* { dg-options "-Os -mthumb -fomit-frame-pointer" } */ #include <stdlib.h> diff --git a/gcc/testsuite/gcc.target/arm/neon-vext-execute.c b/gcc/testsuite/gcc.target/arm/neon-vext-execute.c index 3d6c28cca89..8e44d9ad555 100644 --- a/gcc/testsuite/gcc.target/arm/neon-vext-execute.c +++ b/gcc/testsuite/gcc.target/arm/neon-vext-execute.c @@ -1,5 +1,6 @@ /* { dg-do run } */ /* { dg-require-effective-target arm_neon_ok } */ +/* { dg-require-effective-target arm_neon_hw } */ /* { dg-require-effective-target arm_little_endian } */ /* { dg-options "-O2" } */ /* { dg-add-options arm_neon } */ diff --git a/gcc/testsuite/gcc.target/arm/pr56184.C b/gcc/testsuite/gcc.target/arm/pr56184.C index d44c1b432da..5d23c40c582 100644 --- a/gcc/testsuite/gcc.target/arm/pr56184.C +++ b/gcc/testsuite/gcc.target/arm/pr56184.C @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "incompatible options" { ! { arm_thumb1_ok || arm_thumb2_ok } } { "*" } { "" } } */ /* { dg-options "-fno-short-enums -O2 -mthumb -march=armv7-a -mfpu=neon -mfloat-abi=softfp -mtune=cortex-a9 -fno-section-anchors" } */ typedef unsigned int size_t; diff --git a/gcc/testsuite/gcc.target/arm/pr58784.c b/gcc/testsuite/gcc.target/arm/pr58784.c index e3ef950b499..9a1fcff1cd0 100644 --- a/gcc/testsuite/gcc.target/arm/pr58784.c +++ b/gcc/testsuite/gcc.target/arm/pr58784.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "incompatible options" { arm_thumb1 } { "*" } { "" } } */ /* { dg-options "-march=armv7-a -mfloat-abi=hard -mfpu=neon -marm -O2" } */ typedef struct __attribute__ ((__packed__)) diff --git a/gcc/testsuite/gcc.target/arm/pr59896.c b/gcc/testsuite/gcc.target/arm/pr59896.c index 5896e73799d..ea6dc248b98 100644 --- a/gcc/testsuite/gcc.target/arm/pr59896.c +++ b/gcc/testsuite/gcc.target/arm/pr59896.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "incompatible options" { ! { arm_thumb1_ok || arm_thumb2_ok } } { "*" } { "" } } */ /* { dg-options "-mthumb -O2" } */ typedef unsigned int size_t; diff --git a/gcc/testsuite/gcc.target/arm/pr59985.C b/gcc/testsuite/gcc.target/arm/pr59985.C index cc688a96533..1351c486fe3 100644 --- a/gcc/testsuite/gcc.target/arm/pr59985.C +++ b/gcc/testsuite/gcc.target/arm/pr59985.C @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "incompatible options" { arm_thumb1 } { "*" } { "" } } */ /* { dg-options "-g -fcompare-debug -O2 -march=armv7-a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mfloat-abi=hard" } */ extern void *f1 (unsigned long, unsigned long); diff --git a/gcc/testsuite/gcc.target/arm/stack-red-zone.c b/gcc/testsuite/gcc.target/arm/stack-red-zone.c index b9f0f99371e..8db2e2c092a 100644 --- a/gcc/testsuite/gcc.target/arm/stack-red-zone.c +++ b/gcc/testsuite/gcc.target/arm/stack-red-zone.c @@ -1,4 +1,5 @@ /* No stack red zone. PR38644. */ +/* { dg-skip-if "incompatible options" { ! { arm_thumb1_ok || arm_thumb2_ok } } { "*" } { "" } } */ /* { dg-options "-mthumb -O2" } */ /* { dg-final { scan-assembler "ldrb\[^\n\]*\\n\[\t \]*add\[\t \]*sp" } } */ diff --git a/gcc/testsuite/gcc.target/arm/thumb-find-work-register.c b/gcc/testsuite/gcc.target/arm/thumb-find-work-register.c index f2c0225a4d2..e67a627ea31 100644 --- a/gcc/testsuite/gcc.target/arm/thumb-find-work-register.c +++ b/gcc/testsuite/gcc.target/arm/thumb-find-work-register.c @@ -1,5 +1,6 @@ /* Wrong method to get number of arg reg will cause argument corruption. */ /* { dg-do run } */ +/* { dg-skip-if "incompatible options" { ! { arm_thumb1_ok || arm_thumb2_ok } } { "*" } { "" } } */ /* { dg-require-effective-target arm_eabi } */ /* { dg-options "-mthumb -O1" } */ diff --git a/gcc/testsuite/gcc.target/i386/xop-imul64-vector.c b/gcc/testsuite/gcc.target/i386/xop-imul64-vector.c index 382677e6050..97ef3935a8b 100644 --- a/gcc/testsuite/gcc.target/i386/xop-imul64-vector.c +++ b/gcc/testsuite/gcc.target/i386/xop-imul64-vector.c @@ -33,4 +33,3 @@ int main () /* { dg-final { scan-assembler "vpmulld" } } */ /* { dg-final { scan-assembler "vphadddq" } } */ -/* { dg-final { scan-assembler "vpmacsdql" } } */ diff --git a/gcc/testsuite/gcc.target/mips/pr62030-octeon.c b/gcc/testsuite/gcc.target/mips/pr62030-octeon.c new file mode 100644 index 00000000000..5e3d3b3b635 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/pr62030-octeon.c @@ -0,0 +1,50 @@ +/* { dg-do run } */ +/* { dg-options "-march=octeon" } */ + +extern void abort (void); + +struct node +{ + struct node *next; + struct node *prev; +}; + +struct node node; + +struct head +{ + struct node *first; +}; + +struct head heads[5]; + +int k = 2; + +struct head *head = &heads[2]; + +static int __attribute__((noinline)) +foo (void) +{ + node.prev = (void *)head; + head->first = &node; + + struct node *n = head->first; + struct head *h = &heads[k]; + struct node *next = n->next; + + if (n->prev == (void *)h) + h->first = next; + else + n->prev->next = next; + + n->next = h->first; + return n->next == &node; +} + +int +main (void) +{ + if (foo ()) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/sh/pr61996.c b/gcc/testsuite/gcc.target/sh/pr61996.c new file mode 100644 index 00000000000..51a5f929d55 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr61996.c @@ -0,0 +1,12 @@ +/* Check that the option -musermode has no effect on targets that do not + support user/privileged mode and that it does not interfere with option + -matomic-model=soft-imask. */ +/* { dg-do compile } */ +/* { dg-options "-matomic-model=soft-imask" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*"} { "-m1*" "-m2*" } } */ + +int +test (void) +{ + return 0; +} diff --git a/gcc/testsuite/gfortran.dg/array_assignment_5.f90 b/gcc/testsuite/gfortran.dg/array_assignment_5.f90 new file mode 100644 index 00000000000..6d585270cea --- /dev/null +++ b/gcc/testsuite/gfortran.dg/array_assignment_5.f90 @@ -0,0 +1,16 @@ +! { dg-do run } +! { dg-options "-ffrontend-optimize" } +! PR 62214 - this used to give the wrong result. +! Original test case by Oliver Fuhrer +PROGRAM test + IMPLICIT NONE + CHARACTER(LEN=20) :: fullNames(2) + CHARACTER(LEN=255) :: pathName + CHARACTER(LEN=5) :: fileNames(2) + + pathName = "/dir1/dir2/" + fileNames = (/ "file1", "file2" /) + fullNames = SPREAD(TRIM(pathName),1,2) // fileNames + if (fullNames(1) /= '/dir1/dir2/file1' .or. & + & fullnames(2) /= '/dir1/dir2/file2') call abort +END PROGRAM test diff --git a/gcc/testsuite/gfortran.dg/array_constructor_49.f90 b/gcc/testsuite/gfortran.dg/array_constructor_49.f90 new file mode 100644 index 00000000000..6a198d676fe --- /dev/null +++ b/gcc/testsuite/gfortran.dg/array_constructor_49.f90 @@ -0,0 +1,13 @@ +! { dg-do run } +! { dg-options "-ffrontend-optimize -fdump-tree-original" } +! PR 62106 - this used to give wrong results because +! of a bogus extra temporary variable. +! Original test case by Martien Hulsen +program t + integer :: ndim=2, ndfp=4, i + character (len=8) :: line + write (unit=line,fmt='(4I2)'), (/ ( i, i = 1, ndfp ) /) + ndim + if (line /= ' 3 4 5 6') call abort +end program t +! { dg-final { scan-tree-dump-times "__var" 3 "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/bessel_7.f90 b/gcc/testsuite/gfortran.dg/bessel_7.f90 index 7e63ed1e859..c6b5f7407f7 100644 --- a/gcc/testsuite/gfortran.dg/bessel_7.f90 +++ b/gcc/testsuite/gfortran.dg/bessel_7.f90 @@ -16,7 +16,7 @@ implicit none real,parameter :: values(*) = [0.0, 0.5, 1.0, 0.9, 1.8,2.0,3.0,4.0,4.25,8.0,34.53, 475.78] real,parameter :: myeps(size(values)) = epsilon(0.0) & - * [2, 3, 4, 5, 8, 2, 12, 6, 7, 6, 36, 168 ] + * [2, 3, 4, 5, 8, 2, 13, 6, 7, 6, 36, 168 ] ! The following is sufficient for me - the values above are a bit ! more tolerant ! * [0, 0, 0, 3, 3, 0, 9, 0, 2, 1, 22, 130 ] diff --git a/gcc/testsuite/gfortran.dg/gomp/pr62131.f90 b/gcc/testsuite/gfortran.dg/gomp/pr62131.f90 new file mode 100644 index 00000000000..8e88cd70bcc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr62131.f90 @@ -0,0 +1,19 @@ +! PR fortran/62131 +! { dg-do compile } +! { dg-options "-fopenmp" } + +program pr62131 + integer,allocatable :: nerrs(:,:) + allocate(nerrs(10,10)) + nerrs(:,:) = 0 +!$omp parallel do + do k=1,10 + call uperrs(k,1) + end do +contains + subroutine uperrs(i,io) + integer,intent(in) :: i,io +!$omp atomic + nerrs(i,io)=nerrs(i,io)+1 + end subroutine +end diff --git a/gcc/testsuite/gfortran.dg/pointer_intent_7.f90 b/gcc/testsuite/gfortran.dg/pointer_intent_7.f90 index c09eb2b5ffa..5387ace8c19 100644 --- a/gcc/testsuite/gfortran.dg/pointer_intent_7.f90 +++ b/gcc/testsuite/gfortran.dg/pointer_intent_7.f90 @@ -23,7 +23,7 @@ contains call bar2 (c) call bar3 (c) call bar2p (b) ! { dg-error "INTENT\\(IN\\) in pointer association context \\(actual argument to INTENT = OUT/INOUT" } - call bar3p (b) ! { dg-error "INTENT\\(IN\\) in pointer association context \\(actual argument to INTENT = OUT/INOUT" } + call bar3p (b) ! { dg-error "Actual argument to .n. at \\(1\\) must be polymorphic" } call bar2p (c) ! { dg-error "INTENT\\(IN\\) in pointer association context \\(actual argument to INTENT = OUT/INOUT" } call bar3p (c) ! { dg-error "INTENT\\(IN\\) in pointer association context \\(actual argument to INTENT = OUT/INOUT" } end subroutine diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_24.f90 b/gcc/testsuite/gfortran.dg/realloc_on_assign_24.f90 new file mode 100644 index 00000000000..6f88c2bf27c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_24.f90 @@ -0,0 +1,10 @@ +! { dg-do compile } +! PR 62142 - this used to segfault +! Original test case by Ondřej Čertík . +program test_segfault + implicit none + real, allocatable :: X(:) + allocate (x(1)) + x = 1. + X = floor(X) +end program diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index d4479126648..30b35c8137d 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -2564,13 +2564,16 @@ proc check_effective_target_arm_v8_neon_ok_nocache { } { if { [check_effective_target_arm32] } { foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp-armv8" "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} { if { [check_no_compiler_messages_nocache arm_v8_neon_ok object { + #if __ARM_ARCH < 8 + #error not armv8 or later + #endif #include "arm_neon.h" void foo () { __asm__ volatile ("vrintn.f32 q0, q0"); } - } "$flags"] } { + } "$flags -march=armv8-a"] } { set et_arm_v8_neon_flags $flags return 1 } @@ -2747,6 +2750,7 @@ proc check_effective_target_arm_thumb1_ok { } { #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__) #error FOO #endif + int foo (int i) { return i; } } "-mthumb"] } @@ -2758,6 +2762,7 @@ proc check_effective_target_arm_thumb2_ok { } { #if !defined(__thumb2__) #error FOO #endif + int foo (int i) { return i; } } "-mthumb"] } diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 56b6c3595b8..1469d782f73 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -162,6 +162,7 @@ static int gimple_verify_flow_info (void); static void gimple_make_forwarder_block (edge); static gimple first_non_label_stmt (basic_block); static bool verify_gimple_transaction (gimple); +static bool call_can_make_abnormal_goto (gimple); /* Flowgraph optimization and cleanup. */ static void gimple_merge_blocks (basic_block, basic_block); @@ -424,6 +425,32 @@ assert_unreachable_fallthru_edge_p (edge e) } +/* Initialize GF_CALL_CTRL_ALTERING flag, which indicates the call + could alter control flow except via eh. We initialize the flag at + CFG build time and only ever clear it later. */ + +static void +gimple_call_initialize_ctrl_altering (gimple stmt) +{ + int flags = gimple_call_flags (stmt); + + /* A call alters control flow if it can make an abnormal goto. */ + if (call_can_make_abnormal_goto (stmt) + /* A call also alters control flow if it does not return. */ + || flags & ECF_NORETURN + /* TM ending statements have backedges out of the transaction. + Return true so we split the basic block containing them. + Note that the TM_BUILTIN test is merely an optimization. */ + || ((flags & ECF_TM_BUILTIN) + && is_tm_ending_fndecl (gimple_call_fndecl (stmt))) + /* BUILT_IN_RETURN call is same as return statement. */ + || gimple_call_builtin_p (stmt, BUILT_IN_RETURN)) + gimple_call_set_ctrl_altering (stmt, true); + else + gimple_call_set_ctrl_altering (stmt, false); +} + + /* Build a flowgraph for the sequence of stmts SEQ. */ static void @@ -442,6 +469,9 @@ make_blocks (gimple_seq seq) prev_stmt = stmt; stmt = gsi_stmt (i); + if (stmt && is_gimple_call (stmt)) + gimple_call_initialize_ctrl_altering (stmt); + /* If the statement starts a new basic block or if we have determined in a previous pass that we need to create a new block for STMT, do so now. */ @@ -2349,28 +2379,10 @@ is_ctrl_altering_stmt (gimple t) switch (gimple_code (t)) { case GIMPLE_CALL: - { - int flags = gimple_call_flags (t); - - /* A call alters control flow if it can make an abnormal goto. */ - if (call_can_make_abnormal_goto (t)) - return true; - - /* A call also alters control flow if it does not return. */ - if (flags & ECF_NORETURN) - return true; - - /* TM ending statements have backedges out of the transaction. - Return true so we split the basic block containing them. - Note that the TM_BUILTIN test is merely an optimization. */ - if ((flags & ECF_TM_BUILTIN) - && is_tm_ending_fndecl (gimple_call_fndecl (t))) - return true; - - /* BUILT_IN_RETURN call is same as return statement. */ - if (gimple_call_builtin_p (t, BUILT_IN_RETURN)) - return true; - } + /* Per stmt call flag indicates whether the call could alter + controlflow. */ + if (gimple_call_ctrl_altering_p (t)) + return true; break; case GIMPLE_EH_DISPATCH: @@ -8470,6 +8482,8 @@ execute_fixup_cfg (void) && (!is_gimple_call (stmt) || (gimple_call_flags (stmt) & ECF_NORETURN) == 0))) { + if (stmt && is_gimple_call (stmt)) + gimple_call_set_ctrl_altering (stmt, false); stmt = gimple_build_call (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0); gimple_stmt_iterator gsi = gsi_last_bb (bb); @@ -8480,10 +8494,6 @@ execute_fixup_cfg (void) if (count_scale != REG_BR_PROB_BASE) compute_function_frequency (); - /* We just processed all calls. */ - if (cfun->gimple_df) - vec_free (MODIFIED_NORETURN_CALLS (cfun)); - /* Dump a textual representation of the flowgraph. */ if (dump_file) gimple_dump_cfg (dump_file, dump_flags); diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index b7882cf6762..51b764f816a 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -162,6 +162,23 @@ cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi) return retval; } +/* Cleanup the GF_CALL_CTRL_ALTERING flag according to + to updated gimple_call_flags. */ + +static void +cleanup_call_ctrl_altering_flag (gimple bb_end) +{ + if (!is_gimple_call (bb_end) + || !gimple_call_ctrl_altering_p (bb_end)) + return; + + int flags = gimple_call_flags (bb_end); + if (((flags & (ECF_CONST | ECF_PURE)) + && !(flags & ECF_LOOPING_CONST_OR_PURE)) + || (flags & ECF_LEAF)) + gimple_call_set_ctrl_altering (bb_end, false); +} + /* Try to remove superfluous control structures in basic block BB. Returns true if anything changes. */ @@ -182,6 +199,9 @@ cleanup_control_flow_bb (basic_block bb) stmt = gsi_stmt (gsi); + /* Try to cleanup ctrl altering flag for call which ends bb. */ + cleanup_call_ctrl_altering_flag (stmt); + if (gimple_code (stmt) == GIMPLE_COND || gimple_code (stmt) == GIMPLE_SWITCH) retval |= cleanup_control_expr_graph (bb, gsi); @@ -594,30 +614,24 @@ fixup_noreturn_call (gimple stmt) known not to return, and remove the unreachable code. */ static bool -split_bbs_on_noreturn_calls (void) +split_bb_on_noreturn_calls (basic_block bb) { bool changed = false; - gimple stmt; - basic_block bb; + gimple_stmt_iterator gsi; - /* Detect cases where a mid-block call is now known not to return. */ - if (cfun->gimple_df) - while (vec_safe_length (MODIFIED_NORETURN_CALLS (cfun))) - { - stmt = MODIFIED_NORETURN_CALLS (cfun)->pop (); - bb = gimple_bb (stmt); - /* BB might be deleted at this point, so verify first - BB is present in the cfg. */ - if (bb == NULL - || bb->index < NUM_FIXED_BLOCKS - || bb->index >= last_basic_block_for_fn (cfun) - || BASIC_BLOCK_FOR_FN (cfun, bb->index) != bb - || !gimple_call_noreturn_p (stmt)) - continue; + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + if (!is_gimple_call (stmt)) + continue; + + if (gimple_call_noreturn_p (stmt)) changed |= fixup_noreturn_call (stmt); - } + } + if (changed) + bitmap_set_bit (cfgcleanup_altered_bbs, bb->index); return changed; } @@ -655,8 +669,6 @@ cleanup_tree_cfg_1 (void) basic_block bb; unsigned i, n; - retval |= split_bbs_on_noreturn_calls (); - /* Prepare the worklists of altered blocks. */ cfgcleanup_altered_bbs = BITMAP_ALLOC (NULL); @@ -672,7 +684,10 @@ cleanup_tree_cfg_1 (void) { bb = BASIC_BLOCK_FOR_FN (cfun, i); if (bb) - retval |= cleanup_tree_cfg_bb (bb); + { + retval |= cleanup_tree_cfg_bb (bb); + retval |= split_bb_on_noreturn_calls (bb); + } } /* Now process the altered blocks, as long as any are available. */ @@ -689,9 +704,9 @@ cleanup_tree_cfg_1 (void) retval |= cleanup_tree_cfg_bb (bb); - /* Rerun split_bbs_on_noreturn_calls, in case we have altered any noreturn + /* Rerun split_bb_on_noreturn_calls, in case we have altered any noreturn calls. */ - retval |= split_bbs_on_noreturn_calls (); + retval |= split_bb_on_noreturn_calls (bb); } end_recording_case_labels (); diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index c525fe579ea..76d046309bc 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -1091,12 +1091,6 @@ update_stmt_operands (struct function *fn, gimple stmt) timevar_push (TV_TREE_OPS); - /* If the stmt is a noreturn call queue it to be processed by - split_bbs_on_noreturn_calls during cfg cleanup. */ - if (is_gimple_call (stmt) - && gimple_call_noreturn_p (stmt)) - vec_safe_push (MODIFIED_NORETURN_CALLS (fn), stmt); - gcc_assert (gimple_modified_p (stmt)); build_ssa_operands (fn, stmt); gimple_set_modified (stmt, false); diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index bb3b5e6c1df..b8729ad1242 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -58,7 +58,6 @@ struct GTY (()) range_info_def { #define SSANAMES(fun) (fun)->gimple_df->ssa_names -#define MODIFIED_NORETURN_CALLS(fun) (fun)->gimple_df->modified_noreturn_calls #define DEFAULT_DEFS(fun) (fun)->gimple_df->default_defs #define num_ssa_names (vec_safe_length (cfun->gimple_df->ssa_names)) diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 4204907a133..797f24cd162 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -2321,7 +2321,8 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, } def1 = SSA_NAME_DEF_STMT (op1); - if (flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) + if (gimple_bb (def1) + && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) && loop->inner && flow_bb_inside_loop_p (loop->inner, gimple_bb (def1)) && is_gimple_assign (def1)) diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index fa2989d7286..5567bd9522d 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -414,9 +414,9 @@ typedef struct _loop_vec_info { #define LOOP_VINFO_SCALAR_LOOP(L) (L)->scalar_loop #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \ - (L)->may_misalign_stmts.length () > 0 + ((L)->may_misalign_stmts.length () > 0) #define LOOP_REQUIRES_VERSIONING_FOR_ALIAS(L) \ - (L)->may_alias_ddrs.length () > 0 + ((L)->may_alias_ddrs.length () > 0) #define LOOP_VINFO_NITERS_KNOWN_P(L) \ (tree_fits_shwi_p ((L)->num_iters) && tree_to_shwi ((L)->num_iters) > 0) diff --git a/libada/ChangeLog b/libada/ChangeLog index 94ea2e00ab6..38ba63c2db6 100644 --- a/libada/ChangeLog +++ b/libada/ChangeLog @@ -1,3 +1,7 @@ +2014-08-12 Joel Sherrill <joel.sherrill@oarcorp.com> + + * Makefile.in: Add CFLAGS_FOR_TARGET to GNATLIBCFLAGS_FOR_C. + 2014-07-16 Release Manager * GCC 4.9.1 released. diff --git a/libada/Makefile.in b/libada/Makefile.in index c307b997092..93da740635c 100644 --- a/libada/Makefile.in +++ b/libada/Makefile.in @@ -60,7 +60,7 @@ CFLAGS=-g PICFLAG = @PICFLAG@ GNATLIBFLAGS= -W -Wall -gnatpg -nostdinc GNATLIBCFLAGS= -g -O2 -GNATLIBCFLAGS_FOR_C = -W -Wall $(GNATLIBCFLAGS) \ +GNATLIBCFLAGS_FOR_C = -W -Wall $(GNATLIBCFLAGS) $(CFLAGS_FOR_TARGET) \ -fexceptions -DIN_RTS @have_getipinfo@ host_subdir = @host_subdir@ diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 89f2c8a105d..a48a7d3014e 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,19 @@ +2014-09-01 Jakub Jelinek <jakub@redhat.com> + + Backported from mainline + 2014-08-04 Jakub Jelinek <jakub@redhat.com> + + * runtime/memory.c (xmallocarray): Avoid division for the common case. + +2014-08-20 Steven G. Kargl <kargl@gcc.gnu.org> + + PR libgfortran/62188 + * m4/bessel.m4: Avoid indexing off the end of an array. + * generated/bessel_r10.c: Regenerated. + * generated/bessel_r16.c: Ditto. + * generated/bessel_r4.c: Ditto. + * generated/bessel_r8.c: Ditto. + 2014-07-31 Janne Blomqvist <jb@gcc.gnu.org> Backport from mainline diff --git a/libgfortran/generated/bessel_r10.c b/libgfortran/generated/bessel_r10.c index 14b93e91007..e6977560d90 100644 --- a/libgfortran/generated/bessel_r10.c +++ b/libgfortran/generated/bessel_r10.c @@ -162,7 +162,7 @@ bessel_yn_r10 (gfc_array_r10 * const restrict ret, int n1, int n2, x2rev = GFC_REAL_10_LITERAL(2.)/x; - for (i = 2; i <= n1+n2; i++) + for (i = 2; i <= n2 - n1; i++) { #if defined(GFC_REAL_10_INFINITY) if (unlikely (last2 == -GFC_REAL_10_INFINITY)) diff --git a/libgfortran/generated/bessel_r16.c b/libgfortran/generated/bessel_r16.c index d64fa9c138e..67dea307ef7 100644 --- a/libgfortran/generated/bessel_r16.c +++ b/libgfortran/generated/bessel_r16.c @@ -166,7 +166,7 @@ bessel_yn_r16 (gfc_array_r16 * const restrict ret, int n1, int n2, x2rev = GFC_REAL_16_LITERAL(2.)/x; - for (i = 2; i <= n1+n2; i++) + for (i = 2; i <= n2 - n1; i++) { #if defined(GFC_REAL_16_INFINITY) if (unlikely (last2 == -GFC_REAL_16_INFINITY)) diff --git a/libgfortran/generated/bessel_r4.c b/libgfortran/generated/bessel_r4.c index a86bb5fa958..7bdf07b3db7 100644 --- a/libgfortran/generated/bessel_r4.c +++ b/libgfortran/generated/bessel_r4.c @@ -162,7 +162,7 @@ bessel_yn_r4 (gfc_array_r4 * const restrict ret, int n1, int n2, x2rev = GFC_REAL_4_LITERAL(2.)/x; - for (i = 2; i <= n1+n2; i++) + for (i = 2; i <= n2 - n1; i++) { #if defined(GFC_REAL_4_INFINITY) if (unlikely (last2 == -GFC_REAL_4_INFINITY)) diff --git a/libgfortran/generated/bessel_r8.c b/libgfortran/generated/bessel_r8.c index 84018872e05..313bf179c79 100644 --- a/libgfortran/generated/bessel_r8.c +++ b/libgfortran/generated/bessel_r8.c @@ -162,7 +162,7 @@ bessel_yn_r8 (gfc_array_r8 * const restrict ret, int n1, int n2, x2rev = GFC_REAL_8_LITERAL(2.)/x; - for (i = 2; i <= n1+n2; i++) + for (i = 2; i <= n2 - n1; i++) { #if defined(GFC_REAL_8_INFINITY) if (unlikely (last2 == -GFC_REAL_8_INFINITY)) diff --git a/libgfortran/m4/bessel.m4 b/libgfortran/m4/bessel.m4 index 36ffd335688..6a865448e6b 100644 --- a/libgfortran/m4/bessel.m4 +++ b/libgfortran/m4/bessel.m4 @@ -163,7 +163,7 @@ bessel_yn_r'rtype_kind` ('rtype` * const restrict ret, int n1, int n2, x2rev = GFC_REAL_'rtype_kind`_LITERAL(2.)/x; - for (i = 2; i <= n1+n2; i++) + for (i = 2; i <= n2 - n1; i++) { #if defined('rtype_name`_INFINITY) if (unlikely (last2 == -'rtype_name`_INFINITY)) diff --git a/libgfortran/runtime/memory.c b/libgfortran/runtime/memory.c index c1e735894a5..d3b77de4b87 100644 --- a/libgfortran/runtime/memory.c +++ b/libgfortran/runtime/memory.c @@ -56,7 +56,9 @@ xmallocarray (size_t nmemb, size_t size) if (!nmemb || !size) size = nmemb = 1; - else if (nmemb > SIZE_MAX / size) +#define HALF_SIZE_T (((size_t) 1) << (__CHAR_BIT__ * sizeof (size_t) / 2)) + else if (__builtin_expect ((nmemb | size) >= HALF_SIZE_T, 0) + && nmemb > SIZE_MAX / size) { errno = ENOMEM; os_error ("Integer overflow in xmallocarray"); diff --git a/libgo/runtime/malloc.goc b/libgo/runtime/malloc.goc index 7120457a5b7..37bbf5ef63a 100644 --- a/libgo/runtime/malloc.goc +++ b/libgo/runtime/malloc.goc @@ -79,6 +79,7 @@ runtime_mallocgc(uintptr size, uintptr typ, uint32 flag) MSpan *s; MLink *v; bool incallback; + void *closure; if(size == 0) { // All 0-length allocations use this pointer. @@ -90,6 +91,10 @@ runtime_mallocgc(uintptr size, uintptr typ, uint32 flag) m = runtime_m(); g = runtime_g(); + // We should not be called in between __go_set_closure and the + // actual function call, but cope with it if we are. + closure = g->closure; + incallback = false; if(m->mcache == nil && g->ncgo > 0) { // For gccgo this case can occur when a cgo or SWIG function @@ -206,6 +211,8 @@ runtime_mallocgc(uintptr size, uintptr typ, uint32 flag) if(incallback) runtime_entersyscall(); + g->closure = closure; + return v; } diff --git a/libgo/runtime/mgc0.c b/libgo/runtime/mgc0.c index f963686e313..b5a39d962a6 100644 --- a/libgo/runtime/mgc0.c +++ b/libgo/runtime/mgc0.c @@ -2000,6 +2000,7 @@ runtime_gc(int32 force) runtime_mcall(mgc); // record a new start time in case we're going around again a.start_time = runtime_nanotime(); + m = runtime_m(); } // all done diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e708a482949..4e7f236d825 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,20 @@ +2014-08-26 Jonathan Wakely <jwakely@redhat.com> + + Backported from mainline + 2014-08-12 Jonathan Wakely <jwakely@redhat.com> + + * include/bits/basic_string.h (getline): Qualify call to prevent ADL + and add overloads for rvalue streams. + * testsuite/21_strings/basic_string/inserters_extractors/char/12.cc: + New. + * testsuite/21_strings/basic_string/inserters_extractors/wchar_t/12.cc: + New. + +2014-08-26 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/62264 + * include/experimental/string_view: Fix inconsistent exception specs. + 2014-08-09 François Dumont <fdumont@gcc.gnu.org> PR libstdc++/61667 diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index cd6037677df..93ceb6dae5d 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -2811,7 +2811,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Alloc>& __str) - { return getline(__is, __str, __is.widen('\n')); } + { return std::getline(__is, __str, __is.widen('\n')); } + +#if __cplusplus >= 201103L + /// Read a line from an rvalue stream into a string. + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>&& __is, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) + { return std::getline(__is, __str, __delim); } + + /// Read a line from an rvalue stream into a string. + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>&& __is, + basic_string<_CharT, _Traits, _Alloc>& __str) + { return std::getline(__is, __str); } +#endif template<> basic_istream<char>& diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view index e66039e4748..49f46af544f 100644 --- a/libstdc++-v3/include/experimental/string_view +++ b/libstdc++-v3/include/experimental/string_view @@ -329,7 +329,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find(_CharT __c, size_type __pos=0) const noexcept; size_type - find(const _CharT* __str, size_type __pos, size_type __n) const; + find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; size_type find(const _CharT* __str, size_type __pos=0) const noexcept @@ -343,7 +343,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION rfind(_CharT __c, size_type __pos = npos) const noexcept; size_type - rfind(const _CharT* __str, size_type __pos, size_type __n) const; + rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; size_type rfind(const _CharT* __str, size_type __pos = npos) const noexcept diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/12.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/12.cc new file mode 100644 index 00000000000..a0dda5f6390 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/12.cc @@ -0,0 +1,38 @@ +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2014 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 <string> +#include <sstream> +#include <testsuite_hooks.h> + +void +test01() +{ + std::string s; + getline(std::istringstream("First line\nSecond line\n"), s); + VERIFY( s == "First line" ); + getline(std::istringstream("Third line\nFourth line\n"), s, 'r'); + VERIFY( s == "Thi" ); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/12.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/12.cc new file mode 100644 index 00000000000..db20c0293c5 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/12.cc @@ -0,0 +1,38 @@ +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2014 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 <string> +#include <sstream> +#include <testsuite_hooks.h> + +void +test01() +{ + std::wstring s; + getline(std::wistringstream(L"First line\nSecond line\n"), s); + VERIFY( s == L"First line" ); + getline(std::wistringstream(L"Third line\nFourth line\n"), s, L'r'); + VERIFY( s == L"Thi" ); +} + +int +main() +{ + test01(); +} |