summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>2014-09-09 11:55:59 +0000
committeryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>2014-09-09 11:55:59 +0000
commited8ed458cbe365cc1ad88c09f4a02bc24c0b1cef (patch)
tree74fc6192e0a1ecfa8b0e389cc1dab13806f1d921
parent5d3882b936046af384ab4aeb5eeb535a19911de7 (diff)
downloadlinaro-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
-rw-r--r--gcc/ChangeLog428
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog9
-rw-r--r--gcc/ada/gsocket.h5
-rw-r--r--gcc/ada/s-osinte-rtems.adb2
-rw-r--r--gcc/ada/socket.c2
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/array-notation-common.c5
-rw-r--r--gcc/c/ChangeLog15
-rw-r--r--gcc/c/c-parser.c7
-rw-r--r--gcc/c/c-typeck.c134
-rw-r--r--gcc/cgraphunit.c2
-rw-r--r--gcc/config.gcc25
-rw-r--r--gcc/config/aarch64/aarch64.md3
-rw-r--r--gcc/config/arm/vfp.md10
-rw-r--r--gcc/config/gnu-user.h7
-rw-r--r--gcc/config/i386/driver-i386.c5
-rw-r--r--gcc/config/i386/i386.c15
-rw-r--r--gcc/config/i386/i386.h2
-rw-r--r--gcc/config/i386/i386.md175
-rw-r--r--gcc/config/i386/x86-tune.def5
-rw-r--r--gcc/config/pa/pa-protos.h2
-rw-r--r--gcc/config/pa/pa.c94
-rw-r--r--gcc/config/pa/pa.h10
-rw-r--r--gcc/config/pa/pa.md30
-rw-r--r--gcc/config/rs6000/constraints.md16
-rw-r--r--gcc/config/rs6000/rs6000.c112
-rw-r--r--gcc/config/rs6000/rs6000.h7
-rw-r--r--gcc/config/rs6000/rs6000.md18
-rw-r--r--gcc/config/rs6000/vsx.md331
-rw-r--r--gcc/config/sh/predicates.md2
-rw-r--r--gcc/config/sh/sh.c6
-rw-r--r--gcc/config/sh/sh.md40
-rw-r--r--gcc/config/sh/sh.opt2
-rw-r--r--gcc/cp/ChangeLog43
-rw-r--r--gcc/cp/class.c23
-rw-r--r--gcc/cp/cp-array-notation.c5
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c24
-rw-r--r--gcc/cp/decl2.c5
-rw-r--r--gcc/cp/expr.c8
-rw-r--r--gcc/cp/init.c44
-rw-r--r--gcc/cp/lambda.c5
-rw-r--r--gcc/cp/pt.c18
-rw-r--r--gcc/cp/semantics.c1
-rw-r--r--gcc/cp/typeck2.c3
-rw-r--r--gcc/doc/invoke.texi128
-rw-r--r--gcc/doc/md.texi14
-rw-r--r--gcc/emit-rtl.c2
-rw-r--r--gcc/emit-rtl.h3
-rw-r--r--gcc/expr.c2
-rw-r--r--gcc/fortran/ChangeLog63
-rw-r--r--gcc/fortran/frontend-passes.c30
-rw-r--r--gcc/fortran/gfortran.h2
-rw-r--r--gcc/fortran/interface.c2
-rw-r--r--gcc/fortran/module.c5
-rw-r--r--gcc/fortran/openmp.c9
-rw-r--r--gcc/fortran/trans-expr.c6
-rw-r--r--gcc/fortran/trans-openmp.c32
-rw-r--r--gcc/gcc.c17
-rw-r--r--gcc/gimple-fold.c4
-rw-r--r--gcc/gimple.h24
-rw-r--r--gcc/gimplify.c2
-rw-r--r--gcc/go/gofrontend/expressions.cc7
-rw-r--r--gcc/ifcvt.c31
-rw-r--r--gcc/ipa-cp.c26
-rw-r--r--gcc/lto/ChangeLog8
-rw-r--r--gcc/lto/lto-lang.c6
-rw-r--r--gcc/sched-deps.c7
-rw-r--r--gcc/testsuite/ChangeLog184
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/pr61962.c14
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/pr62008.c10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem3.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C7
-rw-r--r--gcc/testsuite/g++.dg/init/explicit2.C8
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-39.C28
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr62015.C55
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local10.C23
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr62312.c23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/bitfld-6.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr61986.c48
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr60449_0.c30
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr60449_1.c76
-rw-r--r--gcc/testsuite/gcc.dg/pr56724-1.c33
-rw-r--r--gcc/testsuite/gcc.dg/pr56724-2.c31
-rw-r--r--gcc/testsuite/gcc.dg/pr59418.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr61776.c27
-rw-r--r--gcc/testsuite/gcc.dg/pr62004.c47
-rw-r--r--gcc/testsuite/gcc.dg/pr62030.c50
-rw-r--r--gcc/testsuite/gcc.dg/pr62294.c10
-rw-r--r--gcc/testsuite/gcc.dg/pr62294.h3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-19.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr62073.c40
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr62262.c20
-rw-r--r--gcc/testsuite/gcc.target/arm/frame-pointer-1.c1
-rw-r--r--gcc/testsuite/gcc.target/arm/neon-vext-execute.c1
-rw-r--r--gcc/testsuite/gcc.target/arm/pr56184.C1
-rw-r--r--gcc/testsuite/gcc.target/arm/pr58784.c1
-rw-r--r--gcc/testsuite/gcc.target/arm/pr59896.c1
-rw-r--r--gcc/testsuite/gcc.target/arm/pr59985.C1
-rw-r--r--gcc/testsuite/gcc.target/arm/stack-red-zone.c1
-rw-r--r--gcc/testsuite/gcc.target/arm/thumb-find-work-register.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/xop-imul64-vector.c1
-rw-r--r--gcc/testsuite/gcc.target/mips/pr62030-octeon.c50
-rw-r--r--gcc/testsuite/gcc.target/sh/pr61996.c12
-rw-r--r--gcc/testsuite/gfortran.dg/array_assignment_5.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/array_constructor_49.f9013
-rw-r--r--gcc/testsuite/gfortran.dg/bessel_7.f902
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr62131.f9019
-rw-r--r--gcc/testsuite/gfortran.dg/pointer_intent_7.f902
-rw-r--r--gcc/testsuite/gfortran.dg/realloc_on_assign_24.f9010
-rw-r--r--gcc/testsuite/lib/target-supports.exp7
-rw-r--r--gcc/tree-cfg.c62
-rw-r--r--gcc/tree-cfgcleanup.c61
-rw-r--r--gcc/tree-ssa-operands.c6
-rw-r--r--gcc/tree-ssanames.h1
-rw-r--r--gcc/tree-vect-loop.c3
-rw-r--r--gcc/tree-vectorizer.h4
-rw-r--r--libada/ChangeLog4
-rw-r--r--libada/Makefile.in2
-rw-r--r--libgfortran/ChangeLog16
-rw-r--r--libgfortran/generated/bessel_r10.c2
-rw-r--r--libgfortran/generated/bessel_r16.c2
-rw-r--r--libgfortran/generated/bessel_r4.c2
-rw-r--r--libgfortran/generated/bessel_r8.c2
-rw-r--r--libgfortran/m4/bessel.m42
-rw-r--r--libgfortran/runtime/memory.c4
-rw-r--r--libgo/runtime/malloc.goc7
-rw-r--r--libgo/runtime/mgc0.c1
-rw-r--r--libstdc++-v3/ChangeLog17
-rw-r--r--libstdc++-v3/include/bits/basic_string.h18
-rw-r--r--libstdc++-v3/include/experimental/string_view4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/12.cc38
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/12.cc38
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();
+}