summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2014-01-13 19:14:33 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2014-01-13 19:14:33 +0000
commit0dd8cf9cc8350069e94a624959d1ad4487c46a8c (patch)
tree63472a8da3b4d5a6c33190c256b60a5710d30a18 /gcc
parentfe644b69d013e77c7fc2db2a9863969d4f564561 (diff)
parent69888cc76b4873822f5e48b66f69e9d20d19fc50 (diff)
Merge in trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@206584 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog539
-rw-r--r--gcc/ChangeLog-201361
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in7
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/ada/gcc-interface/cuintp.c19
-rw-r--r--gcc/asan.c15
-rw-r--r--gcc/builtins.c2
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-pch.c2
-rw-r--r--gcc/c/ChangeLog12
-rw-r--r--gcc/c/c-decl.c3
-rw-r--r--gcc/c/c-parser.c2
-rw-r--r--gcc/cfgcleanup.c15
-rw-r--r--gcc/cfgexpand.c17
-rw-r--r--gcc/cgraph.h8
-rw-r--r--gcc/config.gcc24
-rw-r--r--gcc/config/aarch64/aarch64-elf.h1
-rw-r--r--gcc/config/aarch64/aarch64-modes.def1
-rw-r--r--gcc/config/aarch64/aarch64.c25
-rw-r--r--gcc/config/aarch64/aarch64.md4
-rw-r--r--gcc/config/arm/arm-cores.def6
-rw-r--r--gcc/config/arm/arm.c33
-rw-r--r--gcc/config/arm/arm.h2
-rw-r--r--gcc/config/darwin.c75
-rw-r--r--gcc/config/i386/i386.c90
-rw-r--r--gcc/config/i386/i386.h6
-rw-r--r--gcc/config/i386/i386.md2
-rw-r--r--gcc/config/i386/sse.md26
-rw-r--r--gcc/config/mips/driver-native.c10
-rw-r--r--gcc/config/mips/mips.c20
-rw-r--r--gcc/config/mips/mips.h4
-rw-r--r--gcc/config/mips/mips.md31
-rw-r--r--gcc/config/pa/pa.c9
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def10
-rw-r--r--gcc/config/rs6000/rs6000-c.c4
-rw-r--r--gcc/config/rs6000/rs6000.c97
-rw-r--r--gcc/config/rs6000/rs6000.h12
-rw-r--r--gcc/config/rs6000/rs6000.md16
-rw-r--r--gcc/config/rs6000/rs6000.opt8
-rw-r--r--gcc/config/s390/s390.c41
-rw-r--r--gcc/config/sh/sh-mem.cc203
-rw-r--r--gcc/cp/ChangeLog58
-rw-r--r--gcc/cp/class.c81
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/cvt.c4
-rw-r--r--gcc/cp/lambda.c2
-rw-r--r--gcc/cp/mangle.c5
-rw-r--r--gcc/cp/parser.c38
-rw-r--r--gcc/cp/pt.c11
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/doc/implement-c.texi5
-rw-r--r--gcc/doc/invoke.texi67
-rw-r--r--gcc/doc/tree-ssa.texi3
-rw-r--r--gcc/expr.c152
-rw-r--r--gcc/expr.h11
-rw-r--r--gcc/fortran/ChangeLog35
-rw-r--r--gcc/fortran/class.c49
-rw-r--r--gcc/fortran/cpp.c1
-rw-r--r--gcc/fortran/decl.c10
-rw-r--r--gcc/fortran/resolve.c8
-rw-r--r--gcc/fortran/trans-io.c2
-rw-r--r--gcc/function.c3
-rw-r--r--gcc/gcov-io.c55
-rw-r--r--gcc/gcov-io.h270
-rw-r--r--gcc/gdbasan.in4
-rw-r--r--gcc/gimple-fold.c49
-rw-r--r--gcc/gimple.c68
-rw-r--r--gcc/gimple.h3
-rw-r--r--gcc/gimplify.c12
-rw-r--r--gcc/go/gofrontend/expressions.cc326
-rw-r--r--gcc/go/gofrontend/expressions.h39
-rw-r--r--gcc/go/gofrontend/go.cc5
-rw-r--r--gcc/go/gofrontend/gogo.cc215
-rw-r--r--gcc/go/gofrontend/gogo.h18
-rw-r--r--gcc/go/gofrontend/statements.cc11
-rw-r--r--gcc/go/gofrontend/statements.h19
-rw-r--r--gcc/go/gofrontend/types.cc81
-rw-r--r--gcc/go/gofrontend/types.h18
-rw-r--r--gcc/hash-table.h5
-rw-r--r--gcc/hw-doloop.c1
-rw-r--r--gcc/ifcvt.c35
-rw-r--r--gcc/ipa-cp.c2
-rw-r--r--gcc/ipa-devirt.c76
-rw-r--r--gcc/ipa-prop.c8
-rw-r--r--gcc/lto/ChangeLog11
-rw-r--r--gcc/lto/lto.c20
-rw-r--r--gcc/modulo-sched.c3
-rw-r--r--gcc/omp-low.c23
-rw-r--r--gcc/optabs.c2
-rw-r--r--gcc/params.def30
-rw-r--r--gcc/params.h12
-rw-r--r--gcc/ree.c166
-rw-r--r--gcc/reorg.c14
-rw-r--r--gcc/stor-layout.c16
-rw-r--r--gcc/target-globals.c55
-rw-r--r--gcc/target-globals.h30
-rw-r--r--gcc/testsuite/ChangeLog405
-rw-r--r--gcc/testsuite/c-c++-common/asan/no-asan-globals.c13
-rw-r--r--gcc/testsuite/c-c++-common/asan/no-asan-stack.c16
-rw-r--r--gcc/testsuite/c-c++-common/asan/no-instrument-reads.c13
-rw-r--r--gcc/testsuite/c-c++-common/asan/no-instrument-writes.c13
-rw-r--r--gcc/testsuite/c-c++-common/asan/no-use-after-return.c13
-rw-r--r--gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c2
-rw-r--r--gcc/testsuite/c-c++-common/asan/use-after-return-1.c53
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c2
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/pr59631.c15
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/spawnee_inline.c2
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/spawner_inline.c2
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c2
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c2
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/varargs_test.c2
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/pr59667.c15
-rw-r--r--gcc/testsuite/g++.dg/abi/abi-tag5.C3
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp30
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-39.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-union3.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic145.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58500.C3
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58534.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58536.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58548.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58549.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58637.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr59112.C3
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr59113.C3
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr59629.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr59635.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr59636.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr59638.C14
-rw-r--r--gcc/testsuite/g++.dg/ext/is_base_of_incomplete-2.C5
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-20.C31
-rw-r--r--gcc/testsuite/g++.dg/lto/lto.exp10
-rw-r--r--gcc/testsuite/g++.dg/opt/pr59622-2.C21
-rw-r--r--gcc/testsuite/g++.dg/opt/pr59622-3.C21
-rw-r--r--gcc/testsuite/g++.dg/opt/pr59622-4.C23
-rw-r--r--gcc/testsuite/g++.dg/opt/pr59622-5.C26
-rw-r--r--gcc/testsuite/g++.dg/pr58950.C8
-rw-r--r--gcc/testsuite/g++.dg/pr59510.C82
-rw-r--r--gcc/testsuite/g++.dg/torture/pr58252.C142
-rw-r--r--gcc/testsuite/g++.dg/torture/pr58585.C20
-rw-r--r--gcc/testsuite/g++.dg/torture/pr59226.C27
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr59743.c23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr59643.c39
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp16
-rw-r--r--gcc/testsuite/gcc.dg/delay-slot-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr59669-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr59669-2.c9
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr59008.c32
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr59610.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr46309.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr57773.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr58668.c25
-rw-r--r--gcc/testsuite/gcc.dg/pr59350-2.c29
-rw-r--r--gcc/testsuite/gcc.dg/pr59350.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr59471.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr59630.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr59643.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr59670.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr59722.c36
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57748-3.c40
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57748-4.c40
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr59374-3.c21
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr59715.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-33.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-34.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-35.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-36.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp47.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp87.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr59519-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr59519-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-simd-clone-10.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-simd-clone-12.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect.exp22
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cmn-neg.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cmn-neg2.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/neon-nested-apcs.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/neon/vst1Q_laneu64-1.c25
-rw-r--r--gcc/testsuite/gcc.target/i386/asm-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vcmppd-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vcmpps-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vfixupimmpd-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vfixupimmps-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vfixupimmsd-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vfixupimmss-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vgetmantpd-2.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vgetmantps-2.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vgetmantsd-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vgetmantss-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/incoming-5.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/intrinsics_4.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr47735.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53623.c25
-rw-r--r--gcc/testsuite/gcc.target/i386/pr55433.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr56246.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr57848.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59099.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59390.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59390_1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59390_2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59501-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59501-2.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59501-3.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59501-4.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59501-5.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59501-6.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59644.c42
-rw-r--r--gcc/testsuite/gcc.target/mips/pr59137.c34
-rw-r--r--gcc/testsuite/gcc.target/mips/umips-branch-3.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/umips-branch-4.c12
-rw-r--r--gcc/testsuite/gcc.target/sh/cmpstrn.c13
-rw-r--r--gcc/testsuite/gfortran.dg/alloc_comp_basics_6.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_procs_2.f9022
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_10_main.f031
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_26a.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_26b.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/class_allocate_16.f9028
-rw-r--r--gcc/testsuite/gfortran.dg/inquire_10.f902
-rw-r--r--gcc/testsuite/gfortran.dg/inquire_15.f901
-rw-r--r--gcc/testsuite/gfortran.dg/lto/lto.exp10
-rw-r--r--gcc/testsuite/gfortran.dg/open_negative_unit_1.f909
-rw-r--r--gcc/testsuite/gfortran.dg/pr16597.f902
-rw-r--r--gcc/testsuite/gfortran.dg/pr59700.f9040
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_proc_32.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/use_only_3.f901
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization17.adb22
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization17_pkg.adb5
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization17_pkg.ads29
-rw-r--r--gcc/testsuite/gnat.dg/weak2.adb10
-rw-r--r--gcc/testsuite/gnat.dg/weak2.ads9
-rw-r--r--gcc/testsuite/go.test/go-test.exp15
-rw-r--r--gcc/testsuite/lib/target-supports.exp53
-rw-r--r--gcc/toplev.c29
-rw-r--r--gcc/tree-cfg.c3
-rw-r--r--gcc/tree-cfg.h1
-rw-r--r--gcc/tree-core.h9
-rw-r--r--gcc/tree-predcom.c36
-rw-r--r--gcc/tree-ssa-loop-ivopts.c91
-rw-r--r--gcc/tree-ssa-loop-niter.c2
-rw-r--r--gcc/tree-ssa-pre.c4
-rw-r--r--gcc/tree-ssa-sink.c6
-rw-r--r--gcc/tree-vect-data-refs.c7
-rw-r--r--gcc/tree-vect-loop-manip.c13
-rw-r--r--gcc/tree-vect-slp.c34
-rw-r--r--gcc/tree.c22
-rw-r--r--gcc/tree.h8
-rw-r--r--gcc/tsan.c2
-rw-r--r--gcc/ubsan.c3
-rw-r--r--gcc/var-tracking.c24
257 files changed, 5052 insertions, 1278 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cf4cfabeb820..01b10357fb95 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,7 +1,523 @@
-2014-01-03 Bingfeng Mei <bmei@broadcom.com>
+2014-01-13 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.h (MAX_CONDITIONAL_EXECUTE): Fix typo in description.
+
+2014-01-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * builtins.c (get_object_alignment_2): Minor tweak.
+ * tree-ssa-loop-ivopts.c (may_be_unaligned_p): Rewrite.
+
+2014-01-13 Christian Bruel <christian.bruel@st.com>
+
+ * config/sh/sh-mem.cc (sh_expand_cmpnstr): Unroll small sizes and
+ optimized non constant lengths.
+
+2014-01-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/59194
+ * omp-low.c (expand_omp_atomic_pipeline): Expand the initial
+ load as __atomic_load_N if possible.
+
+2014-01-11 David Edelsohn <dje.gcc@gmail.com>
+
+ * config/rs6000/rs6000.c (rs6000_expand_mtfsf_builtin): Remove
+ target parameter.
+ (rs6000_expand_builtin): Adjust call.
+
+2014-01-11 David Edelsohn <dje.gcc@gmail.com>
+
+ PR target/58115
+ * config/rs6000/rs6000.h (SWITCHABLE_TARGET): Define.
+ * config/rs6000/rs6000.c: Include target-globals.h.
+ (rs6000_set_current_function): Instead of doing target_reinit
+ unconditionally, use save_target_globals_default_opts and
+ restore_target_globals.
+
+ * config/rs6000/rs6000-builtin.def (mffs, mtfsf): Add builtins for
+ FPSCR.
+ * config/rs6000/rs6000.c (rs6000_expand_mtfsf_builtin): New.
+ (rs6000_expand_builtin): Handle mffs and mtfsf.
+ (rs6000_init_builtins): Define mffs and mtfsf.
+ * config/rs6000/rs6000.md (UNSPECV_MFFS, UNSPECV_MTFSF): New constants.
+ (rs6000_mffs): New pattern.
+ (rs6000_mtfsf): New pattern.
+
+2014-01-11 Bin Cheng <bin.cheng@arm.com>
+
+ * tree-ssa-loop-ivopts.c (iv_ca_narrow): New parameter.
+ Start narrowing with START. Apply candidate-use pair
+ and check overall cost in narrowing.
+ (iv_ca_prune): Pass new argument.
+
+2014-01-10 Jeff Law <law@redhat.com>
+
+ PR middle-end/59743
+ * ree.c (combine_reaching_defs): Ensure the defining statement
+ occurs before the extension when optimizing extensions with
+ different source and destination hard registers.
+
+2014-01-10 Jan Hubicka <jh@suse.cz>
+
+ PR ipa/58585
+ * ipa-devirt.c (build_type_inheritance_graph): Also add types of vtables
+ into the type inheritance graph.
+
+2014-01-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/59754
+ * ree.c (combine_reaching_defs): Disallow !SCALAR_INT_MODE_P
+ modes in the REGNO != REGNO case.
+
+2014-01-10 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000-builtin.def: Fix pasto for VPKSDUS.
+
+2014-01-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59745
+ * tree-predcom.c (tree_predictive_commoning_loop): Call
+ free_affine_expand_cache if giving up because components is NULL.
+
+ * target-globals.c (save_target_globals): Allocate < 4KB structs using
+ GC in payload of target_globals struct instead of allocating them on
+ the heap and the larger structs separately using GC.
+ * target-globals.h (struct target_globals): Make regs, hard_regs,
+ reload, expmed, ira, ira_int and lra_fields GTY((atomic)) instead
+ of GTY((skip)) and change type to void *.
+ (reset_target_globals): Cast loads from those fields to corresponding
+ types.
+
+2014-01-10 Steve Ellcey <sellcey@mips.com>
+
+ PR plugins/59335
+ * Makefile.in (PLUGIN_HEADERS): Add gimplify.h, gimple-iterator.h,
+ gimple-ssa.h, fold-const.h, tree-cfg.h, tree-into-ssa.h,
+ tree-ssanames.h, print-tree.h, varasm.h, and context.h.
+
+2014-01-10 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/59744
+ * aarch64-modes.def (CC_Zmode): New flags mode.
+ * aarch64.c (aarch64_select_cc_mode): Only allow NEG when the condition
+ represents an equality.
+ (aarch64_get_condition_code): Handle CC_Zmode.
+ * aarch64.md (compare_neg<mode>): Restrict to equality operations.
+
+2014-01-10 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * config/s390/s390.c (s390_expand_tbegin): Remove jump over CC
+ extraction in good case.
+
+2014-01-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59374
+ * tree-vect-slp.c (vect_slp_analyze_bb_1): Move dependence
+ checking after SLP discovery. Mark stmts not participating
+ in any SLP instance properly.
+
+2014-01-10 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.c (arm_new_rtx_costs): Use destination mode
+ when handling a SET rtx.
+
+2014-01-10 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm-cores.def (cortex-a53): Specify FL_CRC32.
+ (cortex-a57): Likewise.
+ (cortex-a57.cortex-a53): Likewise. Remove redundant flags.
+
+2014-01-10 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.c (arm_init_iwmmxt_builtins): Skip
+ non-iwmmxt builtins.
+
+2014-01-10 Jan Hubicka <hubicka@ucw.cz>
+
+ PR ipa/58252
+ PR ipa/59226
+ * ipa-devirt.c record_target_from_binfo): Take as argument
+ stack of binfos and lookup matching one for virtual inheritance.
+ (possible_polymorphic_call_targets_1): Update.
+
+2014-01-10 Huacai Chen <chenhc@lemote.com>
+
+ * config/mips/driver-native.c (host_detect_local_cpu): Handle new
+ kernel strings for Loongson-2E/2F/3A.
+
+2014-01-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/59670
+ * tree-vect-data-refs.c (vect_analyze_data_refs): Check
+ is_gimple_call before calling gimple_call_internal_p.
+
+2014-01-09 Steve Ellcey <sellcey@mips.com>
+
+ * Makefile.in (TREE_FLOW_H): Remove.
+ (TREE_SSA_H): Add file names from tree-flow.h.
+ * doc/tree-ssa.texi (Annotations): Remove reference to tree-flow.h
+ * tree.h: Remove tree-flow.h reference.
+ * hash-table.h: Remove tree-flow.h reference.
+ * tree-ssa-loop-niter.c (dump_affine_iv): Replace tree-flow.h
+ reference with tree-ssa-loop.h.
+
+2014-01-09 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * doc/invoke.texi: Add -maltivec={be,le} options, and document
+ default element-order behavior for -maltivec.
+ * config/rs6000/rs6000.opt: Add -maltivec={be,le} options.
+ * config/rs6000/rs6000.c (rs6000_option_override_internal): Ensure
+ that -maltivec={le,be} implies -maltivec; disallow -maltivec=le
+ when targeting big endian, at least for now.
+ * config/rs6000/rs6000.h: Add #define of VECTOR_ELT_ORDER_BIG.
+
+2014-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/47735
+ * cfgexpand.c (expand_one_var): For SSA_NAMEs, if the underlying
+ var satisfies use_register_for_decl, just take into account type
+ alignment, rather than decl alignment.
+
+ PR tree-optimization/59622
+ * gimple-fold.c (gimple_fold_call): Fix a typo in message. For
+ __builtin_unreachable replace the OBJ_TYPE_REF call with a call to
+ __builtin_unreachable and add if needed a setter of the lhs SSA_NAME.
+ Don't devirtualize for inplace at all. For targets.length () == 1,
+ if the call is noreturn and cfun isn't in SSA form yet, clear lhs.
+
+2014-01-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.md (cpu): Remove the unused btver1.
+
+2014-01-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gdbasan.in: Put a breakpoint on __sanitizer::Report.
+
+2014-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/58115
+ * tree-core.h (struct target_globals): New forward declaration.
+ (struct tree_target_option): Add globals field.
+ * tree.h (TREE_TARGET_GLOBALS): Define.
+ (prepare_target_option_nodes_for_pch): New prototype.
+ * target-globals.h (struct target_globals): Define even if
+ !SWITCHABLE_TARGET.
+ * tree.c (prepare_target_option_node_for_pch,
+ prepare_target_option_nodes_for_pch): New functions.
+ * config/i386/i386.h (SWITCHABLE_TARGET): Define.
+ * config/i386/i386.c: Include target-globals.h.
+ (ix86_set_current_function): Instead of doing target_reinit
+ unconditionally, use save_target_globals_default_opts and
+ restore_target_globals.
+
+2014-01-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59715
+ * tree-cfg.h (split_critical_edges): Declare.
+ * tree-cfg.c (split_critical_edges): Export.
+ * tree-ssa-sink.c (execute_sink_code): Split critical edges.
+
+2014-01-09 Max Ostapenko <m.ostapenko@partner.samsung.com>
+
+ * cfgexpand.c (expand_stack_vars): Optionally disable
+ asan stack protection.
+ (expand_used_vars): Likewise.
+ (partition_stack_vars): Likewise.
+ * asan.c (asan_emit_stack_protection): Optionally disable
+ after return stack usage.
+ (instrument_derefs): Optionally disable memory
+ access instrumentation.
+ (instrument_builtin_call): Likewise.
+ (instrument_strlen_call): Likewise.
+ (asan_protect_global): Optionally disable
+ global variables protection.
+ * doc/invoke.texi: Added doc for new options.
+ * params.def: Added new options.
+ * params.h: Likewise.
+
+2014-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/59724
+ * ifcvt.c (cond_exec_process_if_block): Don't call
+ flow_find_head_matching_sequence with 0 longest_match.
+ * cfgcleanup.c (flow_find_head_matching_sequence): Count even
+ non-active insns if !stop_after.
+ (try_head_merge_bb): Revert 2014-01-07 changes.
+
+2014-01-08 Jeff Law <law@redhat.com>
+
+ * ree.c (get_sub_rtx): New function, extracted from...
+ (merge_def_and_ext): Here.
+ (combine_reaching_defs): Use get_sub_rtx.
+
+2014-01-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cgraph.h (varpool_variable_node): Do not choke on null node.
+
+2014-01-08 Catherine Moore <clm@codesourcery.com>
+
+ * config/mips/mips.md (simple_return): Attempt to use JRC for microMIPS.
+ * config/mips/mips.h (MIPS_CALL): Attempt to use JALS for microMIPS.
+
+2014-01-08 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR rtl-optimization/59137
+ * reorg.c (steal_delay_list_from_target): Call update_block for
+ elided insns.
+ (steal_delay_list_from_fallthrough, relax_delay_slots): Likewise.
+
+2014-01-08 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Remove
+ two duplicate entries.
+
+2014-01-08 Richard Sandiford <rdsandiford@googlemail.com>
+
+ Revert:
+ 2012-10-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips.c (mips_truncated_op_cost): New function.
+ (mips_rtx_costs): Adjust test for BADDU.
+ * config/mips/mips.md (*baddu_di<mode>): Push truncates to operands.
+
+ 2012-10-02 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips.md (*baddu_si_eb, *baddu_si_el): Merge into...
+ (*baddu_si): ...this new pattern.
+
+2014-01-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR ipa/59722
+ * ipa-prop.c (ipa_analyze_params_uses): Ignore uses in debug stmts.
+
+2014-01-08 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR middle-end/57748
+ * expr.h (expand_expr_real, expand_expr_real_1): Add new parameter
+ inner_reference_p.
+ (expand_expr, expand_normal): Adjust.
+ * expr.c (expand_expr_real, expand_expr_real_1): Add new parameter
+ inner_reference_p. Use inner_reference_p to expand inner references.
+ (store_expr): Adjust.
+ * cfgexpand.c (expand_call_stmt): Adjust.
+
+2014-01-08 Rong Xu <xur@google.com>
+
+ * gcov-io.c (gcov_var): Move from gcov-io.h.
+ (gcov_position): Ditto.
+ (gcov_is_error): Ditto.
+ (gcov_rewrite): Ditto.
+ * gcov-io.h: Refactor. Move gcov_var to gcov-io.h, and libgcov
+ only part to libgcc/libgcov.h.
+
+2014-01-08 Marek Polacek <polacek@redhat.com>
+
+ PR middle-end/59669
+ * omp-low.c (simd_clone_adjust): Don't crash if def is NULL.
+
+2014-01-08 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/59667
+ * ubsan.c (ubsan_type_descriptor): Call strip_array_types on type2.
+
+2014-01-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/59649
+ * stor-layout.c (get_mode_bounds): For BImode return
+ 0 and STORE_FLAG_VALUE.
+
+2014-01-08 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/59630
+ * gimple.h (is_gimple_builtin_call): Remove.
+ (gimple_builtin_call_types_compatible_p): New.
+ (gimple_call_builtin_p): New overload.
+ * gimple.c (is_gimple_builtin_call): Remove.
+ (validate_call): Rename to ...
+ (gimple_builtin_call_types_compatible_p): ... this and export. Also
+ check return types.
+ (validate_type): New static function.
+ (gimple_call_builtin_p): New overload and adjust.
+ * gimple-fold.c (gimple_fold_builtin): Fold the return value.
+ (gimple_fold_call): Likewise. Use gimple_call_builtin_p.
+ (gimple_fold_stmt_to_constant_1): Likewise.
+ * tsan.c (instrument_gimple): Use gimple_call_builtin_p.
+
+2014-01-08 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/59471
+ * gimplify.c (gimplify_expr): Gimplify register-register type
+ VIEW_CONVERT_EXPRs to separate stmts.
+
+2014-01-07 Jeff Law <law@redhat.com>
+
+ PR middle-end/53623
+ * ree.c (combine_set_extension): Handle case where source
+ and destination registers in an extension insn are different.
+ (combine_reaching_defs): Allow source and destination
+ registers in extension to be different under limited
+ circumstances.
+ (add_removable_extension): Remove restriction that the
+ source and destination registers in the extension are the
+ same.
+ (find_and_remove_re): Emit a copy from the extension's
+ destination to its source after the defining insn if
+ the source and destination registers are different.
+
+ PR middle-end/59285
+ * ifcvt.c (merge_if_block): If we are merging a block with more than
+ one successor with a block with no successors, remove any BARRIER
+ after the second block.
+
+2014-01-07 Dan Xio Qiang <ziyan01@163.com>
+
+ * hw-doloop.c (reorg_loops): Release the bitmap obstack.
+
+2014-01-07 John David Anglin <danglin@gcc.gnu.org>
+
+ PR target/59652
+ * config/pa/pa.c (pa_legitimate_address_p): Return false before reload
+ for 14-bit register offsets when INT14_OK_STRICT is false.
+
+2014-01-07 Roland Stigge <stigge@antcom.de>
+ Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR 57386/target
+ * config/rs6000/rs6000.c (rs6000_legitimate_offset_address_p):
+ Only check TFmode for SPE constants. Don't check TImode or
+ TDmode.
+
+2014-01-07 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-elf.h (ASM_SPEC): Remove identity spec for
+ -mcpu.
+
+2014-01-07 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * config/arm/arm.c (arm_expand_neon_args): Call expand_expr
+ with EXPAND_MEMORY for NEON_ARG_MEMORY; check if the returned
+ rtx is const0_rtx or not.
+
+2014-01-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR target/58115
+ * target-globals.c (save_target_globals): Remove this_fn_optab
+ handling.
+ * toplev.c: Include optabs.h.
+ (target_reinit): Temporarily restore the global options if another
+ set of options are in force.
+
+2014-01-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/58668
+ * cfgcleanup.c (flow_find_cross_jump): Don't count
+ any jumps if dir_p is NULL. Remove p1 variable, use active_insn_p
+ to determine what is counted.
+ (flow_find_head_matching_sequence): Use active_insn_p to determine
+ what is counted.
+ (try_head_merge_bb): Adjust for the flow_find_head_matching_sequence
+ counting change.
+ * ifcvt.c (count_bb_insns): Use active_insn_p && !JUMP_P to
+ determine what is counted.
+
+ PR tree-optimization/59643
+ * tree-predcom.c (split_data_refs_to_components): If one dr is
+ read and one write, determine_offset fails and the write isn't
+ in the bad component, just put the read into the bad component.
+
+2014-01-07 Mike Stump <mikestump@comcast.net>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR pch/59436
+ * tree-core.h (struct tree_optimization_option): Change optabs
+ type from unsigned char * to void *.
+ * optabs.c (init_tree_optimization_optabs): Adjust
+ TREE_OPTIMIZATION_OPTABS initialization.
+
+2014-01-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/59644
+ * config/i386/i386.h (struct machine_function): Add
+ no_drap_save_restore field.
+ * config/i386/i386.c (ix86_save_reg): Use
+ !cfun->machine->no_drap_save_restore instead of
+ crtl->stack_realign_needed.
+ (ix86_finalize_stack_realign_flags): Don't clear drap_reg unless
+ this function clears frame_pointer_needed. Set
+ cfun->machine->no_drap_save_restore if clearing frame_pointer_needed
+ and DRAP reg is needed.
+
+2014-01-06 Marek Polacek <polacek@redhat.com>
+
+ PR c/57773
+ * doc/implement-c.texi: Mention that other integer types are
+ permitted as bit-field types in strictly conforming mode.
+
+2014-01-06 Felix Yang <fei.yang0953@gmail.com>
+
+ * modulo-sched.c (schedule_reg_moves): Clear distance1_uses if it
+ is newly allocated.
+
+2014-01-06 Richard Earnshaw <rearnsha@arm.com>
+
+ * aarch64.c (aarch64_rtx_costs): Fix cost calculation for MADD.
+
+2014-01-06 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/59008
+ * ipa-cp.c (ipcp_discover_new_direct_edges): Changed param_index type
+ to int.
+ * ipa-prop.c (ipa_print_node_params): Fix indentation.
+
+2014-01-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR debug/59350
+ PR debug/59510
+ * var-tracking.c (add_stores): Preserve the value of the source even if
+ we don't record the store.
+
+2014-01-06 Terry Guo <terry.guo@arm.com>
+
+ * config.gcc (arm*-*-*): Check --with-arch against arm-arches.def.
+
+2014-01-05 Iain Sandoe <iain@codesourcery.com>
+
+ PR bootstrap/59541
+ * config/darwin.c (darwin_function_section): Adjust return values to
+ correspond to optimisation changes made in r206070.
+
+2014-01-05 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.c (ix86_data_alignment): Calculate max_align
+ from prefetch_block tune setting.
+ (nocona_cost): Correct size of prefetch block to 64.
+
+2014-01-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/arm/arm.c (arm_get_frame_offsets): Revamp long lines.
+ (arm_expand_epilogue_apcs_frame): Take into account the number of bytes
+ used to save the static chain register in the computation of the offset
+ from which the FP registers need to be restored.
+
+2014-01-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59519
+ * tree-vect-loop-manip.c (slpeel_update_phi_nodes_for_guard1): Don't
+ ICE if get_current_def (current_new_name) is already non-NULL, as long
+ as it is a phi result of some other phi in *new_exit_bb that has
+ the same argument.
+
+ * config/i386/sse.md (avx512f_load<mode>_mask): Emit vmovup{s,d}
+ or vmovdqu* for misaligned_operand.
+ (<sse>_loadu<ssemodesuffix><avxsizesuffix><mask_name>,
+ <sse2_avx_avx512f>_loaddqu<mode><mask_name>): Handle <mask_applied>.
+ * config/i386/i386.c (ix86_expand_special_args_builtin): Set
+ aligned_mem for AVX512F masked aligned load and store builtins and for
+ non-temporal moves.
+
+2014-01-03 Bingfeng Mei <bmei@broadcom.com>
PR tree-optimization/59651
- * tree-vect-loop-manip.c (vect_create_cond_for_alias_checks):
+ * tree-vect-loop-manip.c (vect_create_cond_for_alias_checks):
Address range for negative step should be added by TYPE_SIZE_UNIT.
2014-01-03 Andreas Schwab <schwab@linux-m68k.org>
@@ -79,20 +595,21 @@
2014-01-02 Richard Sandiford <rdsandiford@googlemail.com>
- Update copyright years
+ Update copyright years.
2014-01-02 Richard Sandiford <rdsandiford@googlemail.com>
* common/config/arc/arc-common.c, config/arc/arc-modes.def,
config/arc/arc-protos.h, config/arc/arc.c, config/arc/arc.h,
- config/arc/arc.md, config/arc/arc.opt, config/arm/arm_neon_builtins.def,
- config/arm/crypto.def, config/i386/avx512cdintrin.h,
- config/i386/avx512erintrin.h, config/i386/avx512fintrin.h,
- config/i386/avx512pfintrin.h, config/i386/btver2.md,
- config/i386/shaintrin.h, config/i386/slm.md, config/linux-protos.h,
- config/linux.c, config/winnt-c.c, diagnostic-color.c,
- diagnostic-color.h, gimple-ssa-isolate-paths.c, vtable-verify.c,
- vtable-verify.h: Use the standard form for the copyright notice.
+ config/arc/arc.md, config/arc/arc.opt,
+ config/arm/arm_neon_builtins.def, config/arm/crypto.def,
+ config/i386/avx512cdintrin.h, config/i386/avx512erintrin.h,
+ config/i386/avx512fintrin.h, config/i386/avx512pfintrin.h,
+ config/i386/btver2.md, config/i386/shaintrin.h, config/i386/slm.md,
+ config/linux-protos.h, config/linux.c, config/winnt-c.c,
+ diagnostic-color.c, diagnostic-color.h, gimple-ssa-isolate-paths.c,
+ vtable-verify.c, vtable-verify.h: Use the standard form for the
+ copyright notice.
2014-01-02 Tobias Burnus <burnus@net-b.de>
diff --git a/gcc/ChangeLog-2013 b/gcc/ChangeLog-2013
index 2ffd9593b54e..7cf3c9977528 100644
--- a/gcc/ChangeLog-2013
+++ b/gcc/ChangeLog-2013
@@ -62,19 +62,19 @@
(_mm_roundscale_ss): Ditto.
(_mm_roundscale_sd): Ditto.
* config/i386/i386-builtin-types.def: New types to support
- new built-ins: <V2DF, V2DF, V2DF, INT, INT>, <V4SF, V4SF, V4SF, INT, INT>,
- <(V4SF, V4SF, V2DF, INT>, <V2DF, V2DF, V4SF, INT>,
- <V4SF, V4SF, V4SF, V4SF, IN>.
- * config/i386/i386.c (enum ix86_builtins): Add IX86_BUILTIN_ADDSD_ROUND,
- IX86_BUILTIN_ADDSS_ROUND, IX86_BUILTIN_CVTSD2SS_ROUND,
- IX86_BUILTIN_CVTSS2SD_ROUND, IX86_BUILTIN_DIVSD_ROUND,
- IX86_BUILTIN_GETEXPSD128, IX86_BUILTIN_DIVSS_ROUND,
- IX86_BUILTIN_GETEXPSS128, IX86_BUILTIN_GETMANTSD128,
- IX86_BUILTIN_GETMANTSS128, IX86_BUILTIN_MAXSD_ROUND,
- IX86_BUILTIN_MAXSS_ROUND, IX86_BUILTIN_MINSD_ROUND,
- IX86_BUILTIN_MINSS_ROUND, IX86_BUILTIN_MULSD_ROUND,
- IX86_BUILTIN_MULSS_ROUND, IX86_BUILTIN_RCP14SD,
- IX86_BUILTIN_RCP14SS, IX86_BUILTIN_RNDSCALESD,
+ new built-ins: <V2DF, V2DF, V2DF, INT, INT>,
+ <V4SF, V4SF, V4SF, INT, INT>, <(V4SF, V4SF, V2DF, INT>,
+ <V2DF, V2DF, V4SF, INT>, <V4SF, V4SF, V4SF, V4SF, IN>.
+ * config/i386/i386.c (enum ix86_builtins): Add
+ IX86_BUILTIN_ADDSD_ROUND, IX86_BUILTIN_ADDSS_ROUND,
+ IX86_BUILTIN_CVTSD2SS_ROUND, IX86_BUILTIN_CVTSS2SD_ROUND,
+ IX86_BUILTIN_DIVSD_ROUND, IX86_BUILTIN_GETEXPSD128,
+ IX86_BUILTIN_DIVSS_ROUND, IX86_BUILTIN_GETEXPSS128,
+ IX86_BUILTIN_GETMANTSD128, IX86_BUILTIN_GETMANTSS128,
+ IX86_BUILTIN_MAXSD_ROUND, IX86_BUILTIN_MAXSS_ROUND,
+ IX86_BUILTIN_MINSD_ROUND, IX86_BUILTIN_MINSS_ROUND,
+ IX86_BUILTIN_MULSD_ROUND, IX86_BUILTIN_MULSS_ROUND,
+ IX86_BUILTIN_RCP14SD, IX86_BUILTIN_RCP14SS, IX86_BUILTIN_RNDSCALESD,
IX86_BUILTIN_RNDSCALESS, IX86_BUILTIN_RSQRT14SD,
IX86_BUILTIN_RSQRT14SS, IX86_BUILTIN_SCALEFSD,
IX86_BUILTIN_SCALEFSS, IX86_BUILTIN_SQRTSD_ROUND,
@@ -752,7 +752,6 @@
(ix86_expand_int_vcond): Ditto.
(ix86_expand_vec_perm): Ditto.
(ix86_expand_sse_unpack): Ditto.
- (ix86_constant_alignment): Ditto.
(ix86_builtin_vectorized_function): Ditto.
(ix86_vectorize_builtin_gather): Ditto.
(avx_vpermilp_parallel): Ditto.
@@ -773,15 +772,15 @@
(ix86_autovectorize_vector_sizes): Ditto.
(ix86_expand_vec_perm_vpermi2): New.
(ix86_vector_duplicate_value): Ditto.
- (IX86_BUILTIN_SQRTPD512, IX86_BUILTIN_EXP2PS, IX86_BUILTIN_SQRTPS_NR512,
- IX86_BUILTIN_GATHER3ALTDIV16SF, IX86_BUILTIN_GATHER3ALTDIV16SI,
- IX86_BUILTIN_GATHER3ALTSIV8DF, IX86_BUILTIN_GATHER3ALTSIV8DI,
- IX86_BUILTIN_GATHER3DIV16SF, IX86_BUILTIN_GATHER3DIV16SI,
- IX86_BUILTIN_GATHER3DIV8DF, IX86_BUILTIN_GATHER3DIV8DI,
- IX86_BUILTIN_GATHER3SIV16SF, IX86_BUILTIN_GATHER3SIV16SI,
- IX86_BUILTIN_GATHER3SIV8DF, IX86_BUILTIN_CEILPD_VEC_PACK_SFIX512,
- IX86_BUILTIN_CPYSGNPS512, IX86_BUILTIN_CPYSGNPD512,
- IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX512,
+ (IX86_BUILTIN_SQRTPD512, IX86_BUILTIN_EXP2PS,
+ IX86_BUILTIN_SQRTPS_NR512, IX86_BUILTIN_GATHER3ALTDIV16SF,
+ IX86_BUILTIN_GATHER3ALTDIV16SI, IX86_BUILTIN_GATHER3ALTSIV8DF,
+ IX86_BUILTIN_GATHER3ALTSIV8DI, IX86_BUILTIN_GATHER3DIV16SF,
+ IX86_BUILTIN_GATHER3DIV16SI, IX86_BUILTIN_GATHER3DIV8DF,
+ IX86_BUILTIN_GATHER3DIV8DI, IX86_BUILTIN_GATHER3SIV16SF,
+ IX86_BUILTIN_GATHER3SIV16SI, IX86_BUILTIN_GATHER3SIV8DF,
+ IX86_BUILTIN_CEILPD_VEC_PACK_SFIX512, IX86_BUILTIN_CPYSGNPS512,
+ IX86_BUILTIN_CPYSGNPD512, IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX512,
IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX512): Ditto.
* config/i386/sse.md (*mov<mode>_internal): Disable SSE typeless
stores vectors > 128bit (AVX*).
@@ -816,10 +815,8 @@
* config/nios2/constraints.md: New file.
* config/nios2/t-nios2: New file.
* common/config/nios2/nios2-common.c: New file.
- * doc/invoke.texi (Nios II options): Document Nios II specific
- options.
- * doc/md.texi (Nios II family): Document Nios II specific
- constraints.
+ * doc/invoke.texi (Nios II options): Document Nios II specific options.
+ * doc/md.texi (Nios II family): Document Nios II specific constraints.
* doc/extend.texi (Function Specific Option Pragmas): Document
Nios II supported target pragma functionality.
@@ -1076,8 +1073,8 @@
2013-12-26 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
- * config/i386/i386.c (get_builtin_code_for_version): Rename AMD
- CPU names M_AMD_BOBCAT to M_AMD_BTVER1 and M_AMD_JAGUAR
+ * config/i386/i386.c (get_builtin_code_for_version): Rename AMD
+ CPU names M_AMD_BOBCAT to M_AMD_BTVER1 and M_AMD_JAGUAR
to M_AMD_BTVER2.
(processor_model): Likewise.
(arch_names_table): Likewise.
@@ -3857,12 +3854,6 @@
targets like arm-none-eabi.
* expr.c (expand_assignment): Handle normal fields like bit regions.
-2013-12-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
-
- PR target/58115
- * function.c (invoke_set_current_function_hook): Call
- targetm.set_current_function after setting this_fn_optabs.
-
2013-12-02 Richard Biener <rguenther@suse.de>
PR tree-optimization/59139
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index c88e6a62ab2d..ee2701aaa83c 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20140103
+20140113
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index b9d84b24f4ee..7926bd7584f8 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -929,11 +929,10 @@ CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h
CPP_INTERNAL_H = $(srcdir)/../libcpp/internal.h $(CPP_ID_DATA_H)
TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H) $(DUMPFILE_H)
TREE_PASS_H = tree-pass.h $(TIMEVAR_H) $(DUMPFILE_H)
-TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
+TREE_SSA_H = tree-ssa.h tree-ssa-operands.h \
$(BITMAP_H) sbitmap.h $(BASIC_BLOCK_H) $(GIMPLE_H) \
$(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H) \
tree-ssa-alias.h wide-int.h
-TREE_SSA_H = tree-ssa.h $(TREE_FLOW_H)
PRETTY_PRINT_H = pretty-print.h $(INPUT_H) $(OBSTACK_H)
TREE_PRETTY_PRINT_H = tree-pretty-print.h $(PRETTY_PRINT_H)
GIMPLE_PRETTY_PRINT_H = gimple-pretty-print.h $(TREE_PRETTY_PRINT_H)
@@ -3123,7 +3122,9 @@ PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
cppdefault.h flags.h $(MD5_H) params.def params.h prefix.h tree-inline.h \
$(GIMPLE_PRETTY_PRINT_H) realmpfr.h \
$(IPA_PROP_H) $(TARGET_H) $(RTL_H) $(TM_P_H) $(CFGLOOP_H) $(EMIT_RTL_H) \
- version.h stringpool.h
+ version.h stringpool.h gimplify.h gimple-iterator.h gimple-ssa.h \
+ fold-const.h tree-cfg.h tree-into-ssa.h tree-ssanames.h print-tree.h \
+ varasm.h context.h
# generate the 'build fragment' b-header-vars
s-header-vars: Makefile
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 153b42442f24..a0570a59da9d 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,10 @@
+2014-01-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/59772
+ * gcc-interface/cuintp.c (build_cst_from_int): Use 32-bit integer type
+ as intermediate type.
+ (UI_To_gnu): Likewise.
+
2014-01-03 Eric Botcazou <ebotcazou@adacore.com>
* gnatvsn.ads (Current_Year): Bump to 2014.
diff --git a/gcc/ada/gcc-interface/cuintp.c b/gcc/ada/gcc-interface/cuintp.c
index 7ef68b628b3f..e9b30b28aa56 100644
--- a/gcc/ada/gcc-interface/cuintp.c
+++ b/gcc/ada/gcc-interface/cuintp.c
@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
- * Copyright (C) 1992-2013, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2014, Free Software Foundation, Inc. *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
@@ -55,7 +55,7 @@ static tree
build_cst_from_int (tree type, HOST_WIDE_INT low)
{
if (SCALAR_FLOAT_TYPE_P (type))
- return convert (type, build_int_cst (NULL_TREE, low));
+ return convert (type, build_int_cst (gnat_type_for_size (32, 0), low));
else
return build_int_cst_type (type, low);
}
@@ -89,19 +89,12 @@ UI_To_gnu (Uint Input, tree type)
gcc_assert (Length > 0);
/* The computations we perform below always require a type at least as
- large as an integer not to overflow. REAL types are always fine, but
+ large as an integer not to overflow. FP types are always fine, but
INTEGER or ENUMERAL types we are handed may be too short. We use a
base integer type node for the computations in this case and will
- convert the final result back to the incoming type later on.
- The base integer precision must be superior than 16. */
-
- if (TREE_CODE (comp_type) != REAL_TYPE
- && TYPE_PRECISION (comp_type)
- < TYPE_PRECISION (long_integer_type_node))
- {
- comp_type = long_integer_type_node;
- gcc_assert (TYPE_PRECISION (comp_type) > 16);
- }
+ convert the final result back to the incoming type later on. */
+ if (!SCALAR_FLOAT_TYPE_P (comp_type) && TYPE_PRECISION (comp_type) < 32)
+ comp_type = gnat_type_for_size (32, 0);
gnu_base = build_cst_from_int (comp_type, Base);
diff --git a/gcc/asan.c b/gcc/asan.c
index e077153a969d..53992a81b189 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-builder.h"
#include "ubsan.h"
#include "predict.h"
+#include "params.h"
/* AddressSanitizer finds out-of-bounds and use-after-free bugs
with <2x slowdown on average.
@@ -1003,7 +1004,8 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
str_cst = asan_pp_string (&asan_pp);
/* Emit the prologue sequence. */
- if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase)
+ if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase
+ && ASAN_USE_AFTER_RETURN)
{
use_after_return_class = floor_log2 (asan_frame_size - 1) - 5;
/* __asan_stack_malloc_N guarantees alignment
@@ -1239,6 +1241,9 @@ asan_needs_local_alias (tree decl)
bool
asan_protect_global (tree decl)
{
+ if (!ASAN_GLOBALS)
+ return false;
+
rtx rtl, symbol;
if (TREE_CODE (decl) == STRING_CST)
@@ -1568,6 +1573,11 @@ static void
instrument_derefs (gimple_stmt_iterator *iter, tree t,
location_t location, bool is_store)
{
+ if (is_store && !ASAN_INSTRUMENT_WRITES)
+ return;
+ if (!is_store && !ASAN_INSTRUMENT_READS)
+ return;
+
tree type, base;
HOST_WIDE_INT size_in_bytes;
@@ -1897,6 +1907,9 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
static bool
instrument_builtin_call (gimple_stmt_iterator *iter)
{
+ if (!ASAN_MEMINTRIN)
+ return false;
+
bool iter_advanced_p = false;
gimple call = gsi_stmt (*iter);
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 81bb40775987..3f9af38bbaae 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -434,7 +434,7 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
alignment that can prevail. */
if (offset)
{
- int trailing_zeros = tree_ctz (offset);
+ unsigned int trailing_zeros = tree_ctz (offset);
if (trailing_zeros < HOST_BITS_PER_INT)
{
unsigned int inner = (1U << trailing_zeros) * BITS_PER_UNIT;
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index defc0030a640..d9b69b32c419 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2014-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/58115
+ * c-pch.c (c_common_write_pch): Call
+ prepare_target_option_nodes_for_pch.
+
2014-01-02 Richard Sandiford <rdsandiford@googlemail.com>
Update copyright years
diff --git a/gcc/c-family/c-pch.c b/gcc/c-family/c-pch.c
index e51d5b9409e1..93609b610ff1 100644
--- a/gcc/c-family/c-pch.c
+++ b/gcc/c-family/c-pch.c
@@ -180,6 +180,8 @@ c_common_write_pch (void)
(*debug_hooks->handle_pch) (1);
+ prepare_target_option_nodes_for_pch ();
+
cpp_write_pch_deps (parse_in, pch_outfile);
gt_pch_save (pch_outfile);
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 6cb79c0fa6f3..d3b338a5b8ea 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,15 @@
+2014-01-09 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR c++/59631
+ * c-parser.c (c_parser_postfix_expression): Replaced consecutive if
+ statements with if-elseif statements.
+
+2014-01-06 Marek Polacek <polacek@redhat.com>
+
+ PR c/57773
+ * c-decl.c (check_bitfield_type_and_width): Warn for implementation
+ defined bit-field types only in ISO C.
+
2014-01-02 Richard Sandiford <rdsandiford@googlemail.com>
Update copyright years
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 2dee4c248c0a..9c601facad2f 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -4840,7 +4840,8 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
if (!in_system_header_at (input_location)
&& type_mv != integer_type_node
&& type_mv != unsigned_type_node
- && type_mv != boolean_type_node)
+ && type_mv != boolean_type_node
+ && !flag_isoc99)
pedwarn (input_location, OPT_Wpedantic,
"type of bit-field %qs is a GCC extension", name);
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 25fa701ebd95..2590c9be05ee 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -7500,7 +7500,7 @@ c_parser_postfix_expression (c_parser *parser)
expr = c_parser_postfix_expression (parser);
expr.value = error_mark_node;
}
- if (c_parser_peek_token (parser)->keyword == RID_CILK_SPAWN)
+ else if (c_parser_peek_token (parser)->keyword == RID_CILK_SPAWN)
{
error_at (loc, "consecutive %<_Cilk_spawn%> keywords "
"are not permitted");
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index e2e407bd2dea..77196ee6bf71 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -1295,7 +1295,6 @@ flow_find_cross_jump (basic_block bb1, basic_block bb2, rtx *f1, rtx *f2,
{
rtx i1, i2, last1, last2, afterlast1, afterlast2;
int ninsns = 0;
- rtx p1;
enum replace_direction dir, last_dir, afterlast_dir;
bool follow_fallthru, did_fallthru;
@@ -1323,8 +1322,9 @@ flow_find_cross_jump (basic_block bb1, basic_block bb2, rtx *f1, rtx *f2,
|| (returnjump_p (i2) && !side_effects_p (PATTERN (i2))))
{
last2 = i2;
- /* Count everything except for unconditional jump as insn. */
- if (!simplejump_p (i2) && !returnjump_p (i2) && last1)
+ /* Count everything except for unconditional jump as insn.
+ Don't count any jumps if dir_p is NULL. */
+ if (!simplejump_p (i2) && !returnjump_p (i2) && last1 && dir_p)
ninsns++;
i2 = PREV_INSN (i2);
}
@@ -1375,8 +1375,7 @@ flow_find_cross_jump (basic_block bb1, basic_block bb2, rtx *f1, rtx *f2,
last1 = i1, last2 = i2;
afterlast_dir = last_dir;
last_dir = dir;
- p1 = PATTERN (i1);
- if (!(GET_CODE (p1) == USE || GET_CODE (p1) == CLOBBER))
+ if (active_insn_p (i1))
ninsns++;
}
@@ -1422,7 +1421,8 @@ flow_find_cross_jump (basic_block bb1, basic_block bb2, rtx *f1, rtx *f2,
/* Like flow_find_cross_jump, except start looking for a matching sequence from
the head of the two blocks. Do not include jumps at the end.
If STOP_AFTER is nonzero, stop after finding that many matching
- instructions. */
+ instructions. If STOP_AFTER is zero, count all INSN_P insns, if it is
+ non-zero, only count active insns. */
int
flow_find_head_matching_sequence (basic_block bb1, basic_block bb2, rtx *f1,
@@ -1494,7 +1494,8 @@ flow_find_head_matching_sequence (basic_block bb1, basic_block bb2, rtx *f1,
beforelast1 = last1, beforelast2 = last2;
last1 = i1, last2 = i2;
- ninsns++;
+ if (!stop_after || active_insn_p (i1))
+ ninsns++;
}
if (i1 == BB_END (bb1) || i2 == BB_END (bb2)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 2ba1cf4e36e0..c0cbeb3c0220 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -798,7 +798,7 @@ partition_stack_vars (void)
sizes, as the shorter vars wouldn't be adequately protected.
Don't do that for "large" (unsupported) alignment objects,
those aren't protected anyway. */
- if ((flag_sanitize & SANITIZE_ADDRESS) && isize != jsize
+ if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK && isize != jsize
&& ialign * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)
break;
@@ -981,7 +981,7 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data)
if (alignb * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)
{
base = virtual_stack_vars_rtx;
- if ((flag_sanitize & SANITIZE_ADDRESS) && pred)
+ if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK && pred)
{
HOST_WIDE_INT prev_offset = frame_offset;
tree repr_decl = NULL_TREE;
@@ -1160,7 +1160,7 @@ defer_stack_allocation (tree var, bool toplevel)
/* If stack protection is enabled, *all* stack variables must be deferred,
so that we can re-order the strings to the top of the frame.
Similarly for Address Sanitizer. */
- if (flag_stack_protect || (flag_sanitize & SANITIZE_ADDRESS))
+ if (flag_stack_protect || ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK))
return true;
/* We handle "large" alignment via dynamic allocation. We want to handle
@@ -1215,8 +1215,11 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
we conservatively assume it will be on stack even if VAR is
eventually put into register after RA pass. For non-automatic
variables, which won't be on stack, we collect alignment of
- type and ignore user specified alignment. */
- if (TREE_STATIC (var) || DECL_EXTERNAL (var))
+ type and ignore user specified alignment. Similarly for
+ SSA_NAMEs for which use_register_for_decl returns true. */
+ if (TREE_STATIC (var)
+ || DECL_EXTERNAL (var)
+ || (TREE_CODE (origvar) == SSA_NAME && use_register_for_decl (var)))
align = MINIMUM_ALIGNMENT (TREE_TYPE (var),
TYPE_MODE (TREE_TYPE (var)),
TYPE_ALIGN (TREE_TYPE (var)));
@@ -1820,7 +1823,7 @@ expand_used_vars (void)
expand_stack_vars (stack_protect_decl_phase_2, &data);
}
- if (flag_sanitize & SANITIZE_ADDRESS)
+ if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK)
/* Phase 3, any partitions that need asan protection
in addition to phase 1 and 2. */
expand_stack_vars (asan_decl_phase_3, &data);
@@ -2253,7 +2256,7 @@ expand_call_stmt (gimple stmt)
if (lhs)
expand_assignment (lhs, exp, false);
else
- expand_expr_real_1 (exp, const0_rtx, VOIDmode, EXPAND_NORMAL, NULL);
+ expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
mark_transaction_restart_calls (stmt);
}
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 8b25d947511d..7ce54014e1ef 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1426,8 +1426,12 @@ varpool_variable_node (varpool_node *node,
{
varpool_node *n;
- n = dyn_cast <varpool_node> (symtab_alias_ultimate_target (node,
- availability));
+ if (node)
+ n = dyn_cast <varpool_node> (symtab_alias_ultimate_target (node,
+ availability));
+ else
+ n = NULL;
+
if (!n && availability)
*availability = AVAIL_NOT_AVAILABLE;
return n;
diff --git a/gcc/config.gcc b/gcc/config.gcc
index bd0fb6359604..23657a5b0f42 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3476,19 +3476,17 @@ case "${target}" in
fi
done
- case "$with_arch" in
- "" \
- | armv[23456] | armv2a | armv3m | armv4t | armv5t \
- | armv5te | armv6j |armv6k | armv6z | armv6zk | armv6-m \
- | armv7 | armv7-a | armv7-r | armv7-m | armv8-a \
- | iwmmxt | ep9312)
- # OK
- ;;
- *)
- echo "Unknown arch used in --with-arch=$with_arch" 1>&2
- exit 1
- ;;
- esac
+ # See if it matches any of the entries in arm-arches.def
+ if [ x"$with_arch" = x ] \
+ || grep "^ARM_ARCH(\"$with_arch\"," \
+ ${srcdir}/config/arm/arm-arches.def \
+ > /dev/null; then
+ # OK
+ true
+ else
+ echo "Unknown arch used in --with-arch=$with_arch" 1>&2
+ exit 1
+ fi
case "$with_float" in
"" \
diff --git a/gcc/config/aarch64/aarch64-elf.h b/gcc/config/aarch64/aarch64-elf.h
index 7bcdc13d1404..15ab630de884 100644
--- a/gcc/config/aarch64/aarch64-elf.h
+++ b/gcc/config/aarch64/aarch64-elf.h
@@ -144,7 +144,6 @@
#define ASM_SPEC "\
%{mbig-endian:-EB} \
%{mlittle-endian:-EL} \
-%{mcpu=*:-mcpu=%*} \
%{march=*:-march=%*} \
%(asm_cpu_spec)" \
ASM_MABI_SPEC
diff --git a/gcc/config/aarch64/aarch64-modes.def b/gcc/config/aarch64/aarch64-modes.def
index 3a56d622a824..1d2cc7679466 100644
--- a/gcc/config/aarch64/aarch64-modes.def
+++ b/gcc/config/aarch64/aarch64-modes.def
@@ -24,6 +24,7 @@ CC_MODE (CC_SWP);
CC_MODE (CC_ZESWP); /* zero-extend LHS (but swap to make it RHS). */
CC_MODE (CC_SESWP); /* sign-extend LHS (but swap to make it RHS). */
CC_MODE (CC_NZ); /* Only N and Z bits of condition flags are valid. */
+CC_MODE (CC_Z); /* Only Z bit of condition flags is valid. */
/* Vector modes. */
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI. */
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 3fd58b961047..9e507b842579 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3326,17 +3326,24 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
|| GET_CODE (x) == NEG))
return CC_NZmode;
- /* A compare with a shifted or negated operand. Because of canonicalization,
+ /* A compare with a shifted operand. Because of canonicalization,
the comparison will have to be swapped when we emit the assembly
code. */
if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode)
&& (GET_CODE (y) == REG || GET_CODE (y) == SUBREG)
&& (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
|| GET_CODE (x) == LSHIFTRT
- || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND
- || GET_CODE (x) == NEG))
+ || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND))
return CC_SWPmode;
+ /* Similarly for a negated operand, but we can only do this for
+ equalities. */
+ if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode)
+ && (GET_CODE (y) == REG || GET_CODE (y) == SUBREG)
+ && (code == EQ || code == NE)
+ && GET_CODE (x) == NEG)
+ return CC_Zmode;
+
/* A compare of a mode narrower than SI mode against zero can be done
by extending the value in the comparison. */
if ((GET_MODE (x) == QImode || GET_MODE (x) == HImode)
@@ -3427,6 +3434,15 @@ aarch64_get_condition_code (rtx x)
}
break;
+ case CC_Zmode:
+ switch (comp_code)
+ {
+ case NE: return AARCH64_NE;
+ case EQ: return AARCH64_EQ;
+ default: gcc_unreachable ();
+ }
+ break;
+
default:
gcc_unreachable ();
break;
@@ -4643,12 +4659,15 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
extra_cost->mult[GET_MODE (x) == DImode].extend_add;
return true;
}
+
*cost += (rtx_cost (XEXP (op0, 0), MULT, 0, speed)
+ rtx_cost (XEXP (op0, 1), MULT, 1, speed)
+ rtx_cost (op1, PLUS, 1, speed));
if (speed)
*cost += extra_cost->mult[GET_MODE (x) == DImode].add;
+
+ return true;
}
*cost += (rtx_cost (new_op0, PLUS, 0, speed)
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 4e838ee847b8..3b5e92e41629 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1250,8 +1250,8 @@
)
(define_insn "*compare_neg<mode>"
- [(set (reg:CC_SWP CC_REGNUM)
- (compare:CC_SWP
+ [(set (reg:CC_Z CC_REGNUM)
+ (compare:CC_Z
(neg:GPI (match_operand:GPI 0 "register_operand" "r"))
(match_operand:GPI 1 "register_operand" "r")))]
""
diff --git a/gcc/config/arm/arm-cores.def b/gcc/config/arm/arm-cores.def
index d961e250e469..1e97273e51b4 100644
--- a/gcc/config/arm/arm-cores.def
+++ b/gcc/config/arm/arm-cores.def
@@ -152,8 +152,8 @@ ARM_CORE("marvell-pj4", marvell_pj4, marvell_pj4, 7A, FL_LDSCHED, 9e)
ARM_CORE("cortex-a15.cortex-a7", cortexa15cortexa7, cortexa7, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a15)
/* V8 Architecture Processors */
-ARM_CORE("cortex-a53", cortexa53, cortexa53, 8A, FL_LDSCHED, cortex_a53)
-ARM_CORE("cortex-a57", cortexa57, cortexa15, 8A, FL_LDSCHED, cortex_a15)
+ARM_CORE("cortex-a53", cortexa53, cortexa53, 8A, FL_LDSCHED | FL_CRC32, cortex_a53)
+ARM_CORE("cortex-a57", cortexa57, cortexa15, 8A, FL_LDSCHED | FL_CRC32, cortex_a15)
/* V8 big.LITTLE implementations */
-ARM_CORE("cortex-a57.cortex-a53", cortexa57cortexa53, cortexa53, 8A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a15)
+ARM_CORE("cortex-a57.cortex-a53", cortexa57cortexa53, cortexa53, 8A, FL_LDSCHED | FL_CRC32, cortex_a15)
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 42450c71c272..0cb16f94b3f3 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -9092,6 +9092,9 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
{
case SET:
*cost = 0;
+ /* SET RTXs don't have a mode so we get it from the destination. */
+ mode = GET_MODE (SET_DEST (x));
+
if (REG_P (SET_SRC (x))
&& REG_P (SET_DEST (x)))
{
@@ -9106,6 +9109,8 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
in 16 bits in Thumb mode. */
if (!speed_p && TARGET_THUMB && outer_code == COND_EXEC)
*cost >>= 1;
+
+ return true;
}
if (CONST_INT_P (SET_SRC (x)))
@@ -9113,7 +9118,6 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
/* Handle CONST_INT here, since the value doesn't have a mode
and we would otherwise be unable to work out the true cost. */
*cost = rtx_cost (SET_DEST (x), SET, 0, speed_p);
- mode = GET_MODE (SET_DEST (x));
outer_code = SET;
/* Slightly lower the cost of setting a core reg to a constant.
This helps break up chains and allows for better scheduling. */
@@ -20316,8 +20320,10 @@ arm_get_frame_offsets (void)
offsets->saved_args = crtl->args.pretend_args_size;
/* In Thumb mode this is incorrect, but never used. */
- offsets->frame = offsets->saved_args + (frame_pointer_needed ? 4 : 0) +
- arm_compute_static_chain_stack_bytes();
+ offsets->frame
+ = (offsets->saved_args
+ + arm_compute_static_chain_stack_bytes ()
+ + (frame_pointer_needed ? 4 : 0));
if (TARGET_32BIT)
{
@@ -20357,9 +20363,10 @@ arm_get_frame_offsets (void)
}
/* Saved registers include the stack frame. */
- offsets->saved_regs = offsets->saved_args + saved +
- arm_compute_static_chain_stack_bytes();
+ offsets->saved_regs
+ = offsets->saved_args + arm_compute_static_chain_stack_bytes () + saved;
offsets->soft_frame = offsets->saved_regs + CALLER_INTERWORKING_SLOT_SIZE;
+
/* A leaf function does not need any stack alignment if it has nothing
on the stack. */
if (leaf && frame_size == 0
@@ -24241,7 +24248,7 @@ arm_init_iwmmxt_builtins (void)
enum machine_mode mode;
tree type;
- if (d->name == 0)
+ if (d->name == 0 || !(d->mask == FL_IWMMXT || d->mask == FL_IWMMXT2))
continue;
mode = insn_data[d->icode].operand[1].mode;
@@ -24838,7 +24845,11 @@ arm_expand_neon_args (rtx target, int icode, int have_retval,
type_mode);
}
- op[argc] = expand_normal (arg[argc]);
+ /* Use EXPAND_MEMORY for NEON_ARG_MEMORY to ensure a MEM_P
+ be returned. */
+ op[argc] = expand_expr (arg[argc], NULL_RTX, VOIDmode,
+ (thisarg == NEON_ARG_MEMORY
+ ? EXPAND_MEMORY : EXPAND_NORMAL));
switch (thisarg)
{
@@ -24857,6 +24868,9 @@ arm_expand_neon_args (rtx target, int icode, int have_retval,
break;
case NEON_ARG_MEMORY:
+ /* Check if expand failed. */
+ if (op[argc] == const0_rtx)
+ return 0;
gcc_assert (MEM_P (op[argc]));
PUT_MODE (op[argc], mode[argc]);
/* ??? arm_neon.h uses the same built-in functions for signed
@@ -27048,7 +27062,10 @@ arm_expand_epilogue_apcs_frame (bool really_return)
saved_regs_mask = offsets->saved_regs_mask;
/* Find the offset of the floating-point save area in the frame. */
- floats_from_frame = offsets->saved_args - offsets->frame;
+ floats_from_frame
+ = (offsets->saved_args
+ + arm_compute_static_chain_stack_bytes ()
+ - offsets->frame);
/* Compute how many core registers saved and how far away the floats are. */
for (i = 0; i <= LAST_ARM_REGNUM; i++)
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 409589d2dac2..b815488db535 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -189,7 +189,7 @@ extern arm_cc arm_current_cc;
#define ARM_INVERSE_CONDITION_CODE(X) ((arm_cc) (((int)X) ^ 1))
-/* The maximaum number of instructions that is beneficial to
+/* The maximum number of instructions that is beneficial to
conditionally execute. */
#undef MAX_CONDITIONAL_EXECUTE
#define MAX_CONDITIONAL_EXECUTE arm_max_conditional_execute ()
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 95ca5db70027..3c50e24edf26 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -3609,57 +3609,36 @@ darwin_function_section (tree decl, enum node_frequency freq,
if (decl && DECL_SECTION_NAME (decl) != NULL_TREE)
return get_named_section (decl, NULL, 0);
- /* Default when there is no function re-ordering. */
- if (!flag_reorder_functions)
- return (weak)
- ? darwin_sections[text_coal_section]
- : text_section;
-
- /* Startup code should go to startup subsection unless it is
- unlikely executed (this happens especially with function splitting
- where we can split away unnecessary parts of static constructors). */
- if (startup && freq != NODE_FREQUENCY_UNLIKELY_EXECUTED)
- {
- /* If we do have a profile or(and) LTO phase is executed, we do not need
- these ELF section. */
- if (!in_lto_p || !flag_profile_values)
- return (weak)
- ? darwin_sections[text_startup_coal_section]
- : darwin_sections[text_startup_section];
- else
- return text_section;
- }
+ /* We always put unlikely executed stuff in the cold section. */
+ if (freq == NODE_FREQUENCY_UNLIKELY_EXECUTED)
+ return (weak) ? darwin_sections[text_cold_coal_section]
+ : darwin_sections[text_cold_section];
+
+ /* If we have LTO *and* feedback information, then let LTO handle
+ the function ordering, it makes a better job (for normal, hot,
+ startup and exit - hence the bailout for cold above). */
+ if (in_lto_p && flag_profile_values)
+ goto default_function_sections;
+
+ /* Non-cold startup code should go to startup subsection. */
+ if (startup)
+ return (weak) ? darwin_sections[text_startup_coal_section]
+ : darwin_sections[text_startup_section];
/* Similarly for exit. */
- if (exit && freq != NODE_FREQUENCY_UNLIKELY_EXECUTED)
- return (weak)
- ? darwin_sections[text_exit_coal_section]
- : darwin_sections[text_exit_section];
-
- /* Group cold functions together, similarly for hot code. */
- switch (freq)
- {
- case NODE_FREQUENCY_UNLIKELY_EXECUTED:
- return (weak)
- ? darwin_sections[text_cold_coal_section]
- : darwin_sections[text_cold_section];
- break;
- case NODE_FREQUENCY_HOT:
- {
- /* If we do have a profile or(and) LTO phase is executed, we do not need
- these ELF section. */
- if (!in_lto_p || !flag_profile_values)
- return (weak)
- ? darwin_sections[text_hot_coal_section]
- : darwin_sections[text_hot_section];
- break;
- }
- default:
- return (weak)
- ? darwin_sections[text_coal_section]
+ if (exit)
+ return (weak) ? darwin_sections[text_exit_coal_section]
+ : darwin_sections[text_exit_section];
+
+ /* Place hot code. */
+ if (freq == NODE_FREQUENCY_HOT)
+ return (weak) ? darwin_sections[text_hot_coal_section]
+ : darwin_sections[text_hot_section];
+
+ /* Otherwise, default to the 'normal' non-reordered sections. */
+default_function_sections:
+ return (weak) ? darwin_sections[text_coal_section]
: text_section;
- break;
- }
}
/* When a function is partitioned between sections, we need to insert a label
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1d04a3c64ee9..d10fe9529e47 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -81,6 +81,7 @@ along with GCC; see the file COPYING3. If not see
#include "wide-int.h"
#include "context.h"
#include "pass_manager.h"
+#include "target-globals.h"
static rtx legitimize_dllimport_symbol (rtx, bool);
static rtx legitimize_pe_coff_extern_decl (rtx, bool);
@@ -1569,7 +1570,7 @@ struct processor_costs nocona_cost = {
8, /* MMX or SSE register to integer */
8, /* size of l1 cache. */
1024, /* size of l2 cache. */
- 128, /* size of prefetch block */
+ 64, /* size of prefetch block */
8, /* number of parallel prefetches */
1, /* Branch cost */
COSTS_N_INSNS (6), /* cost of FADD and FSUB insns. */
@@ -4869,16 +4870,25 @@ ix86_set_current_function (tree fndecl)
{
cl_target_option_restore (&global_options,
TREE_TARGET_OPTION (new_tree));
- target_reinit ();
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
}
else if (old_tree)
{
- struct cl_target_option *def
- = TREE_TARGET_OPTION (target_option_current_node);
-
- cl_target_option_restore (&global_options, def);
- target_reinit ();
+ new_tree = target_option_current_node;
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
}
}
}
@@ -9282,7 +9292,7 @@ ix86_save_reg (unsigned int regno, bool maybe_eh_return)
if (crtl->drap_reg
&& regno == REGNO (crtl->drap_reg)
- && crtl->stack_realign_needed)
+ && !cfun->machine->no_drap_save_restore)
return true;
return (df_regs_ever_live_p (regno)
@@ -10520,18 +10530,6 @@ ix86_finalize_stack_realign_flags (void)
return;
}
- /* If drap has been set, but it actually isn't live at the start
- of the function and !stack_realign, there is no reason to set it up. */
- if (crtl->drap_reg && !stack_realign)
- {
- basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
- if (! REGNO_REG_SET_P (DF_LR_IN (bb), REGNO (crtl->drap_reg)))
- {
- crtl->drap_reg = NULL_RTX;
- crtl->need_drap = false;
- }
- }
-
/* If the only reason for frame_pointer_needed is that we conservatively
assumed stack realignment might be needed, but in the end nothing that
needed the stack alignment had been spilled, clear frame_pointer_needed
@@ -10585,6 +10583,8 @@ ix86_finalize_stack_realign_flags (void)
crtl->need_drap = false;
}
}
+ else
+ cfun->machine->no_drap_save_restore = true;
frame_pointer_needed = false;
stack_realign = false;
@@ -26466,8 +26466,16 @@ ix86_constant_alignment (tree exp, int align)
int
ix86_data_alignment (tree type, int align, bool opt)
{
- int max_align = optimize_size ? BITS_PER_WORD
- : MIN (512, MAX_OFILE_ALIGNMENT);
+ /* A data structure, equal or greater than the size of a cache line
+ (64 bytes in the Pentium 4 and other recent Intel processors, including
+ processors based on Intel Core microarchitecture) should be aligned
+ so that its base address is a multiple of a cache line size. */
+
+ int max_align
+ = MIN ((unsigned) ix86_tune_cost->prefetch_block * 8, MAX_OFILE_ALIGNMENT);
+
+ if (max_align < BITS_PER_WORD)
+ max_align = BITS_PER_WORD;
if (opt
&& AGGREGATE_TYPE_P (type)
@@ -34407,6 +34415,9 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
case CODE_FOR_sse2_movntidi:
case CODE_FOR_sse_movntq:
case CODE_FOR_sse2_movntisi:
+ case CODE_FOR_avx512f_movntv16sf:
+ case CODE_FOR_avx512f_movntv8df:
+ case CODE_FOR_avx512f_movntv8di:
aligned_mem = true;
break;
default:
@@ -34431,6 +34442,24 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
klass = load;
memory = 0;
break;
+ case VOID_FTYPE_PV8DF_V8DF_QI:
+ case VOID_FTYPE_PV16SF_V16SF_HI:
+ case VOID_FTYPE_PV8DI_V8DI_QI:
+ case VOID_FTYPE_PV16SI_V16SI_HI:
+ switch (icode)
+ {
+ /* These builtins and instructions require the memory
+ to be properly aligned. */
+ case CODE_FOR_avx512f_storev16sf_mask:
+ case CODE_FOR_avx512f_storev16si_mask:
+ case CODE_FOR_avx512f_storev8df_mask:
+ case CODE_FOR_avx512f_storev8di_mask:
+ aligned_mem = true;
+ break;
+ default:
+ break;
+ }
+ /* FALLTHRU */
case VOID_FTYPE_PV8SF_V8SI_V8SF:
case VOID_FTYPE_PV4DF_V4DI_V4DF:
case VOID_FTYPE_PV4SF_V4SI_V4SF:
@@ -34439,10 +34468,6 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
case VOID_FTYPE_PV4DI_V4DI_V4DI:
case VOID_FTYPE_PV4SI_V4SI_V4SI:
case VOID_FTYPE_PV2DI_V2DI_V2DI:
- case VOID_FTYPE_PV8DF_V8DF_QI:
- case VOID_FTYPE_PV16SF_V16SF_HI:
- case VOID_FTYPE_PV8DI_V8DI_QI:
- case VOID_FTYPE_PV16SI_V16SI_HI:
case VOID_FTYPE_PDOUBLE_V2DF_QI:
case VOID_FTYPE_PFLOAT_V4SF_QI:
nargs = 2;
@@ -34459,6 +34484,19 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
nargs = 3;
klass = load;
memory = 0;
+ switch (icode)
+ {
+ /* These builtins and instructions require the memory
+ to be properly aligned. */
+ case CODE_FOR_avx512f_loadv16sf_mask:
+ case CODE_FOR_avx512f_loadv16si_mask:
+ case CODE_FOR_avx512f_loadv8df_mask:
+ case CODE_FOR_avx512f_loadv8di_mask:
+ aligned_mem = true;
+ break;
+ default:
+ break;
+ }
break;
case VOID_FTYPE_UINT_UINT_UINT:
case VOID_FTYPE_UINT64_UINT_UINT:
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index cdaab3684e1c..27151f60ffab 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2419,6 +2419,9 @@ struct GTY(()) machine_function {
stack below the return address. */
BOOL_BITFIELD static_chain_on_stack : 1;
+ /* If true, it is safe to not save/restore DRAP register. */
+ BOOL_BITFIELD no_drap_save_restore : 1;
+
/* During prologue/epilogue generation, the current frame state.
Otherwise, the frame state at the end of the prologue. */
struct machine_frame_state fs;
@@ -2507,6 +2510,9 @@ extern void debug_dispatch_window (int);
#define IX86_HLE_ACQUIRE (1 << 16)
#define IX86_HLE_RELEASE (1 << 17)
+/* For switching between functions with different target attributes. */
+#define SWITCHABLE_TARGET 1
+
/*
Local variables:
version-control: t
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index de0b2dd771b9..954bbed2f195 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -366,7 +366,7 @@
;; Processor type.
(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
- btver1,btver2"
+ btver2"
(const (symbol_ref "ix86_schedule")))
;; A basic instruction type. Refinements due to arguments to be
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 405f9988d9bf..dfc98ba813ad 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -786,8 +786,12 @@
{
case MODE_V8DF:
case MODE_V16SF:
+ if (misaligned_operand (operands[1], <MODE>mode))
+ return "vmovu<ssemodesuffix>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
return "vmova<ssemodesuffix>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
default:
+ if (misaligned_operand (operands[1], <MODE>mode))
+ return "vmovdqu<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
return "vmovdqa<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
}
}
@@ -936,11 +940,14 @@
false, still emit UNSPEC_LOADU insn to honor user's request for
misaligned load. */
if (TARGET_AVX
- && misaligned_operand (operands[1], <MODE>mode)
- /* FIXME: Revisit after AVX512F merge is completed. */
- && !<mask_applied>)
+ && misaligned_operand (operands[1], <MODE>mode))
{
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+ rtx src = operands[1];
+ if (<mask_applied>)
+ src = gen_rtx_VEC_MERGE (<MODE>mode, operands[1],
+ operands[2 * <mask_applied>],
+ operands[3 * <mask_applied>]);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], src));
DONE;
}
})
@@ -1046,11 +1053,14 @@
false, still emit UNSPEC_LOADU insn to honor user's request for
misaligned load. */
if (TARGET_AVX
- && misaligned_operand (operands[1], <MODE>mode)
- /* FIXME: Revisit after AVX512F merge is completed. */
- && !<mask_applied>)
+ && misaligned_operand (operands[1], <MODE>mode))
{
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+ rtx src = operands[1];
+ if (<mask_applied>)
+ src = gen_rtx_VEC_MERGE (<MODE>mode, operands[1],
+ operands[2 * <mask_applied>],
+ operands[3 * <mask_applied>]);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], src));
DONE;
}
})
diff --git a/gcc/config/mips/driver-native.c b/gcc/config/mips/driver-native.c
index 3f1a8d0151d2..4c2a658c77a7 100644
--- a/gcc/config/mips/driver-native.c
+++ b/gcc/config/mips/driver-native.c
@@ -58,11 +58,17 @@ host_detect_local_cpu (int argc, const char **argv)
if (strncmp (buf, "cpu model", sizeof ("cpu model") - 1) == 0)
{
if (strstr (buf, "Godson2 V0.2") != NULL
- || strstr (buf, "Loongson-2 V0.2") != NULL)
+ || strstr (buf, "Loongson-2 V0.2") != NULL
+ || strstr (buf, "Loongson-2E") != NULL)
cpu = "loongson2e";
else if (strstr (buf, "Godson2 V0.3") != NULL
- || strstr (buf, "Loongson-2 V0.3") != NULL)
+ || strstr (buf, "Loongson-2 V0.3") != NULL
+ || strstr (buf, "Loongson-2F") != NULL)
cpu = "loongson2f";
+ else if (strstr (buf, "Godson3 V0.5") != NULL
+ || strstr (buf, "Loongson-3 V0.5") != NULL
+ || strstr (buf, "Loongson-3A") != NULL)
+ cpu = "loongson3a";
else if (strstr (buf, "SiByte SB1") != NULL)
cpu = "sb1";
else if (strstr (buf, "R5000") != NULL)
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index aa1a5ea385ec..617391cdcb11 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -3634,17 +3634,6 @@ mips_set_reg_reg_cost (enum machine_mode mode)
}
}
-/* Return the cost of an operand X that can be trucated for free.
- SPEED says whether we're optimizing for size or speed. */
-
-static int
-mips_truncated_op_cost (rtx x, bool speed)
-{
- if (GET_CODE (x) == TRUNCATE)
- x = XEXP (x, 0);
- return set_src_cost (x, speed);
-}
-
/* Implement TARGET_RTX_COSTS. */
static bool
@@ -4037,13 +4026,12 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
case ZERO_EXTEND:
if (outer_code == SET
&& ISA_HAS_BADDU
+ && (GET_CODE (XEXP (x, 0)) == TRUNCATE
+ || GET_CODE (XEXP (x, 0)) == SUBREG)
&& GET_MODE (XEXP (x, 0)) == QImode
- && GET_CODE (XEXP (x, 0)) == PLUS)
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS)
{
- rtx plus = XEXP (x, 0);
- *total = (COSTS_N_INSNS (1)
- + mips_truncated_op_cost (XEXP (plus, 0), speed)
- + mips_truncated_op_cost (XEXP (plus, 1), speed));
+ *total = set_src_cost (XEXP (XEXP (x, 0), 0), speed);
return true;
}
*total = mips_zero_extend_cost (mode, XEXP (x, 0));
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index acbf6a31d7fc..bc9d301291c6 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2529,7 +2529,9 @@ typedef struct mips_args {
: TARGET_MICROMIPS && !TARGET_INTERLINK_COMPRESSED \
? "%*" INSN "r%!\t%" #TARGET_OPNO "%/" \
: "%*" INSN "r\t%" #TARGET_OPNO "%/") \
- : MIPS_ABSOLUTE_JUMP ("%*" INSN "\t%" #TARGET_OPNO "%/"))
+ : TARGET_MICROMIPS && !TARGET_INTERLINK_COMPRESSED \
+ ? MIPS_ABSOLUTE_JUMP ("%*" INSN "%!\t%" #TARGET_OPNO "%/") \
+ : MIPS_ABSOLUTE_JUMP ("%*" INSN "\t%" #TARGET_OPNO "%/")) \
/* Similar to MIPS_CALL, but this is for MICROMIPS "j" to generate
"jrc" when nop is in the delay slot of "jr". */
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 4b0e3b6925e0..fb47a890c4c4 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -1312,20 +1312,32 @@
;; Combiner patterns for unsigned byte-add.
-(define_insn "*baddu_si"
+(define_insn "*baddu_si_eb"
[(set (match_operand:SI 0 "register_operand" "=d")
(zero_extend:SI
- (plus:QI (match_operand:QI 1 "register_operand" "d")
- (match_operand:QI 2 "register_operand" "d"))))]
- "ISA_HAS_BADDU"
+ (subreg:QI
+ (plus:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "register_operand" "d")) 3)))]
+ "ISA_HAS_BADDU && BYTES_BIG_ENDIAN"
+ "baddu\\t%0,%1,%2"
+ [(set_attr "alu_type" "add")])
+
+(define_insn "*baddu_si_el"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (zero_extend:SI
+ (subreg:QI
+ (plus:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "register_operand" "d")) 0)))]
+ "ISA_HAS_BADDU && !BYTES_BIG_ENDIAN"
"baddu\\t%0,%1,%2"
[(set_attr "alu_type" "add")])
(define_insn "*baddu_di<mode>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(zero_extend:GPR
- (plus:QI (truncate:QI (match_operand:DI 1 "register_operand" "d"))
- (truncate:QI (match_operand:DI 2 "register_operand" "d")))))]
+ (truncate:QI
+ (plus:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:DI 2 "register_operand" "d")))))]
"ISA_HAS_BADDU && TARGET_64BIT"
"baddu\\t%0,%1,%2"
[(set_attr "alu_type" "add")])
@@ -6149,7 +6161,12 @@
(define_insn "*<optab>"
[(any_return)]
""
- "%*j\t$31%/"
+ {
+ if (TARGET_MICROMIPS)
+ return "%*jr%:\t$31";
+ else
+ return "%*j\t$31%/";
+ }
[(set_attr "type" "jump")
(set_attr "mode" "none")])
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 2c4f6bfcaceb..c3755bfa9122 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -10424,13 +10424,13 @@ pa_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
/* When INT14_OK_STRICT is false, a secondary reload is needed
to adjust the displacement of SImode and DImode floating point
- instructions. So, we return false when STRICT is true. We
+ instructions but this may fail when the register also needs
+ reloading. So, we return false when STRICT is true. We
also reject long displacements for float mode addresses since
the majority of accesses will use floating point instructions
that don't support 14-bit offsets. */
if (!INT14_OK_STRICT
- && reload_in_progress
- && strict
+ && (strict || !(reload_in_progress || reload_completed))
&& mode != QImode
&& mode != HImode)
return false;
@@ -10490,8 +10490,7 @@ pa_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
return true;
if (!INT14_OK_STRICT
- && reload_in_progress
- && strict
+ && (strict || !(reload_in_progress || reload_completed))
&& mode != QImode
&& mode != HImode)
return false;
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 4bbccbd7d820..b7b67fae1c8f 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -1318,7 +1318,7 @@ BU_P8V_AV_2 (VMRGOW, "vmrgow", CONST, p8_vmrgow)
BU_P8V_AV_2 (VPKUDUM, "vpkudum", CONST, altivec_vpkudum)
BU_P8V_AV_2 (VPKSDSS, "vpksdss", CONST, altivec_vpksdss)
BU_P8V_AV_2 (VPKUDUS, "vpkudus", CONST, altivec_vpkudus)
-BU_P8V_AV_2 (VPKSDUS, "vpksdus", CONST, altivec_vpkswus)
+BU_P8V_AV_2 (VPKSDUS, "vpksdus", CONST, altivec_vpksdus)
BU_P8V_AV_2 (VRLD, "vrld", CONST, vrotlv2di3)
BU_P8V_AV_2 (VSLD, "vsld", CONST, vashlv2di3)
BU_P8V_AV_2 (VSRD, "vsrd", CONST, vlshrv2di3)
@@ -1752,6 +1752,14 @@ BU_SPECIAL_X (RS6000_BUILTIN_GET_TB, "__builtin_ppc_get_timebase",
BU_SPECIAL_X (RS6000_BUILTIN_MFTB, "__builtin_ppc_mftb",
RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
+BU_SPECIAL_X (RS6000_BUILTIN_MFFS, "__builtin_mffs",
+ RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
+
+RS6000_BUILTIN_X (RS6000_BUILTIN_MTFSF, "__builtin_mtfsf",
+ RS6000_BTM_ALWAYS,
+ RS6000_BTC_MISC | RS6000_BTC_UNARY | RS6000_BTC_VOID,
+ CODE_FOR_rs6000_mtfsf)
+
/* Darwin CfString builtin. */
BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS,
RS6000_BTC_MISC)
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 3f53d44c0877..51968f8b7fda 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -611,10 +611,6 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_VUPKHSH, ALTIVEC_BUILTIN_VUPKHSH,
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 },
- { ALTIVEC_BUILTIN_VEC_UNPACKH, P8V_BUILTIN_VUPKHSW,
- RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 },
- { ALTIVEC_BUILTIN_VEC_UNPACKH, P8V_BUILTIN_VUPKHSW,
- RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V4SI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_VUPKHSH, P8V_BUILTIN_VUPKHSW,
RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_VUPKHSH, P8V_BUILTIN_VUPKHSW,
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 687f2f20795f..8eeb2d6de95d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -78,6 +78,7 @@
#include "tree-vectorizer.h"
#include "dumpfile.h"
#include "cgraph.h"
+#include "target-globals.h"
#if TARGET_XCOFF
#include "xcoffout.h" /* get declarations of xcoff_*_section_name */
#endif
@@ -3238,6 +3239,18 @@ rs6000_option_override_internal (bool global_init_p)
&& !(processor_target_table[tune_index].target_enable & OPTION_MASK_HTM))
rs6000_isa_flags |= ~rs6000_isa_flags_explicit & OPTION_MASK_STRICT_ALIGN;
+ /* -maltivec={le,be} implies -maltivec. */
+ if (rs6000_altivec_element_order != 0)
+ rs6000_isa_flags |= OPTION_MASK_ALTIVEC;
+
+ /* Disallow -maltivec=le in big endian mode for now. This is not
+ known to be useful for anyone. */
+ if (BYTES_BIG_ENDIAN && rs6000_altivec_element_order == 1)
+ {
+ warning (0, N_("-maltivec=le not allowed for big-endian targets"));
+ rs6000_altivec_element_order = 0;
+ }
+
/* Add some warnings for VSX. */
if (TARGET_VSX)
{
@@ -6324,13 +6337,14 @@ rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x,
break;
case TFmode:
- case TDmode:
- case TImode:
- case PTImode:
if (TARGET_E500_DOUBLE)
return (SPE_CONST_OFFSET_OK (offset)
&& SPE_CONST_OFFSET_OK (offset + 8));
+ /* fall through */
+ case TDmode:
+ case TImode:
+ case PTImode:
extra = 8;
if (!worst_case)
break;
@@ -11450,6 +11464,48 @@ rs6000_expand_zeroop_builtin (enum insn_code icode, rtx target)
static rtx
+rs6000_expand_mtfsf_builtin (enum insn_code icode, tree exp)
+{
+ rtx pat;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ tree arg1 = CALL_EXPR_ARG (exp, 1);
+ rtx op0 = expand_normal (arg0);
+ rtx op1 = expand_normal (arg1);
+ enum machine_mode mode0 = insn_data[icode].operand[0].mode;
+ enum machine_mode mode1 = insn_data[icode].operand[1].mode;
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node || arg1 == error_mark_node)
+ return const0_rtx;
+
+ if (GET_CODE (op0) != CONST_INT
+ || INTVAL (op0) > 255
+ || INTVAL (op0) < 0)
+ {
+ error ("argument 1 must be an 8-bit field value");
+ return const0_rtx;
+ }
+
+ if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+
+ if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+
+ pat = GEN_FCN (icode) (op0, op1);
+ if (! pat)
+ return const0_rtx;
+ emit_insn (pat);
+
+ return NULL_RTX;
+}
+
+
+static rtx
rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
{
rtx pat;
@@ -13256,6 +13312,12 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
: CODE_FOR_rs6000_mftb_si),
target);
+ case RS6000_BUILTIN_MFFS:
+ return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_mffs, target);
+
+ case RS6000_BUILTIN_MTFSF:
+ return rs6000_expand_mtfsf_builtin (CODE_FOR_rs6000_mtfsf, exp);
+
case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
case ALTIVEC_BUILTIN_MASK_FOR_STORE:
{
@@ -13563,6 +13625,14 @@ rs6000_init_builtins (void)
NULL_TREE);
def_builtin ("__builtin_ppc_mftb", ftype, RS6000_BUILTIN_MFTB);
+ ftype = build_function_type_list (double_type_node, NULL_TREE);
+ def_builtin ("__builtin_mffs", ftype, RS6000_BUILTIN_MFFS);
+
+ ftype = build_function_type_list (void_type_node,
+ intSI_type_node, double_type_node,
+ NULL_TREE);
+ def_builtin ("__builtin_mtfsf", ftype, RS6000_BUILTIN_MTFSF);
+
#if TARGET_XCOFF
/* AIX libm provides clog as __clog. */
if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
@@ -31188,16 +31258,25 @@ rs6000_set_current_function (tree fndecl)
{
cl_target_option_restore (&global_options,
TREE_TARGET_OPTION (new_tree));
- target_reinit ();
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
}
else if (old_tree)
{
- struct cl_target_option *def
- = TREE_TARGET_OPTION (target_option_current_node);
-
- cl_target_option_restore (&global_options, def);
- target_reinit ();
+ new_tree = target_option_current_node;
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
}
}
}
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 9ebe9abd3ad6..fdfe1c911b57 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -468,6 +468,15 @@ extern int rs6000_vector_align[];
? rs6000_vector_align[(MODE)] \
: (int)GET_MODE_BITSIZE ((MODE)))
+/* Determine the element order to use for vector instructions. By
+ default we use big-endian element order when targeting big-endian,
+ and little-endian element order when targeting little-endian. For
+ programs being ported from BE Power to LE Power, it can sometimes
+ be useful to use big-endian element order when targeting little-endian.
+ This is set via -maltivec=be, for example. */
+#define VECTOR_ELT_ORDER_BIG \
+ (BYTES_BIG_ENDIAN || (rs6000_altivec_element_order == 2))
+
/* Alignment options for fields in structures for sub-targets following
AIX-like ABI.
ALIGN_POWER word-aligns FP doubles (default AIX ABI).
@@ -2437,6 +2446,9 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
+/* For switching between functions with different target attributes. */
+#define SWITCHABLE_TARGET 1
+
/* uncomment for disabling the corresponding default options */
/* #define MACHINE_no_sched_interblock */
/* #define MACHINE_no_sched_speculative */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 5605dddafdbb..53c34ad09cc6 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -140,6 +140,8 @@
UNSPECV_ISYNC ; isync instruction
UNSPECV_MFTB ; move from time base
UNSPECV_NLGR ; non-local goto receiver
+ UNSPECV_MFFS ; Move from FPSCR
+ UNSPECV_MTFSF ; Move to FPSCR Fields
])
@@ -15587,6 +15589,20 @@
})
+(define_insn "rs6000_mffs"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+ (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS"
+ "mffs %0")
+
+(define_insn "rs6000_mtfsf"
+ [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
+ (match_operand:DF 1 "gpc_reg_operand" "d")]
+ UNSPECV_MTFSF)]
+ "TARGET_HARD_FLOAT && TARGET_FPRS"
+ "mtfsf %0,%1")
+
+
;; Power8 fusion support for fusing an addis instruction with a D-form load of
;; a GPR. The addis instruction must be adjacent to the load, and use the same
;; register that is being loaded. The fused ops must be physically adjacent.
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index fdbc70f9cc63..3240a7516bb9 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -140,6 +140,14 @@ maltivec
Target Report Mask(ALTIVEC) Var(rs6000_isa_flags)
Use AltiVec instructions
+maltivec=le
+Target Report RejectNegative Var(rs6000_altivec_element_order, 1) Save
+Generate Altivec instructions using little-endian element order
+
+maltivec=be
+Target Report RejectNegative Var(rs6000_altivec_element_order, 2)
+Generate Altivec instructions using big-endian element order
+
mhard-dfp
Target Report Mask(DFP) Var(rs6000_isa_flags)
Use decimal floating point instructions
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 3d480fd631b2..eeccaedfb08c 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -10005,16 +10005,9 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
void
s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
{
- const int CC0 = 1 << 3;
- const int CC1 = 1 << 2;
- const int CC3 = 1 << 0;
- rtx abort_label = gen_label_rtx ();
- rtx leave_label = gen_label_rtx ();
rtx retry_plus_two = gen_reg_rtx (SImode);
rtx retry_reg = gen_reg_rtx (SImode);
rtx retry_label = NULL_RTX;
- rtx jump;
- int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
if (retry != NULL_RTX)
{
@@ -10031,38 +10024,25 @@ s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
emit_insn (gen_tbegin_nofloat_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
tdb));
- jump = s390_emit_jump (abort_label,
- gen_rtx_NE (VOIDmode,
- gen_rtx_REG (CCRAWmode, CC_REGNUM),
- gen_rtx_CONST_INT (VOIDmode, CC0)));
-
- JUMP_LABEL (jump) = abort_label;
- LABEL_NUSES (abort_label) = 1;
- add_int_reg_note (jump, REG_BR_PROB, very_unlikely);
-
- /* Initialize CC return value. */
- emit_move_insn (dest, const0_rtx);
-
- s390_emit_jump (leave_label, NULL_RTX);
- LABEL_NUSES (leave_label) = 1;
- emit_barrier ();
-
- /* Abort handler code. */
-
- emit_label (abort_label);
emit_move_insn (dest, gen_rtx_UNSPEC (SImode,
gen_rtvec (1, gen_rtx_REG (CCRAWmode,
CC_REGNUM)),
UNSPEC_CC_TO_INT));
if (retry != NULL_RTX)
{
+ const int CC0 = 1 << 3;
+ const int CC1 = 1 << 2;
+ const int CC3 = 1 << 0;
+ rtx jump;
rtx count = gen_reg_rtx (SImode);
+ rtx leave_label = gen_label_rtx ();
+
+ /* Exit for success and permanent failures. */
jump = s390_emit_jump (leave_label,
gen_rtx_EQ (VOIDmode,
gen_rtx_REG (CCRAWmode, CC_REGNUM),
- gen_rtx_CONST_INT (VOIDmode, CC1 | CC3)));
- LABEL_NUSES (leave_label) = 2;
- add_int_reg_note (jump, REG_BR_PROB, very_unlikely);
+ gen_rtx_CONST_INT (VOIDmode, CC0 | CC1 | CC3)));
+ LABEL_NUSES (leave_label) = 1;
/* CC2 - transient failure. Perform retry with ppa. */
emit_move_insn (count, retry_plus_two);
@@ -10073,9 +10053,8 @@ s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
retry_reg));
JUMP_LABEL (jump) = retry_label;
LABEL_NUSES (retry_label) = 1;
+ emit_label (leave_label);
}
-
- emit_label (leave_label);
}
/* Builtins. */
diff --git a/gcc/config/sh/sh-mem.cc b/gcc/config/sh/sh-mem.cc
index 3dca5f084868..e29ff775449b 100644
--- a/gcc/config/sh/sh-mem.cc
+++ b/gcc/config/sh/sh-mem.cc
@@ -324,7 +324,6 @@ sh_expand_cmpnstr (rtx *operands)
rtx addr2 = operands[2];
rtx s1_addr = copy_addr_to_reg (XEXP (addr1, 0));
rtx s2_addr = copy_addr_to_reg (XEXP (addr2, 0));
- rtx tmp0 = gen_reg_rtx (SImode);
rtx tmp1 = gen_reg_rtx (SImode);
rtx tmp2 = gen_reg_rtx (SImode);
@@ -334,98 +333,132 @@ sh_expand_cmpnstr (rtx *operands)
rtx L_end_loop_byte = gen_label_rtx ();
rtx len = force_reg (SImode, operands[3]);
- int constp = (CONST_INT_P (operands[3]));
- int bytes = (constp ? INTVAL (operands[3]) : 0);
- int witers = bytes / 4;
+ int constp = CONST_INT_P (operands[3]);
- /* We could still loop on a register count. Not found very
- convincing to optimize yet. */
- if (! constp)
- return false;
-
- if (witers > 1)
+ /* Loop on a register count. */
+ if (constp)
{
- rtx L_loop_long = gen_label_rtx ();
- rtx L_end_loop_long = gen_label_rtx ();
+ rtx tmp0 = gen_reg_rtx (SImode);
rtx tmp3 = gen_reg_rtx (SImode);
rtx lenw = gen_reg_rtx (SImode);
- int align = INTVAL (operands[4]);
-
- emit_move_insn (tmp0, const0_rtx);
-
- if (align < 4)
- {
- emit_insn (gen_iorsi3 (tmp1, s1_addr, s2_addr));
- emit_insn (gen_tstsi_t (GEN_INT (3), tmp1));
- jump = emit_jump_insn (gen_branch_false (L_loop_byte));
- add_int_reg_note (jump, REG_BR_PROB, prob_likely);
- }
-
- addr1 = adjust_automodify_address (addr1, SImode, s1_addr, 0);
- addr2 = adjust_automodify_address (addr2, SImode, s2_addr, 0);
-
- /* word count. Do we have iterations ? */
- emit_insn (gen_lshrsi3 (lenw, len, GEN_INT (2)));
-
- /*start long loop. */
- emit_label (L_loop_long);
-
- /* tmp2 is aligned, OK to load. */
- emit_move_insn (tmp2, addr2);
- emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, 4));
-
- /* tmp1 is aligned, OK to load. */
- emit_move_insn (tmp1, addr1);
- emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr, 4));
-
- /* Is there a 0 byte ? */
- emit_insn (gen_andsi3 (tmp3, tmp2, tmp1));
-
- emit_insn (gen_cmpstr_t (tmp0, tmp3));
- jump = emit_jump_insn (gen_branch_true (L_end_loop_long));
- add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
- emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
- jump = emit_jump_insn (gen_branch_false (L_end_loop_long));
- add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
-
- if (TARGET_SH2)
- emit_insn (gen_dect (lenw, lenw));
- else
- {
- emit_insn (gen_addsi3 (lenw, lenw, GEN_INT (-1)));
- emit_insn (gen_tstsi_t (lenw, lenw));
- }
- jump = emit_jump_insn (gen_branch_false (L_loop_long));
- add_int_reg_note (jump, REG_BR_PROB, prob_likely);
-
- /* end loop. Reached max iterations. */
- if (bytes % 4 == 0)
- {
- /* Done. */
- jump = emit_jump_insn (gen_jump_compact (L_return));
- emit_barrier_after (jump);
- }
- else
- {
- /* Remaining bytes to read. */
- emit_move_insn (len, GEN_INT (bytes % 4));
- jump = emit_jump_insn (gen_jump_compact (L_loop_byte));
- emit_barrier_after (jump);
- }
-
- emit_label (L_end_loop_long);
-
- /* Remaining bytes to read. */
- emit_move_insn (len, GEN_INT (4));
+ rtx L_loop_long = gen_label_rtx ();
+ rtx L_end_loop_long = gen_label_rtx ();
+ rtx L_small = gen_label_rtx ();
- /* Found last word. Restart it byte per byte. */
- emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr, -4));
- emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, -4));
+ int align = INTVAL (operands[4]);
+ int bytes = INTVAL (operands[3]);
+ int witers = bytes / 4;
+
+ if (witers > 1)
+ {
+ addr1 = adjust_automodify_address (addr1, SImode, s1_addr, 0);
+ addr2 = adjust_automodify_address (addr2, SImode, s2_addr, 0);
+
+ emit_move_insn (tmp0, const0_rtx);
+
+ if (align < 4)
+ {
+ emit_insn (gen_iorsi3 (tmp1, s1_addr, s2_addr));
+ emit_insn (gen_tstsi_t (GEN_INT (3), tmp1));
+ jump = emit_jump_insn (gen_branch_false (L_loop_byte));
+ add_int_reg_note (jump, REG_BR_PROB, prob_likely);
+ }
+
+ /* word count. Do we have iterations ? */
+ emit_insn (gen_lshrsi3 (lenw, len, GEN_INT (2)));
+
+ /*start long loop. */
+ emit_label (L_loop_long);
+
+ /* tmp2 is aligned, OK to load. */
+ emit_move_insn (tmp2, addr2);
+ emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr,
+ GET_MODE_SIZE (SImode)));
+
+ /* tmp1 is aligned, OK to load. */
+ emit_move_insn (tmp1, addr1);
+ emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr,
+ GET_MODE_SIZE (SImode)));
+
+ /* Is there a 0 byte ? */
+ emit_insn (gen_andsi3 (tmp3, tmp2, tmp1));
+
+ emit_insn (gen_cmpstr_t (tmp0, tmp3));
+ jump = emit_jump_insn (gen_branch_true (L_end_loop_long));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+
+ emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
+ jump = emit_jump_insn (gen_branch_false (L_end_loop_long));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+
+ if (TARGET_SH2)
+ emit_insn (gen_dect (lenw, lenw));
+ else
+ {
+ emit_insn (gen_addsi3 (lenw, lenw, GEN_INT (-1)));
+ emit_insn (gen_tstsi_t (lenw, lenw));
+ }
+
+ jump = emit_jump_insn (gen_branch_false (L_loop_long));
+ add_int_reg_note (jump, REG_BR_PROB, prob_likely);
+
+ /* end loop. Reached max iterations. */
+ if (bytes % 4 == 0)
+ {
+ /* Done. */
+ jump = emit_jump_insn (gen_jump_compact (L_return));
+ emit_barrier_after (jump);
+ }
+ else
+ {
+ /* Remaining bytes to read. */
+ jump = emit_jump_insn (gen_jump_compact (L_small));
+ emit_barrier_after (jump);
+ }
+
+ emit_label (L_end_loop_long);
+
+ /* Found last word. Restart it byte per byte. */
+ bytes = 4;
+ emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr,
+ -GET_MODE_SIZE (SImode)));
+ emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr,
+ -GET_MODE_SIZE (SImode)));
+ }
+
+ emit_label (L_small);
+
+ gcc_assert (bytes <= 7);
+
+ addr1 = adjust_automodify_address (addr1, QImode, s1_addr, 0);
+ addr2 = adjust_automodify_address (addr2, QImode, s2_addr, 0);
+
+ while (bytes--)
+ {
+ emit_insn (gen_extendqisi2 (tmp1, addr1));
+ emit_insn (gen_extendqisi2 (tmp2, addr2));
+
+ emit_insn (gen_cmpeqsi_t (tmp2, const0_rtx));
+ jump = emit_jump_insn (gen_branch_true (L_end_loop_byte));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+
+ emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
+ if (flag_delayed_branch)
+ emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2)));
+ jump = emit_jump_insn (gen_branch_false (L_end_loop_byte));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+
+ addr1 = adjust_address (addr1, QImode, GET_MODE_SIZE (QImode));
+ addr2 = adjust_address (addr2, QImode, GET_MODE_SIZE (QImode));
+ }
+
+ jump = emit_jump_insn (gen_jump_compact( L_end_loop_byte));
+ emit_barrier_after (jump);
}
- addr1 = adjust_address (addr1, QImode, 0);
- addr2 = adjust_address (addr2, QImode, 0);
+ addr1 = adjust_automodify_address (addr1, QImode, s1_addr, 0);
+ addr2 = adjust_automodify_address (addr2, QImode, s2_addr, 0);
emit_label (L_loop_byte);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 70211081dbf1..9213de72d1b4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,61 @@
+2014-01-09 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR c++/59631
+ * parser.c (cp_parser_postfix_expression): Added a new if-statement
+ and replaced an existing if-statement with else-if statement.
+ Changed an existing error message wording to match the one from the C
+ parser.
+
+2014-01-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/59614
+ * class.c (abi_tag_data): Add tags field.
+ (check_abi_tags): Initialize it.
+ (find_abi_tags_r): Support collecting missing tags.
+ (mark_type_abi_tags): Don't look at template args.
+ (inherit_targ_abi_tags): New.
+ (check_bases_and_members): Use it.
+ * cp-tree.h (ABI_TAG_IMPLICIT): New.
+ * mangle.c (write_abi_tags): Check it.
+
+2014-01-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/58856
+ * pt.c (num_innermost_template_parms): New.
+ (get_underlying_template): Use it.
+
+ PR c++/58965
+ * mangle.c (write_guarded_var_name): Handle null DECL_NAME.
+
+2014-01-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * semantics.c (trait_expr_value, [CPTK_IS_BASE_OF]): Implement
+ the letter of 20.11.6 about Base and Derived naming the same
+ class type modulo cv-qualifiers.
+
+2014-01-06 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/59635
+ * lambda.c (maybe_add_lambda_conv_op): Handle marking conversion
+ function as unimplemented for generic lambdas with varargs.
+
+ PR c++/59636
+ * parser.c (cp_parser_template_parameter): Early out with
+ error_mark_node if parameter declaration was not parsed.
+
+ PR c++/59629
+ * parser.c (cp_parser_lambda_expression): Save/reset/restore
+ auto_is_implicit_function_template_parm_p around lambda body.
+
+ PR c++/59638
+ * parser.c (cp_parser_init_declarator): Undo fully implicit
+ template parameter list when declarator is not a function.
+
+2014-01-03 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/58950
+ * cvt.c (convert_to_void): Handle VEC_PERM_EXPR and VEC_COND_EXPR.
+
2014-01-03 Tobias Burnus <burnus@net-b.de>
PR c++/58567
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 1f07b97a6158..4dbe3a67b8ca 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1341,14 +1341,20 @@ struct abi_tag_data
{
tree t;
tree subob;
+ // error_mark_node to get diagnostics; otherwise collect missing tags here
+ tree tags;
};
static tree
-find_abi_tags_r (tree *tp, int */*walk_subtrees*/, void *data)
+find_abi_tags_r (tree *tp, int *walk_subtrees, void *data)
{
if (!OVERLOAD_TYPE_P (*tp))
return NULL_TREE;
+ /* walk_tree shouldn't be walking into any subtrees of a RECORD_TYPE
+ anyway, but let's make sure of it. */
+ *walk_subtrees = false;
+
if (tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (*tp)))
{
struct abi_tag_data *p = static_cast<struct abi_tag_data*>(data);
@@ -1359,7 +1365,20 @@ find_abi_tags_r (tree *tp, int */*walk_subtrees*/, void *data)
tree id = get_identifier (TREE_STRING_POINTER (tag));
if (!IDENTIFIER_MARKED (id))
{
- if (TYPE_P (p->subob))
+ if (p->tags != error_mark_node)
+ {
+ /* We're collecting tags from template arguments. */
+ tree str = build_string (IDENTIFIER_LENGTH (id),
+ IDENTIFIER_POINTER (id));
+ p->tags = tree_cons (NULL_TREE, str, p->tags);
+ ABI_TAG_IMPLICIT (p->tags) = true;
+
+ /* Don't inherit this tag multiple times. */
+ IDENTIFIER_MARKED (id) = true;
+ }
+
+ /* Otherwise we're diagnosing missing tags. */
+ else if (TYPE_P (p->subob))
{
warning (OPT_Wabi_tag, "%qT does not have the %E abi tag "
"that base %qT has", p->t, tag, p->subob);
@@ -1398,22 +1417,6 @@ mark_type_abi_tags (tree t, bool val)
IDENTIFIER_MARKED (id) = val;
}
}
-
- /* Also mark ABI tags from template arguments. */
- if (CLASSTYPE_TEMPLATE_INFO (t))
- {
- tree args = CLASSTYPE_TI_ARGS (t);
- for (int i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
- {
- tree level = TMPL_ARGS_LEVEL (args, i+1);
- for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
- {
- tree arg = TREE_VEC_ELT (level, j);
- if (CLASS_TYPE_P (arg))
- mark_type_abi_tags (arg, val);
- }
- }
- }
}
/* Check that class T has all the abi tags that subobject SUBOB has, or
@@ -1425,13 +1428,50 @@ check_abi_tags (tree t, tree subob)
mark_type_abi_tags (t, true);
tree subtype = TYPE_P (subob) ? subob : TREE_TYPE (subob);
- struct abi_tag_data data = { t, subob };
+ struct abi_tag_data data = { t, subob, error_mark_node };
cp_walk_tree_without_duplicates (&subtype, find_abi_tags_r, &data);
mark_type_abi_tags (t, false);
}
+void
+inherit_targ_abi_tags (tree t)
+{
+ if (CLASSTYPE_TEMPLATE_INFO (t) == NULL_TREE)
+ return;
+
+ mark_type_abi_tags (t, true);
+
+ tree args = CLASSTYPE_TI_ARGS (t);
+ struct abi_tag_data data = { t, NULL_TREE, NULL_TREE };
+ for (int i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
+ {
+ tree level = TMPL_ARGS_LEVEL (args, i+1);
+ for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
+ {
+ tree arg = TREE_VEC_ELT (level, j);
+ data.subob = arg;
+ cp_walk_tree_without_duplicates (&arg, find_abi_tags_r, &data);
+ }
+ }
+
+ // If we found some tags on our template arguments, add them to our
+ // abi_tag attribute.
+ if (data.tags)
+ {
+ tree attr = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
+ if (attr)
+ TREE_VALUE (attr) = chainon (data.tags, TREE_VALUE (attr));
+ else
+ TYPE_ATTRIBUTES (t)
+ = tree_cons (get_identifier ("abi_tag"), data.tags,
+ TYPE_ATTRIBUTES (t));
+ }
+
+ mark_type_abi_tags (t, false);
+}
+
/* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P,
and NO_CONST_ASN_REF_P. Also set flag bits in T based on
properties of the bases. */
@@ -5432,6 +5472,9 @@ check_bases_and_members (tree t)
bool saved_nontrivial_dtor;
tree fn;
+ /* Pick up any abi_tags from our template arguments before checking. */
+ inherit_targ_abi_tags (t);
+
/* By default, we use const reference arguments and generate default
constructors. */
cant_have_const_ctor = 0;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index bdae500d374a..96af562f245e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -65,6 +65,7 @@ c-common.h, not after.
TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR)
TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX)
ATTR_IS_DEPENDENT (in the TREE_LIST for an attribute)
+ ABI_TAG_IMPLICIT (in the TREE_LIST for the argument of abi_tag)
CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR)
LAMBDA_EXPR_CAPTURES_THIS_P (in LAMBDA_EXPR)
DECLTYPE_FOR_LAMBDA_CAPTURE (in DECLTYPE_TYPE)
@@ -2589,6 +2590,10 @@ struct GTY((variable_size)) lang_decl {
must be applied at instantiation time. */
#define ATTR_IS_DEPENDENT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
+/* In a TREE_LIST in the argument of attribute abi_tag, indicates that the tag
+ was inherited from a template parameter, not explicitly indicated. */
+#define ABI_TAG_IMPLICIT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
+
extern tree decl_shadowed_for_var_lookup (tree);
extern void decl_shadowed_for_var_insert (tree, tree);
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index ca8e7632466b..b413ee854e66 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -1402,7 +1402,9 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
|| code == PREDECREMENT_EXPR
|| code == PREINCREMENT_EXPR
|| code == POSTDECREMENT_EXPR
- || code == POSTINCREMENT_EXPR)))
+ || code == POSTINCREMENT_EXPR))
+ || code == VEC_PERM_EXPR
+ || code == VEC_COND_EXPR)
&& (complain & tf_warning))
warning_at (loc, OPT_Wunused_value, "value computed is not used");
}
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 1855716532af..8bb820d0c3b0 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -970,7 +970,7 @@ maybe_add_lambda_conv_op (tree type)
the conversion op is used. */
if (varargs_function_p (callop))
{
- DECL_DELETED_FN (fn) = 1;
+ DECL_DELETED_FN (STRIP_TEMPLATE (fn)) = 1;
return;
}
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index b607811df12a..a1ea7c69a84d 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1339,6 +1339,8 @@ write_abi_tags (tree tags)
for (tree t = tags; t; t = TREE_CHAIN (t))
{
+ if (ABI_TAG_IMPLICIT (t))
+ continue;
tree str = TREE_VALUE (t);
vec_safe_push (vec, str);
}
@@ -3770,7 +3772,8 @@ mangle_conv_op_name_for_type (const tree type)
static void
write_guarded_var_name (const tree variable)
{
- if (strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0)
+ if (DECL_NAME (variable)
+ && strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0)
/* The name of a guard variable for a reference temporary should refer
to the reference, not the temporary. */
write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c99c1fcb6454..c3016bcda4b6 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -5803,7 +5803,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
postfix_expression =
cp_parser_postfix_expression (parser, false, false,
false, false, &idk);
- if (saved_in_statement & IN_CILK_SPAWN)
+ if (!flag_enable_cilkplus)
+ {
+ error_at (token->location, "-fcilkplus must be enabled to use"
+ " %<_Cilk_spawn%>");
+ cfun->calls_cilk_spawn = 0;
+ }
+ else if (saved_in_statement & IN_CILK_SPAWN)
{
error_at (token->location, "consecutive %<_Cilk_spawn%> keywords "
"are not permitted");
@@ -5830,8 +5836,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
finish_expr_stmt (sync_expr);
}
else
- error_at (input_location, "_Cilk_sync cannot be used without enabling "
- "Cilk Plus");
+ error_at (token->location, "-fcilkplus must be enabled to use"
+ " %<_Cilk_sync%>");
cp_lexer_consume_token (parser->lexer);
break;
@@ -8738,6 +8744,8 @@ cp_parser_lambda_expression (cp_parser* parser)
= parser->fully_implicit_function_template_p;
tree implicit_template_parms = parser->implicit_template_parms;
cp_binding_level* implicit_template_scope = parser->implicit_template_scope;
+ bool auto_is_implicit_function_template_parm_p
+ = parser->auto_is_implicit_function_template_parm_p;
parser->num_template_parameter_lists = 0;
parser->in_statement = 0;
@@ -8745,6 +8753,7 @@ cp_parser_lambda_expression (cp_parser* parser)
parser->fully_implicit_function_template_p = false;
parser->implicit_template_parms = 0;
parser->implicit_template_scope = 0;
+ parser->auto_is_implicit_function_template_parm_p = false;
/* By virtue of defining a local class, a lambda expression has access to
the private variables of enclosing classes. */
@@ -8772,6 +8781,8 @@ cp_parser_lambda_expression (cp_parser* parser)
= fully_implicit_function_template_p;
parser->implicit_template_parms = implicit_template_parms;
parser->implicit_template_scope = implicit_template_scope;
+ parser->auto_is_implicit_function_template_parm_p
+ = auto_is_implicit_function_template_parm_p;
}
pop_deferring_access_checks ();
@@ -12977,20 +12988,21 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
= cp_parser_parameter_declaration (parser, /*template_parm_p=*/true,
/*parenthesized_p=*/NULL);
+ if (!parameter_declarator)
+ return error_mark_node;
+
/* If the parameter declaration is marked as a parameter pack, set
*IS_PARAMETER_PACK to notify the caller. Also, unmark the
declarator's PACK_EXPANSION_P, otherwise we'll get errors from
grokdeclarator. */
- if (parameter_declarator
- && parameter_declarator->declarator
+ if (parameter_declarator->declarator
&& parameter_declarator->declarator->parameter_pack_p)
{
*is_parameter_pack = true;
parameter_declarator->declarator->parameter_pack_p = false;
}
- if (parameter_declarator
- && parameter_declarator->default_argument)
+ if (parameter_declarator->default_argument)
{
/* Can happen in some cases of erroneous input (c++/34892). */
if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
@@ -13014,8 +13026,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
/* We might end up with a pack expansion as the type of the non-type
template parameter, in which case this is a non-type template
parameter pack. */
- else if (parameter_declarator
- && parameter_declarator->decl_specifiers.type
+ else if (parameter_declarator->decl_specifiers.type
&& PACK_EXPANSION_P (parameter_declarator->decl_specifiers.type))
{
*is_parameter_pack = true;
@@ -16775,6 +16786,15 @@ cp_parser_init_declarator (cp_parser* parser,
warning (OPT_Wattributes,
"attributes after parenthesized initializer ignored");
+ /* A non-template declaration involving a function parameter list containing
+ an implicit template parameter will have been made into a template. If it
+ turns out that the resulting declaration is not an actual function then
+ finish the template declaration here. An error message will already have
+ been issued. */
+ if (parser->fully_implicit_function_template_p)
+ if (!function_declarator_p (declarator))
+ finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
+
/* For an in-class declaration, use `grokfield' to create the
declaration. */
if (member_p)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 98d7365a7cca..2e7cf60ba7dd 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5149,6 +5149,15 @@ alias_template_specialization_p (const_tree t)
&& DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t)));
}
+/* Return the number of innermost template parameters in TMPL. */
+
+static int
+num_innermost_template_parms (tree tmpl)
+{
+ tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
+ return TREE_VEC_LENGTH (parms);
+}
+
/* Return either TMPL or another template that it is equivalent to under DR
1286: An alias that just changes the name of a template is equivalent to
the other template. */
@@ -5164,6 +5173,8 @@ get_underlying_template (tree tmpl)
{
tree sub = TYPE_TI_TEMPLATE (result);
if (PRIMARY_TEMPLATE_P (sub)
+ && (num_innermost_template_parms (tmpl)
+ == num_innermost_template_parms (sub))
&& same_type_p (result, TREE_TYPE (sub)))
{
/* The alias type is equivalent to the pattern of the
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0bb64c7752b5..9f878874e6d7 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7106,7 +7106,8 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_BASE_OF:
return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
- && DERIVED_FROM_P (type1, type2));
+ && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
+ || DERIVED_FROM_P (type1, type2)));
case CPTK_IS_CLASS:
return (NON_UNION_CLASS_TYPE_P (type1));
diff --git a/gcc/doc/implement-c.texi b/gcc/doc/implement-c.texi
index 2ddae637dec5..762ffe018de0 100644
--- a/gcc/doc/implement-c.texi
+++ b/gcc/doc/implement-c.texi
@@ -479,9 +479,8 @@ by the @option{-funsigned-bitfields} option.
@cite{Allowable bit-field types other than @code{_Bool}, @code{signed int},
and @code{unsigned int} (C99 and C11 6.7.2.1).}
-No other types are permitted in strictly conforming mode.
-@c Would it be better to restrict the pedwarn for other types to C90
-@c mode and document the other types for C99/C11 mode?
+Other integer types, such as @code{long int}, and enumerated types are
+permitted even in strictly conforming mode.
@item
@cite{Whether atomic types are permitted for bit-fields (C11 6.7.2.1).}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ae4d52976465..9e16b3b14229 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -10065,6 +10065,41 @@ The default choice depends on the target.
Set the maximum number of existing candidates that will be considered when
seeking a basis for a new straight-line strength reduction candidate.
+@item asan-globals
+Enable buffer overflow detection for global objects. This kind
+of protection is enabled by default if you are using
+@option{-fsanitize=address} option.
+To disable global objects protection use @option{--param asan-globals=0}.
+
+@item asan-stack
+Enable buffer overflow detection for stack objects. This kind of
+protection is enabled by default when using@option{-fsanitize=address}.
+To disable stack protection use @option{--param asan-stack=0} option.
+
+@item asan-instrument-reads
+Enable buffer overflow detection for memory reads. This kind of
+protection is enabled by default when using @option{-fsanitize=address}.
+To disable memory reads protection use
+@option{--param asan-instrument-reads=0}.
+
+@item asan-instrument-writes
+Enable buffer overflow detection for memory writes. This kind of
+protection is enabled by default when using @option{-fsanitize=address}.
+To disable memory writes protection use
+@option{--param asan-instrument-writes=0} option.
+
+@item asan-memintrin
+Enable detection for built-in functions. This kind of protection
+is enabled by default when using @option{-fsanitize=address}.
+To disable built-in functions protection use
+@option{--param asan-memintrin=0}.
+
+@item asan-use-after-return
+Enable detection of use-after-return. This kind of protection
+is enabled by default when using @option{-fsanitize=address} option.
+To disable use-after-return detection use
+@option{--param asan-use-after-return=0}.
+
@end table
@end table
@@ -18855,6 +18890,38 @@ the AltiVec instruction set. You may also need to set
@option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
enhancements.
+When @option{-maltivec} is used, rather than @option{-maltivec=le} or
+@option{-maltivec=be}, the element order for Altivec intrinsics such
+as @code{vec_splat}, @code{vec_extract}, and @code{vec_insert} will
+match array element order corresponding to the endianness of the
+target. That is, element zero identifies the leftmost element in a
+vector register when targeting a big-endian platform, and identifies
+the rightmost element in a vector register when targeting a
+little-endian platform.
+
+@item -maltivec=be
+@opindex maltivec=be
+Generate Altivec instructions using big-endian element order,
+regardless of whether the target is big- or little-endian. This is
+the default when targeting a big-endian platform.
+
+The element order is used to interpret element numbers in Altivec
+intrinsics such as @code{vec_splat}, @code{vec_extract}, and
+@code{vec_insert}. By default, these will match array element order
+corresponding to the endianness for the target.
+
+@item -maltivec=le
+@opindex maltivec=le
+Generate Altivec instructions using little-endian element order,
+regardless of whether the target is big- or little-endian. This is
+the default when targeting a little-endian platform. This option is
+currently ignored when targeting a big-endian platform.
+
+The element order is used to interpret element numbers in Altivec
+intrinsics such as @code{vec_splat}, @code{vec_extract}, and
+@code{vec_insert}. By default, these will match array element order
+corresponding to the endianness for the target.
+
@item -mvrsave
@itemx -mno-vrsave
@opindex mvrsave
diff --git a/gcc/doc/tree-ssa.texi b/gcc/doc/tree-ssa.texi
index 391dba89e5d2..e0238bd218a9 100644
--- a/gcc/doc/tree-ssa.texi
+++ b/gcc/doc/tree-ssa.texi
@@ -53,9 +53,6 @@ variable has aliases. All these attributes are stored in data
structures called annotations which are then linked to the field
@code{ann} in @code{struct tree_common}.
-Presently, we define annotations for variables (@code{var_ann_t}).
-Annotations are defined and documented in @file{tree-flow.h}.
-
@node SSA Operands
@section SSA Operands
diff --git a/gcc/expr.c b/gcc/expr.c
index 28d84b46becc..756edbe92362 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5294,7 +5294,7 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
temp = expand_expr_real (exp, tmp_target, GET_MODE (target),
(call_param_p
? EXPAND_STACK_PARM : EXPAND_NORMAL),
- &alt_rtl);
+ &alt_rtl, false);
}
/* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
@@ -7882,11 +7882,21 @@ expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
DECL_RTL of the VAR_DECL. *ALT_RTL is also set if EXP is a
COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
- recursively. */
+ recursively.
+
+ If INNER_REFERENCE_P is true, we are expanding an inner reference.
+ In this case, we don't adjust a returned MEM rtx that wouldn't be
+ sufficiently aligned for its mode; instead, it's up to the caller
+ to deal with it afterwards. This is used to make sure that unaligned
+ base objects for which out-of-bounds accesses are supported, for
+ example record types with trailing arrays, aren't realigned behind
+ the back of the caller.
+ The normal operating mode is to pass FALSE for this parameter. */
rtx
expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
- enum expand_modifier modifier, rtx *alt_rtl)
+ enum expand_modifier modifier, rtx *alt_rtl,
+ bool inner_reference_p)
{
rtx ret;
@@ -7898,7 +7908,8 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
return ret ? ret : const0_rtx;
}
- ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);
+ ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl,
+ inner_reference_p);
return ret;
}
@@ -9209,7 +9220,8 @@ stmt_is_replaceable_p (gimple stmt)
rtx
expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
- enum expand_modifier modifier, rtx *alt_rtl)
+ enum expand_modifier modifier, rtx *alt_rtl,
+ bool inner_reference_p)
{
rtx op0, op1, temp, decl_rtl;
tree type;
@@ -9355,7 +9367,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
set_curr_insn_location (gimple_location (g));
r = expand_expr_real (gimple_assign_rhs_to_tree (g), target,
- tmode, modifier, NULL);
+ tmode, modifier, NULL, inner_reference_p);
set_curr_insn_location (saved_loc);
if (REG_P (r) && !REG_EXPR (r))
set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (exp), r);
@@ -9580,7 +9592,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
case SAVE_EXPR:
{
tree val = treeop0;
- rtx ret = expand_expr_real_1 (val, target, tmode, modifier, alt_rtl);
+ rtx ret = expand_expr_real_1 (val, target, tmode, modifier, alt_rtl,
+ inner_reference_p);
if (!SAVE_EXPR_RESOLVED_P (exp))
{
@@ -9717,6 +9730,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
MEM_VOLATILE_P (temp) = 1;
if (modifier != EXPAND_WRITE
&& modifier != EXPAND_MEMORY
+ && !inner_reference_p
&& mode != BLKmode
&& align < GET_MODE_ALIGNMENT (mode))
{
@@ -9942,15 +9956,16 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
computation, since it will need a temporary and TARGET is known
to have to do. This occurs in unchecked conversion in Ada. */
orig_op0 = op0
- = expand_expr (tem,
- (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
- && COMPLETE_TYPE_P (TREE_TYPE (tem))
- && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
- != INTEGER_CST)
- && modifier != EXPAND_STACK_PARM
- ? target : NULL_RTX),
- VOIDmode,
- modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
+ = expand_expr_real (tem,
+ (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
+ && COMPLETE_TYPE_P (TREE_TYPE (tem))
+ && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
+ != INTEGER_CST)
+ && modifier != EXPAND_STACK_PARM
+ ? target : NULL_RTX),
+ VOIDmode,
+ modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier,
+ NULL, true);
/* If the field has a mode, we want to access it in the
field's mode, not the computed mode.
@@ -10307,14 +10322,15 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
{
/* See the normal_inner_ref case for the rationale. */
orig_op0
- = expand_expr (tem,
- (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
- && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
- != INTEGER_CST)
- && modifier != EXPAND_STACK_PARM
- ? target : NULL_RTX),
- VOIDmode,
- modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
+ = expand_expr_real (tem,
+ (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
+ && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
+ != INTEGER_CST)
+ && modifier != EXPAND_STACK_PARM
+ ? target : NULL_RTX),
+ VOIDmode,
+ modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier,
+ NULL, true);
if (MEM_P (orig_op0))
{
@@ -10341,7 +10357,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
}
if (!op0)
- op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
+ op0 = expand_expr_real (treeop0, NULL_RTX, VOIDmode, modifier,
+ NULL, inner_reference_p);
/* If the input and output modes are both the same, we are done. */
if (mode == GET_MODE (op0))
@@ -10408,50 +10425,53 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
op0 = copy_rtx (op0);
set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
}
- else if (mode != BLKmode
- && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode)
- /* If the target does have special handling for unaligned
- loads of mode then use them. */
- && ((icode = optab_handler (movmisalign_optab, mode))
- != CODE_FOR_nothing))
- {
- rtx reg, insn;
-
- op0 = adjust_address (op0, mode, 0);
- /* We've already validated the memory, and we're creating a
- new pseudo destination. The predicates really can't
- fail. */
- reg = gen_reg_rtx (mode);
-
- /* Nor can the insn generator. */
- insn = GEN_FCN (icode) (reg, op0);
- emit_insn (insn);
- return reg;
- }
- else if (STRICT_ALIGNMENT
+ else if (modifier != EXPAND_WRITE
+ && modifier != EXPAND_MEMORY
+ && !inner_reference_p
&& mode != BLKmode
&& MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))
{
- tree inner_type = TREE_TYPE (treeop0);
- HOST_WIDE_INT temp_size
- = MAX (int_size_in_bytes (inner_type),
- (HOST_WIDE_INT) GET_MODE_SIZE (mode));
- rtx new_rtx
- = assign_stack_temp_for_type (mode, temp_size, type);
- rtx new_with_op0_mode
- = adjust_address (new_rtx, GET_MODE (op0), 0);
-
- gcc_assert (!TREE_ADDRESSABLE (exp));
-
- if (GET_MODE (op0) == BLKmode)
- emit_block_move (new_with_op0_mode, op0,
- GEN_INT (GET_MODE_SIZE (mode)),
- (modifier == EXPAND_STACK_PARM
- ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
- else
- emit_move_insn (new_with_op0_mode, op0);
+ /* If the target does have special handling for unaligned
+ loads of mode then use them. */
+ if ((icode = optab_handler (movmisalign_optab, mode))
+ != CODE_FOR_nothing)
+ {
+ rtx reg, insn;
+
+ op0 = adjust_address (op0, mode, 0);
+ /* We've already validated the memory, and we're creating a
+ new pseudo destination. The predicates really can't
+ fail. */
+ reg = gen_reg_rtx (mode);
+
+ /* Nor can the insn generator. */
+ insn = GEN_FCN (icode) (reg, op0);
+ emit_insn (insn);
+ return reg;
+ }
+ else if (STRICT_ALIGNMENT)
+ {
+ tree inner_type = TREE_TYPE (treeop0);
+ HOST_WIDE_INT temp_size
+ = MAX (int_size_in_bytes (inner_type),
+ (HOST_WIDE_INT) GET_MODE_SIZE (mode));
+ rtx new_rtx
+ = assign_stack_temp_for_type (mode, temp_size, type);
+ rtx new_with_op0_mode
+ = adjust_address (new_rtx, GET_MODE (op0), 0);
+
+ gcc_assert (!TREE_ADDRESSABLE (exp));
+
+ if (GET_MODE (op0) == BLKmode)
+ emit_block_move (new_with_op0_mode, op0,
+ GEN_INT (GET_MODE_SIZE (mode)),
+ (modifier == EXPAND_STACK_PARM
+ ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
+ else
+ emit_move_insn (new_with_op0_mode, op0);
- op0 = new_rtx;
+ op0 = new_rtx;
+ }
}
op0 = adjust_address (op0, mode, 0);
@@ -10551,7 +10571,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
/* WITH_SIZE_EXPR expands to its first argument. The caller should
have pulled out the size to use in whatever context it needed. */
return expand_expr_real (treeop0, original_target, tmode,
- modifier, alt_rtl);
+ modifier, alt_rtl, inner_reference_p);
default:
return expand_expr_real_2 (&ops, target, tmode, modifier);
diff --git a/gcc/expr.h b/gcc/expr.h
index a39b98ea5efb..da5d4a6d56fd 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -41,7 +41,8 @@ along with GCC; see the file COPYING3. If not see
is a constant that is not a legitimate address.
EXPAND_WRITE means we are only going to write to the resulting rtx.
EXPAND_MEMORY means we are interested in a memory result, even if
- the memory is constant and we could have propagated a constant value. */
+ the memory is constant and we could have propagated a constant value,
+ or the memory is unaligned on a STRICT_ALIGNMENT target. */
enum expand_modifier {EXPAND_NORMAL = 0, EXPAND_STACK_PARM, EXPAND_SUM,
EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER, EXPAND_WRITE,
EXPAND_MEMORY};
@@ -437,9 +438,9 @@ extern rtx force_operand (rtx, rtx);
/* Work horses for expand_expr. */
extern rtx expand_expr_real (tree, rtx, enum machine_mode,
- enum expand_modifier, rtx *);
+ enum expand_modifier, rtx *, bool);
extern rtx expand_expr_real_1 (tree, rtx, enum machine_mode,
- enum expand_modifier, rtx *);
+ enum expand_modifier, rtx *, bool);
extern rtx expand_expr_real_2 (sepops, rtx, enum machine_mode,
enum expand_modifier);
@@ -450,13 +451,13 @@ static inline rtx
expand_expr (tree exp, rtx target, enum machine_mode mode,
enum expand_modifier modifier)
{
- return expand_expr_real (exp, target, mode, modifier, NULL);
+ return expand_expr_real (exp, target, mode, modifier, NULL, false);
}
static inline rtx
expand_normal (tree exp)
{
- return expand_expr_real (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL, NULL);
+ return expand_expr_real (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL, NULL, false);
}
/* At the start of a function, record that we have no previously-pushed
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 202c0479e426..f2f1a853ddfc 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,38 @@
+2014-01-12 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/58026
+ * decl.c (gfc_match_data_decl): Improve error recovery.
+
+2014-01-09 Tobias Burnus <burnus@net-b.de>
+
+ * cpp.c (gfc_cpp_handle_option): Add missing break.
+ * trans-io.c (transfer_expr): Silence unused value warning.
+
+2014-01-08 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/58182
+ * resolve.c (gfc_verify_binding_labels): Modify order of checks.
+
+2014-01-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/59589
+ * class.c (comp_is_finalizable): New function to dermine if a given
+ component is finalizable.
+ (finalize_component, generate_finalization_wrapper): Use it.
+
+2014-01-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/59023
+ PR fortran/59662
+ * resolve.c (resolve_global_procedure): Don't apply to c-binding
+ procedures.
+ (gfc_verify_binding_labels): Remove duplicate line.
+
+2014-01-04 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/59547
+ * class.c (add_proc_comp): Copy pure attribute.
+
2014-01-02 Richard Sandiford <rdsandiford@googlemail.com>
Update copyright years
diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 47a308257eba..d3569fd6ba89 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -714,9 +714,11 @@ add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
if (tb->u.specific)
{
- c->ts.interface = tb->u.specific->n.sym;
+ gfc_symbol *ifc = tb->u.specific->n.sym;
+ c->ts.interface = ifc;
if (!tb->deferred)
c->initializer = gfc_get_variable_expr (tb->u.specific);
+ c->attr.pure = ifc->attr.pure;
}
}
@@ -785,6 +787,25 @@ has_finalizer_component (gfc_symbol *derived)
}
+static bool
+comp_is_finalizable (gfc_component *comp)
+{
+ if (comp->attr.allocatable && comp->ts.type != BT_CLASS)
+ return true;
+ else if (comp->ts.type == BT_DERIVED && !comp->attr.pointer
+ && (comp->ts.u.derived->attr.alloc_comp
+ || has_finalizer_component (comp->ts.u.derived)
+ || (comp->ts.u.derived->f2k_derived
+ && comp->ts.u.derived->f2k_derived->finalizers)))
+ return true;
+ else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
+ && CLASS_DATA (comp)->attr.allocatable)
+ return true;
+ else
+ return false;
+}
+
+
/* Call DEALLOCATE for the passed component if it is allocatable, if it is
neither allocatable nor a pointer but has a finalizer, call it. If it
is a nonpointer component with allocatable components or has finalizers, walk
@@ -801,19 +822,7 @@ finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
gfc_expr *e;
gfc_ref *ref;
- if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS
- && !comp->attr.allocatable)
- return;
-
- if ((comp->ts.type == BT_DERIVED && comp->attr.pointer)
- || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
- && CLASS_DATA (comp)->attr.pointer))
- return;
-
- if (comp->ts.type == BT_DERIVED && !comp->attr.allocatable
- && (comp->ts.u.derived->f2k_derived == NULL
- || comp->ts.u.derived->f2k_derived->finalizers == NULL)
- && !has_finalizer_component (comp->ts.u.derived))
+ if (!comp_is_finalizable (comp))
return;
e = gfc_copy_expr (expr);
@@ -1460,17 +1469,7 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
&& ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
continue;
- if (comp->ts.type != BT_CLASS && !comp->attr.pointer
- && (comp->attr.allocatable
- || (comp->ts.type == BT_DERIVED
- && (comp->ts.u.derived->attr.alloc_comp
- || has_finalizer_component (comp->ts.u.derived)
- || (comp->ts.u.derived->f2k_derived
- && comp->ts.u.derived->f2k_derived->finalizers)))))
- finalizable_comp = true;
- else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
- && CLASS_DATA (comp)->attr.allocatable)
- finalizable_comp = true;
+ finalizable_comp |= comp_is_finalizable (comp);
}
/* If there is no new finalizer and no new allocatable, return with
diff --git a/gcc/fortran/cpp.c b/gcc/fortran/cpp.c
index 37bc13b388ed..68ce91ffdbf5 100644
--- a/gcc/fortran/cpp.c
+++ b/gcc/fortran/cpp.c
@@ -363,6 +363,7 @@ gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED
case OPT_Wdate_time:
gfc_cpp_option.warn_date_time = value;
+ break;
case OPT_A:
case OPT_D:
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index e8ac941a0825..8831b1997bd6 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -4287,12 +4287,10 @@ gfc_match_data_decl (void)
|| current_ts.u.derived->attr.zero_comp))
goto ok;
- /* Now we have an error, which we signal, and then fix up
- because the knock-on is plain and simple confusing. */
- gfc_error_now ("Derived type at %C has not been previously defined "
- "and so cannot appear in a derived type definition");
- current_attr.pointer = 1;
- goto ok;
+ gfc_error ("Derived type at %C has not been previously defined "
+ "and so cannot appear in a derived type definition");
+ m = MATCH_ERROR;
+ goto cleanup;
}
ok:
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 0e80f491abc7..ad088bb73b2e 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -2351,6 +2351,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *where,
if ((sym->attr.if_source == IFSRC_UNKNOWN
|| sym->attr.if_source == IFSRC_IFBODY)
&& gsym->type != GSYM_UNKNOWN
+ && !gsym->binding_label
&& gsym->ns
&& gsym->ns->resolved != -1
&& gsym->ns->proc_name
@@ -10163,7 +10164,6 @@ gfc_verify_binding_labels (gfc_symbol *sym)
gsym->where = sym->declared_at;
gsym->sym_name = sym->name;
gsym->binding_label = sym->binding_label;
- gsym->binding_label = sym->binding_label;
gsym->ns = sym->ns;
gsym->mod_name = module;
if (sym->attr.function)
@@ -10200,11 +10200,11 @@ gfc_verify_binding_labels (gfc_symbol *sym)
&& ((gsym->type != GSYM_SUBROUTINE && gsym->type != GSYM_FUNCTION)
|| (gsym->defined && sym->attr.if_source != IFSRC_IFBODY))
&& sym != gsym->ns->proc_name
- && (strcmp (gsym->sym_name, sym->name) != 0
- || module != gsym->mod_name
+ && (module != gsym->mod_name
+ || strcmp (gsym->sym_name, sym->name) != 0
|| (module && strcmp (module, gsym->mod_name) != 0)))
{
- /* Print an error if the procdure is defined multiple times; we have to
+ /* Print an error if the procedure is defined multiple times; we have to
exclude references to the same procedure via module association or
multiple checks for the same procedure. */
gfc_error ("Procedure %s with binding label %s at %L uses the same "
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index ba27f810d79a..853e77d62f52 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -2152,7 +2152,7 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
function, if only referenced in an io statement, requires this
check (see PR58771). */
if (ts->u.derived->backend_decl == NULL_TREE)
- tmp = gfc_typenode_for_spec (ts);
+ (void) gfc_typenode_for_spec (ts);
for (c = ts->u.derived->components; c; c = c->next)
{
diff --git a/gcc/function.c b/gcc/function.c
index 8dcdb3136614..b43e67f65ef6 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -4405,6 +4405,7 @@ invoke_set_current_function_hook (tree fndecl)
cl_optimization_restore (&global_options, TREE_OPTIMIZATION (opts));
}
+ targetm.set_current_function (fndecl);
this_fn_optabs = this_target_optabs;
if (opts != optimization_default_node)
@@ -4414,8 +4415,6 @@ invoke_set_current_function_hook (tree fndecl)
this_fn_optabs = (struct target_optabs *)
TREE_OPTIMIZATION_OPTABS (opts);
}
-
- targetm.set_current_function (fndecl);
}
}
diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c
index ef5120a0c1f3..b710f596e378 100644
--- a/gcc/gcov-io.c
+++ b/gcc/gcov-io.c
@@ -36,6 +36,61 @@ static const gcov_unsigned_t *gcov_read_words (unsigned);
static void gcov_allocate (unsigned);
#endif
+/* Optimum number of gcov_unsigned_t's read from or written to disk. */
+#define GCOV_BLOCK_SIZE (1 << 10)
+
+GCOV_LINKAGE struct gcov_var
+{
+ FILE *file;
+ gcov_position_t start; /* Position of first byte of block */
+ unsigned offset; /* Read/write position within the block. */
+ unsigned length; /* Read limit in the block. */
+ unsigned overread; /* Number of words overread. */
+ int error; /* < 0 overflow, > 0 disk error. */
+ int mode; /* < 0 writing, > 0 reading */
+#if IN_LIBGCOV
+ /* Holds one block plus 4 bytes, thus all coverage reads & writes
+ fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
+ to and from the disk. libgcov never backtracks and only writes 4
+ or 8 byte objects. */
+ gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1];
+#else
+ int endian; /* Swap endianness. */
+ /* Holds a variable length block, as the compiler can write
+ strings and needs to backtrack. */
+ size_t alloc;
+ gcov_unsigned_t *buffer;
+#endif
+} gcov_var;
+
+/* Save the current position in the gcov file. */
+static inline gcov_position_t
+gcov_position (void)
+{
+ gcc_assert (gcov_var.mode > 0);
+ return gcov_var.start + gcov_var.offset;
+}
+
+/* Return nonzero if the error flag is set. */
+static inline int
+gcov_is_error (void)
+{
+ return gcov_var.file ? gcov_var.error : 1;
+}
+
+#if IN_LIBGCOV
+/* Move to beginning of file and initialize for writing. */
+GCOV_LINKAGE inline void
+gcov_rewrite (void)
+{
+ gcc_assert (gcov_var.mode > 0);
+ gcov_var.mode = -1;
+ gcov_var.start = 0;
+ gcov_var.offset = 0;
+ fseek (gcov_var.file, 0L, SEEK_SET);
+}
+#endif
+
static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
{
#if !IN_LIBGCOV
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 3d3fd0565872..cbf95cfc5523 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -164,51 +164,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#ifndef GCC_GCOV_IO_H
#define GCC_GCOV_IO_H
-#if IN_LIBGCOV
-/* About the target */
-
-#if BITS_PER_UNIT == 8
-typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI)));
-typedef unsigned gcov_position_t __attribute__ ((mode (SI)));
-#if LONG_LONG_TYPE_SIZE > 32
-typedef signed gcov_type __attribute__ ((mode (DI)));
-typedef unsigned gcov_type_unsigned __attribute__ ((mode (DI)));
-#else
-typedef signed gcov_type __attribute__ ((mode (SI)));
-typedef unsigned gcov_type_unsigned __attribute__ ((mode (SI)));
-#endif
-#else
-#if BITS_PER_UNIT == 16
-typedef unsigned gcov_unsigned_t __attribute__ ((mode (HI)));
-typedef unsigned gcov_position_t __attribute__ ((mode (HI)));
-#if LONG_LONG_TYPE_SIZE > 32
-typedef signed gcov_type __attribute__ ((mode (SI)));
-typedef unsigned gcov_type_unsigned __attribute__ ((mode (SI)));
-#else
-typedef signed gcov_type __attribute__ ((mode (HI)));
-typedef unsigned gcov_type_unsigned __attribute__ ((mode (HI)));
-#endif
-#else
-typedef unsigned gcov_unsigned_t __attribute__ ((mode (QI)));
-typedef unsigned gcov_position_t __attribute__ ((mode (QI)));
-#if LONG_LONG_TYPE_SIZE > 32
-typedef signed gcov_type __attribute__ ((mode (HI)));
-typedef unsigned gcov_type_unsigned __attribute__ ((mode (HI)));
-#else
-typedef signed gcov_type __attribute__ ((mode (QI)));
-typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
-#endif
-#endif
-#endif
-
-
-#if defined (TARGET_POSIX_IO)
-#define GCOV_LOCKED 1
-#else
-#define GCOV_LOCKED 0
-#endif
-
-#else /* !IN_LIBGCOV */
+#ifndef IN_LIBGCOV
/* About the host */
typedef unsigned gcov_unsigned_t;
@@ -231,47 +187,9 @@ typedef unsigned HOST_WIDEST_INT gcov_type_unsigned;
#define GCOV_LOCKED 0
#endif
-#endif /* !IN_LIBGCOV */
-
-/* In gcov we want function linkage to be static. In the compiler we want
- it extern, so that they can be accessed from elsewhere. In libgcov we
- need these functions to be extern, so prefix them with __gcov. In
- libgcov they must also be hidden so that the instance in the executable
- is not also used in a DSO. */
-#if IN_LIBGCOV
-
-#include "tconfig.h"
-
-#define gcov_var __gcov_var
-#define gcov_open __gcov_open
-#define gcov_close __gcov_close
-#define gcov_write_tag_length __gcov_write_tag_length
-#define gcov_position __gcov_position
-#define gcov_seek __gcov_seek
-#define gcov_rewrite __gcov_rewrite
-#define gcov_is_error __gcov_is_error
-#define gcov_write_unsigned __gcov_write_unsigned
-#define gcov_write_counter __gcov_write_counter
-#define gcov_write_summary __gcov_write_summary
-#define gcov_read_unsigned __gcov_read_unsigned
-#define gcov_read_counter __gcov_read_counter
-#define gcov_read_summary __gcov_read_summary
-
-/* Poison these, so they don't accidentally slip in. */
-#pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length
-#pragma GCC poison gcov_read_string gcov_sync gcov_time gcov_magic
-
-#ifdef HAVE_GAS_HIDDEN
-#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
-#else
-#define ATTRIBUTE_HIDDEN
-#endif
-
-#else
-
#define ATTRIBUTE_HIDDEN
-#endif
+#endif /* !IN_LIBGOCV */
#ifndef GCOV_LINKAGE
#define GCOV_LINKAGE extern
@@ -442,132 +360,7 @@ struct gcov_summary
struct gcov_ctr_summary ctrs[GCOV_COUNTERS_SUMMABLE];
};
-/* Structures embedded in coveraged program. The structures generated
- by write_profile must match these. */
-
-#if IN_LIBGCOV
-/* Information about counters for a single function. */
-struct gcov_ctr_info
-{
- gcov_unsigned_t num; /* number of counters. */
- gcov_type *values; /* their values. */
-};
-
-/* Information about a single function. This uses the trailing array
- idiom. The number of counters is determined from the merge pointer
- array in gcov_info. The key is used to detect which of a set of
- comdat functions was selected -- it points to the gcov_info object
- of the object file containing the selected comdat function. */
-
-struct gcov_fn_info
-{
- const struct gcov_info *key; /* comdat key */
- gcov_unsigned_t ident; /* unique ident of function */
- gcov_unsigned_t lineno_checksum; /* function lineo_checksum */
- gcov_unsigned_t cfg_checksum; /* function cfg checksum */
- struct gcov_ctr_info ctrs[0]; /* instrumented counters */
-};
-
-/* Type of function used to merge counters. */
-typedef void (*gcov_merge_fn) (gcov_type *, gcov_unsigned_t);
-
-/* Information about a single object file. */
-struct gcov_info
-{
- gcov_unsigned_t version; /* expected version number */
- struct gcov_info *next; /* link to next, used by libgcov */
-
- gcov_unsigned_t stamp; /* uniquifying time stamp */
- const char *filename; /* output file name */
-
- gcov_merge_fn merge[GCOV_COUNTERS]; /* merge functions (null for
- unused) */
-
- unsigned n_functions; /* number of functions */
- const struct gcov_fn_info *const *functions; /* pointer to pointers
- to function information */
-};
-
-/* Register a new object file module. */
-extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN;
-
-/* Called before fork, to avoid double counting. */
-extern void __gcov_flush (void) ATTRIBUTE_HIDDEN;
-
-/* Function to reset all counters to 0. */
-extern void __gcov_reset (void);
-
-/* Function to enable early write of profile information so far. */
-extern void __gcov_dump (void);
-
-/* The merge function that just sums the counters. */
-extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
-
-/* The merge function to choose the most common value. */
-extern void __gcov_merge_single (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
-
-/* The merge function to choose the most common difference between
- consecutive values. */
-extern void __gcov_merge_delta (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
-
-/* The merge function that just ors the counters together. */
-extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
-
-extern void __gcov_merge_time_profile (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
-
-/* The profiler functions. */
-extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
-extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
-extern void __gcov_one_value_profiler (gcov_type *, gcov_type);
-extern void __gcov_indirect_call_profiler (gcov_type*, gcov_type,
- void*, void*);
-extern void __gcov_indirect_call_profiler_v2 (gcov_type, void *);
-extern void __gcov_average_profiler (gcov_type *, gcov_type);
-extern void __gcov_ior_profiler (gcov_type *, gcov_type);
-extern void __gcov_time_profiler (gcov_type *);
-
-#ifndef inhibit_libc
-/* The wrappers around some library functions.. */
-extern pid_t __gcov_fork (void) ATTRIBUTE_HIDDEN;
-extern int __gcov_execl (const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execlp (const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execle (const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execv (const char *, char *const []) ATTRIBUTE_HIDDEN;
-extern int __gcov_execvp (const char *, char *const []) ATTRIBUTE_HIDDEN;
-extern int __gcov_execve (const char *, char *const [], char *const [])
- ATTRIBUTE_HIDDEN;
-#endif
-
-#endif /* IN_LIBGCOV */
-
-#if IN_LIBGCOV >= 0
-
-/* Optimum number of gcov_unsigned_t's read from or written to disk. */
-#define GCOV_BLOCK_SIZE (1 << 10)
-
-GCOV_LINKAGE struct gcov_var
-{
- FILE *file;
- gcov_position_t start; /* Position of first byte of block */
- unsigned offset; /* Read/write position within the block. */
- unsigned length; /* Read limit in the block. */
- unsigned overread; /* Number of words overread. */
- int error; /* < 0 overflow, > 0 disk error. */
- int mode; /* < 0 writing, > 0 reading */
-#if IN_LIBGCOV
- /* Holds one block plus 4 bytes, thus all coverage reads & writes
- fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
- to and from the disk. libgcov never backtracks and only writes 4
- or 8 byte objects. */
- gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1];
-#else
- int endian; /* Swap endianness. */
- /* Holds a variable length block, as the compiler can write
- strings and needs to backtrack. */
- size_t alloc;
- gcov_unsigned_t *buffer;
-#endif
-} gcov_var ATTRIBUTE_HIDDEN;
+#if !defined(inhibit_libc)
/* Functions for reading and writing gcov files. In libgcov you can
open the file for reading then writing. Elsewhere you can open the
@@ -578,38 +371,20 @@ GCOV_LINKAGE struct gcov_var
you use the functions for reading, then gcov_rewrite then the
functions for writing. Your file may become corrupted if you break
these invariants. */
-#if IN_LIBGCOV
-GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
-#else
+
+#if !IN_LIBGCOV
GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/);
GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t);
#endif
-GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN;
/* Available everywhere. */
-static gcov_position_t gcov_position (void);
-static int gcov_is_error (void);
-
+GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN;
GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN;
GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN;
GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *) ATTRIBUTE_HIDDEN;
-
-#if IN_LIBGCOV
-/* Available only in libgcov */
-GCOV_LINKAGE void gcov_write_counter (gcov_type) ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t)
- ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
- const struct gcov_summary *)
- ATTRIBUTE_HIDDEN;
-static void gcov_rewrite (void);
-GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
-#else
-/* Available outside libgcov */
GCOV_LINKAGE const char *gcov_read_string (void);
GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/,
gcov_unsigned_t /*length */);
-#endif
#if !IN_GCOV
/* Available outside gcov */
@@ -651,37 +426,6 @@ GCOV_LINKAGE void compute_working_sets (const struct gcov_ctr_summary *summary,
GCOV_LINKAGE time_t gcov_time (void);
#endif
-/* Save the current position in the gcov file. */
-
-static inline gcov_position_t
-gcov_position (void)
-{
- gcc_assert (gcov_var.mode > 0);
- return gcov_var.start + gcov_var.offset;
-}
-
-/* Return nonzero if the error flag is set. */
-
-static inline int
-gcov_is_error (void)
-{
- return gcov_var.file ? gcov_var.error : 1;
-}
-
-#if IN_LIBGCOV
-/* Move to beginning of file and initialize for writing. */
-
-static inline void
-gcov_rewrite (void)
-{
- gcc_assert (gcov_var.mode > 0);
- gcov_var.mode = -1;
- gcov_var.start = 0;
- gcov_var.offset = 0;
- fseek (gcov_var.file, 0L, SEEK_SET);
-}
-#endif
-
-#endif /* IN_LIBGCOV >= 0 */
+#endif /* !inhibit_libc */
#endif /* GCC_GCOV_IO_H */
diff --git a/gcc/gdbasan.in b/gcc/gdbasan.in
index cf05825395b9..3a6fca0a8acc 100644
--- a/gcc/gdbasan.in
+++ b/gcc/gdbasan.in
@@ -1,3 +1,7 @@
# Put a breakpoint on __asan_report_error to help with debugging buffer
# overflow.
b __asan_report_error
+
+# Put a breakpoint on __sanitizer::Report to help with debugging sanitizer
+# issues.
+b __sanitizer::Report
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 5d5b361501bb..e3c1a5695cc1 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -879,8 +879,6 @@ gimple_fold_builtin (gimple stmt)
int nargs;
location_t loc = gimple_location (stmt);
- gcc_assert (is_gimple_call (stmt));
-
ignore = (gimple_call_lhs (stmt) == NULL);
/* First try the generic builtin folder. If that succeeds, return the
@@ -890,6 +888,8 @@ gimple_fold_builtin (gimple stmt)
{
if (ignore)
STRIP_NOPS (result);
+ else
+ result = fold_convert (gimple_call_return_type (stmt), result);
return result;
}
@@ -1167,7 +1167,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
(OBJ_TYPE_REF_EXPR (callee)))))
{
fprintf (dump_file,
- "Type inheritnace inconsistent devirtualization of ");
+ "Type inheritance inconsistent devirtualization of ");
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, " to ");
print_generic_expr (dump_file, callee, TDF_SLIM);
@@ -1177,24 +1177,45 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee));
changed = true;
}
- else if (flag_devirtualize && virtual_method_call_p (callee))
+ else if (flag_devirtualize && !inplace && virtual_method_call_p (callee))
{
bool final;
vec <cgraph_node *>targets
= possible_polymorphic_call_targets (callee, &final);
if (final && targets.length () <= 1)
{
+ tree lhs = gimple_call_lhs (stmt);
if (targets.length () == 1)
{
gimple_call_set_fndecl (stmt, targets[0]->decl);
changed = true;
+ /* If the call becomes noreturn, remove the lhs. */
+ if (lhs && (gimple_call_flags (stmt) & ECF_NORETURN))
+ {
+ if (TREE_CODE (lhs) == SSA_NAME)
+ {
+ tree var = create_tmp_var (TREE_TYPE (lhs), NULL);
+ tree def = get_or_create_ssa_default_def (cfun, var);
+ gimple new_stmt = gimple_build_assign (lhs, def);
+ gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
+ }
+ gimple_call_set_lhs (stmt, NULL_TREE);
+ }
}
- else if (!inplace)
+ else
{
tree fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
gimple new_stmt = gimple_build_call (fndecl, 0);
gimple_set_location (new_stmt, gimple_location (stmt));
- gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
+ if (lhs && TREE_CODE (lhs) == SSA_NAME)
+ {
+ tree var = create_tmp_var (TREE_TYPE (lhs), NULL);
+ tree def = get_or_create_ssa_default_def (cfun, var);
+ gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
+ update_call_from_tree (gsi, def);
+ }
+ else
+ gsi_replace (gsi, new_stmt, true);
return true;
}
}
@@ -1206,8 +1227,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
/* Check for builtins that CCP can handle using information not
available in the generic fold routines. */
- callee = gimple_call_fndecl (stmt);
- if (callee && DECL_BUILT_IN (callee))
+ if (gimple_call_builtin_p (stmt))
{
tree result = gimple_fold_builtin (stmt);
if (result)
@@ -1216,7 +1236,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
gimplify_and_update_call_from_tree (gsi, result);
changed = true;
}
- else if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD)
+ else if (gimple_call_builtin_p (stmt, BUILT_IN_MD))
changed |= targetm.gimple_fold_builtin (gsi);
}
@@ -2726,7 +2746,9 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
fn = (*valueize) (gimple_call_fn (stmt));
if (TREE_CODE (fn) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
- && DECL_BUILT_IN (TREE_OPERAND (fn, 0)))
+ && DECL_BUILT_IN (TREE_OPERAND (fn, 0))
+ && gimple_builtin_call_types_compatible_p (stmt,
+ TREE_OPERAND (fn, 0)))
{
tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt));
tree call, retval;
@@ -2738,8 +2760,11 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
fn, gimple_call_num_args (stmt), args);
retval = fold_call_expr (EXPR_LOCATION (call), call, false);
if (retval)
- /* fold_call_expr wraps the result inside a NOP_EXPR. */
- STRIP_NOPS (retval);
+ {
+ /* fold_call_expr wraps the result inside a NOP_EXPR. */
+ STRIP_NOPS (retval);
+ retval = fold_convert (gimple_call_return_type (stmt), retval);
+ }
return retval;
}
return NULL_TREE;
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 0330c0cc9f38..4d3b99ed9d23 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -2351,27 +2351,37 @@ gimple_ior_addresses_taken (bitmap addresses_taken, gimple stmt)
}
-/* Return TRUE iff stmt is a call to a built-in function. */
+/* Return true if TYPE1 and TYPE2 are compatible enough for builtin
+ processing. */
-bool
-is_gimple_builtin_call (gimple stmt)
-{
- tree callee;
-
- if (is_gimple_call (stmt)
- && (callee = gimple_call_fndecl (stmt))
- && is_builtin_fn (callee)
- && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
- return true;
-
- return false;
+static bool
+validate_type (tree type1, tree type2)
+{
+ if (INTEGRAL_TYPE_P (type1)
+ && INTEGRAL_TYPE_P (type2))
+ ;
+ else if (POINTER_TYPE_P (type1)
+ && POINTER_TYPE_P (type2))
+ ;
+ else if (TREE_CODE (type1)
+ != TREE_CODE (type2))
+ return false;
+ return true;
}
-/* Return true when STMTs arguments match those of FNDECL. */
+/* Return true when STMTs arguments and return value match those of FNDECL,
+ a decl of a builtin function. */
-static bool
-validate_call (gimple stmt, tree fndecl)
+bool
+gimple_builtin_call_types_compatible_p (gimple stmt, tree fndecl)
{
+ gcc_checking_assert (DECL_BUILT_IN_CLASS (fndecl) != NOT_BUILT_IN);
+
+ tree ret = gimple_call_lhs (stmt);
+ if (ret
+ && !validate_type (TREE_TYPE (ret), TREE_TYPE (TREE_TYPE (fndecl))))
+ return false;
+
tree targs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
unsigned nargs = gimple_call_num_args (stmt);
for (unsigned i = 0; i < nargs; ++i)
@@ -2380,14 +2390,7 @@ validate_call (gimple stmt, tree fndecl)
if (!targs)
return true;
tree arg = gimple_call_arg (stmt, i);
- if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
- && INTEGRAL_TYPE_P (TREE_VALUE (targs)))
- ;
- else if (POINTER_TYPE_P (TREE_TYPE (arg))
- && POINTER_TYPE_P (TREE_VALUE (targs)))
- ;
- else if (TREE_CODE (TREE_TYPE (arg))
- != TREE_CODE (TREE_VALUE (targs)))
+ if (!validate_type (TREE_TYPE (arg), TREE_VALUE (targs)))
return false;
targs = TREE_CHAIN (targs);
}
@@ -2396,6 +2399,19 @@ validate_call (gimple stmt, tree fndecl)
return true;
}
+/* Return true when STMT is builtins call. */
+
+bool
+gimple_call_builtin_p (gimple stmt)
+{
+ tree fndecl;
+ if (is_gimple_call (stmt)
+ && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
+ && DECL_BUILT_IN_CLASS (fndecl) != NOT_BUILT_IN)
+ return gimple_builtin_call_types_compatible_p (stmt, fndecl);
+ return false;
+}
+
/* Return true when STMT is builtins call to CLASS. */
bool
@@ -2405,7 +2421,7 @@ gimple_call_builtin_p (gimple stmt, enum built_in_class klass)
if (is_gimple_call (stmt)
&& (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
&& DECL_BUILT_IN_CLASS (fndecl) == klass)
- return validate_call (stmt, fndecl);
+ return gimple_builtin_call_types_compatible_p (stmt, fndecl);
return false;
}
@@ -2419,7 +2435,7 @@ gimple_call_builtin_p (gimple stmt, enum built_in_function code)
&& (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (fndecl) == code)
- return validate_call (stmt, fndecl);
+ return gimple_builtin_call_types_compatible_p (stmt, fndecl);
return false;
}
diff --git a/gcc/gimple.h b/gcc/gimple.h
index df92863699be..0e80d2eb7002 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1253,7 +1253,8 @@ extern tree gimple_unsigned_type (tree);
extern tree gimple_signed_type (tree);
extern alias_set_type gimple_get_alias_set (tree);
extern bool gimple_ior_addresses_taken (bitmap, gimple);
-extern bool is_gimple_builtin_call (gimple stmt);
+extern bool gimple_builtin_call_types_compatible_p (gimple, tree);
+extern bool gimple_call_builtin_p (gimple);
extern bool gimple_call_builtin_p (gimple, enum built_in_class);
extern bool gimple_call_builtin_p (gimple, enum built_in_function);
extern bool gimple_asm_clobbers_memory_p (const_gimple);
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index a6e0c75478b0..202d084f09fb 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -7373,12 +7373,22 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
TREE_TYPE (*expr_p));
break;
+ case VIEW_CONVERT_EXPR:
+ if (is_gimple_reg_type (TREE_TYPE (*expr_p))
+ && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
+ {
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
+ recalculate_side_effects (*expr_p);
+ break;
+ }
+ /* Fallthru. */
+
case ARRAY_REF:
case ARRAY_RANGE_REF:
case REALPART_EXPR:
case IMAGPART_EXPR:
case COMPONENT_REF:
- case VIEW_CONVERT_EXPR:
ret = gimplify_compound_lval (expr_p, pre_p, post_p,
fallback ? fallback : fb_rvalue);
break;
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 2f1c026c9833..6f2f24367aaa 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -3060,6 +3060,9 @@ class Type_conversion_expression : public Expression
Expression*
do_lower(Gogo*, Named_object*, Statement_inserter*, int);
+ Expression*
+ do_flatten(Gogo*, Named_object*, Statement_inserter*);
+
bool
do_is_constant() const;
@@ -3203,6 +3206,25 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*,
return this;
}
+// Flatten a type conversion by using a temporary variable for the slice
+// in slice to string conversions.
+
+Expression*
+Type_conversion_expression::do_flatten(Gogo*, Named_object*,
+ Statement_inserter* inserter)
+{
+ if (this->type()->is_string_type()
+ && this->expr_->type()->is_slice_type()
+ && !this->expr_->is_variable())
+ {
+ Temporary_statement* temp =
+ Statement::make_temporary(NULL, this->expr_, this->location());
+ inserter->insert(temp);
+ this->expr_ = Expression::make_temporary_reference(temp, this->location());
+ }
+ return this;
+}
+
// Return whether a type conversion is a constant.
bool
@@ -3361,47 +3383,24 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
}
else if (type->is_string_type() && expr_type->is_slice_type())
{
- if (!DECL_P(expr_tree))
- expr_tree = save_expr(expr_tree);
-
- Type* int_type = Type::lookup_integer_type("int");
- tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
-
+ Location location = this->location();
Array_type* a = expr_type->array_type();
Type* e = a->element_type()->forwarded();
go_assert(e->integer_type() != NULL);
- tree valptr = fold_convert(const_ptr_type_node,
- a->value_pointer_tree(gogo, expr_tree));
- tree len = a->length_tree(gogo, expr_tree);
- len = fold_convert_loc(this->location().gcc_location(), int_type_tree,
- len);
+ go_assert(this->expr_->is_variable());
+
+ Runtime::Function code;
if (e->integer_type()->is_byte())
- {
- static tree byte_array_to_string_fndecl;
- ret = Gogo::call_builtin(&byte_array_to_string_fndecl,
- this->location(),
- "__go_byte_array_to_string",
- 2,
- type_tree,
- const_ptr_type_node,
- valptr,
- int_type_tree,
- len);
- }
+ code = Runtime::BYTE_ARRAY_TO_STRING;
else
- {
- go_assert(e->integer_type()->is_rune());
- static tree int_array_to_string_fndecl;
- ret = Gogo::call_builtin(&int_array_to_string_fndecl,
- this->location(),
- "__go_int_array_to_string",
- 2,
- type_tree,
- const_ptr_type_node,
- valptr,
- int_type_tree,
- len);
- }
+ {
+ go_assert(e->integer_type()->is_rune());
+ code = Runtime::INT_ARRAY_TO_STRING;
+ }
+ Expression* valptr = a->get_value_pointer(gogo, this->expr_);
+ Expression* len = a->get_length(gogo, this->expr_);
+ Expression* a2s_expr = Runtime::make_call(code, location, 2, valptr, len);
+ ret = a2s_expr->get_tree(context);
}
else if (type->is_slice_type() && expr_type->is_string_type())
{
@@ -6595,6 +6594,7 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
{
std::swap(left_type, right_type);
std::swap(left_tree, right_tree);
+ std::swap(left_expr, right_expr);
}
if (right_type->is_nil_type())
@@ -6603,7 +6603,8 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
&& left_type->array_type()->length() == NULL)
{
Array_type* at = left_type->array_type();
- left_tree = at->value_pointer_tree(context->gogo(), left_tree);
+ left_expr = at->get_value_pointer(context->gogo(), left_expr);
+ left_tree = left_expr->get_tree(context);
right_tree = fold_convert(TREE_TYPE(left_tree), null_pointer_node);
}
else if (left_type->interface_type() != NULL)
@@ -7037,6 +7038,9 @@ class Builtin_call_expression : public Call_expression
Expression*
do_lower(Gogo*, Named_object*, Statement_inserter*, int);
+ Expression*
+ do_flatten(Gogo*, Named_object*, Statement_inserter*);
+
bool
do_is_constant() const;
@@ -7367,6 +7371,36 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
return this;
}
+// Flatten a builtin call expression. This turns the arguments of copy and
+// append into temporary expressions.
+
+Expression*
+Builtin_call_expression::do_flatten(Gogo*, Named_object*,
+ Statement_inserter* inserter)
+{
+ if (this->code_ == BUILTIN_APPEND
+ || this->code_ == BUILTIN_COPY)
+ {
+ Location loc = this->location();
+ Type* at = this->args()->front()->type();
+ for (Expression_list::iterator pa = this->args()->begin();
+ pa != this->args()->end();
+ ++pa)
+ {
+ if ((*pa)->is_nil_expression())
+ *pa = Expression::make_slice_composite_literal(at, NULL, loc);
+ if (!(*pa)->is_variable())
+ {
+ Temporary_statement* temp =
+ Statement::make_temporary(NULL, *pa, loc);
+ inserter->insert(temp);
+ *pa = Expression::make_temporary_reference(temp, loc);
+ }
+ }
+ }
+ return this;
+}
+
// Lower a make expression.
Expression*
@@ -8503,7 +8537,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
return error_mark_node;
}
this->seen_ = true;
- val_tree = arg_type->array_type()->length_tree(gogo, arg_tree);
+ Expression* len = arg_type->array_type()->get_length(gogo, arg);
+ val_tree = len->get_tree(context);
this->seen_ = false;
}
else if (arg_type->map_type() != NULL)
@@ -8543,8 +8578,9 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
return error_mark_node;
}
this->seen_ = true;
- val_tree = arg_type->array_type()->capacity_tree(gogo,
- arg_tree);
+ Expression* cap =
+ arg_type->array_type()->get_capacity(gogo, arg);
+ val_tree = cap->get_tree(context);
this->seen_ = false;
}
else if (arg_type->channel_type() != NULL)
@@ -8848,9 +8884,11 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
Type* arg1_type = arg1->type();
Array_type* at = arg1_type->array_type();
- arg1_tree = save_expr(arg1_tree);
- tree arg1_val = at->value_pointer_tree(gogo, arg1_tree);
- tree arg1_len = at->length_tree(gogo, arg1_tree);
+ go_assert(arg1->is_variable());
+ Expression* arg1_valptr = at->get_value_pointer(gogo, arg1);
+ Expression* arg1_len_expr = at->get_length(gogo, arg1);
+ tree arg1_val = arg1_valptr->get_tree(context);
+ tree arg1_len = arg1_len_expr->get_tree(context);
if (arg1_val == error_mark_node || arg1_len == error_mark_node)
return error_mark_node;
@@ -8860,9 +8898,11 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
if (arg2_type->is_slice_type())
{
at = arg2_type->array_type();
- arg2_tree = save_expr(arg2_tree);
- arg2_val = at->value_pointer_tree(gogo, arg2_tree);
- arg2_len = at->length_tree(gogo, arg2_tree);
+ go_assert(arg2->is_variable());
+ Expression* arg2_valptr = at->get_value_pointer(gogo, arg2);
+ Expression* arg2_len_expr = at->get_length(gogo, arg2);
+ arg2_val = arg2_valptr->get_tree(context);
+ arg2_len = arg2_len_expr->get_tree(context);
}
else
{
@@ -8950,23 +8990,15 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
}
else
{
- arg2_tree = Expression::convert_for_assignment(context, at,
- arg2->type(),
- arg2_tree,
- location);
- if (arg2_tree == error_mark_node)
+ go_assert(arg2->is_variable());
+ arg2_val =
+ at->get_value_pointer(gogo, arg2)->get_tree(context);
+ arg2_len = at->get_length(gogo, arg2)->get_tree(context);
+ Btype* element_btype = element_type->get_backend(gogo);
+ tree element_type_tree = type_to_tree(element_btype);
+ if (element_type_tree == error_mark_node)
return error_mark_node;
-
- arg2_tree = save_expr(arg2_tree);
-
- arg2_val = at->value_pointer_tree(gogo, arg2_tree);
- arg2_len = at->length_tree(gogo, arg2_tree);
-
- Btype* element_btype = element_type->get_backend(gogo);
- tree element_type_tree = type_to_tree(element_btype);
- if (element_type_tree == error_mark_node)
- return error_mark_node;
- element_size = TYPE_SIZE_UNIT(element_type_tree);
+ element_size = TYPE_SIZE_UNIT(element_type_tree);
}
arg2_val = fold_convert_loc(location.gcc_location(), ptr_type_node,
@@ -10371,6 +10403,9 @@ class Array_index_expression : public Expression
do_check_types(Gogo*);
Expression*
+ do_flatten(Gogo*, Named_object*, Statement_inserter*);
+
+ Expression*
do_copy()
{
return Expression::make_array_index(this->array_->copy(),
@@ -10611,6 +10646,22 @@ Array_index_expression::do_check_types(Gogo*)
}
}
+// Flatten array indexing by using a temporary variable for slices.
+
+Expression*
+Array_index_expression::do_flatten(Gogo*, Named_object*,
+ Statement_inserter* inserter)
+{
+ Location loc = this->location();
+ if (this->array_->type()->is_slice_type() && !this->array_->is_variable())
+ {
+ Temporary_statement* temp = Statement::make_temporary(NULL, this->array_, loc);
+ inserter->insert(temp);
+ this->array_ = Expression::make_temporary_reference(temp, loc);
+ }
+ return this;
+}
+
// Return whether this expression is addressable.
bool
@@ -10643,22 +10694,17 @@ Array_index_expression::do_get_tree(Translate_context* context)
go_assert(this->array_->type()->is_error());
return error_mark_node;
}
+ go_assert(!array_type->is_slice_type() || this->array_->is_variable());
tree type_tree = type_to_tree(array_type->get_backend(gogo));
if (type_tree == error_mark_node)
return error_mark_node;
- tree array_tree = this->array_->get_tree(context);
- if (array_tree == error_mark_node)
- return error_mark_node;
-
- if (array_type->length() == NULL && !DECL_P(array_tree))
- array_tree = save_expr(array_tree);
-
tree length_tree = NULL_TREE;
if (this->end_ == NULL || this->end_->is_nil_expression())
{
- length_tree = array_type->length_tree(gogo, array_tree);
+ Expression* len = array_type->get_length(gogo, this->array_);
+ length_tree = len->get_tree(context);
if (length_tree == error_mark_node)
return error_mark_node;
length_tree = save_expr(length_tree);
@@ -10667,7 +10713,8 @@ Array_index_expression::do_get_tree(Translate_context* context)
tree capacity_tree = NULL_TREE;
if (this->end_ != NULL)
{
- capacity_tree = array_type->capacity_tree(gogo, array_tree);
+ Expression* cap = array_type->get_capacity(gogo, this->array_);
+ capacity_tree = cap->get_tree(context);
if (capacity_tree == error_mark_node)
return error_mark_node;
capacity_tree = save_expr(capacity_tree);
@@ -10732,13 +10779,18 @@ Array_index_expression::do_get_tree(Translate_context* context)
if (array_type->length() != NULL)
{
// Fixed array.
+ tree array_tree = this->array_->get_tree(context);
+ if (array_tree == error_mark_node)
+ return error_mark_node;
return build4(ARRAY_REF, TREE_TYPE(type_tree), array_tree,
start_tree, NULL_TREE, NULL_TREE);
}
else
{
// Open array.
- tree values = array_type->value_pointer_tree(gogo, array_tree);
+ Expression* valptr =
+ array_type->get_value_pointer(gogo, this->array_);
+ tree values = valptr->get_tree(context);
Type* element_type = array_type->element_type();
Btype* belement_type = element_type->get_backend(gogo);
tree element_type_tree = type_to_tree(belement_type);
@@ -10820,7 +10872,8 @@ Array_index_expression::do_get_tree(Translate_context* context)
start_tree),
element_size);
- tree value_pointer = array_type->value_pointer_tree(gogo, array_tree);
+ Expression* valptr = array_type->get_value_pointer(gogo, this->array_);
+ tree value_pointer = valptr->get_tree(context);
if (value_pointer == error_mark_node)
return error_mark_node;
@@ -14133,6 +14186,22 @@ Expression::is_nonconstant_composite_literal() const
}
}
+// Return true if this is a variable or temporary_variable.
+
+bool
+Expression::is_variable() const
+{
+ switch (this->classification_)
+ {
+ case EXPRESSION_VAR_REFERENCE:
+ case EXPRESSION_TEMPORARY_REFERENCE:
+ case EXPRESSION_SET_AND_USE_TEMPORARY:
+ return true;
+ default:
+ return false;
+ }
+}
+
// Return true if this is a reference to a local variable.
bool
@@ -14574,6 +14643,117 @@ Expression::make_type_info(Type* type, Type_info type_info)
return new Type_info_expression(type, type_info);
}
+// An expression that evaluates to some characteristic of a slice.
+// This is used when indexing, bound-checking, or nil checking a slice.
+
+class Slice_info_expression : public Expression
+{
+ public:
+ Slice_info_expression(Expression* slice, Slice_info slice_info,
+ Location location)
+ : Expression(EXPRESSION_SLICE_INFO, location),
+ slice_(slice), slice_info_(slice_info)
+ { }
+
+ protected:
+ Type*
+ do_type();
+
+ void
+ do_determine_type(const Type_context*)
+ { }
+
+ Expression*
+ do_copy()
+ {
+ return new Slice_info_expression(this->slice_->copy(), this->slice_info_,
+ this->location());
+ }
+
+ tree
+ do_get_tree(Translate_context* context);
+
+ void
+ do_dump_expression(Ast_dump_context*) const;
+
+ void
+ do_issue_nil_check()
+ { this->slice_->issue_nil_check(); }
+
+ private:
+ // The slice for which we are getting information.
+ Expression* slice_;
+ // What information we want.
+ Slice_info slice_info_;
+};
+
+// Return the type of the slice info.
+
+Type*
+Slice_info_expression::do_type()
+{
+ switch (this->slice_info_)
+ {
+ case SLICE_INFO_VALUE_POINTER:
+ return Type::make_pointer_type(
+ this->slice_->type()->array_type()->element_type());
+ case SLICE_INFO_LENGTH:
+ case SLICE_INFO_CAPACITY:
+ return Type::lookup_integer_type("int");
+ default:
+ go_unreachable();
+ }
+}
+
+// Return slice information in GENERIC.
+
+tree
+Slice_info_expression::do_get_tree(Translate_context* context)
+{
+ Gogo* gogo = context->gogo();
+
+ Bexpression* bslice = tree_to_expr(this->slice_->get_tree(context));
+ Bexpression* ret;
+ switch (this->slice_info_)
+ {
+ case SLICE_INFO_VALUE_POINTER:
+ case SLICE_INFO_LENGTH:
+ case SLICE_INFO_CAPACITY:
+ ret = gogo->backend()->struct_field_expression(bslice, this->slice_info_,
+ this->location());
+ break;
+ default:
+ go_unreachable();
+ }
+ return expr_to_tree(ret);
+}
+
+// Dump ast representation for a type info expression.
+
+void
+Slice_info_expression::do_dump_expression(
+ Ast_dump_context* ast_dump_context) const
+{
+ ast_dump_context->ostream() << "sliceinfo(";
+ this->slice_->dump_expression(ast_dump_context);
+ ast_dump_context->ostream() << ",";
+ ast_dump_context->ostream() <<
+ (this->slice_info_ == SLICE_INFO_VALUE_POINTER ? "values"
+ : this->slice_info_ == SLICE_INFO_LENGTH ? "length"
+ : this->slice_info_ == SLICE_INFO_CAPACITY ? "capacity "
+ : "unknown");
+ ast_dump_context->ostream() << ")";
+}
+
+// Make a slice info expression.
+
+Expression*
+Expression::make_slice_info(Expression* slice, Slice_info slice_info,
+ Location location)
+{
+ return new Slice_info_expression(slice, slice_info, location);
+}
+
// An expression which evaluates to the offset of a field within a
// struct. This, like Type_info_expression, q.v., is only used to
// initialize fields of a type descriptor.
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index e447418b949e..abebbd16961b 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -102,6 +102,7 @@ class Expression
EXPRESSION_RECEIVE,
EXPRESSION_TYPE_DESCRIPTOR,
EXPRESSION_TYPE_INFO,
+ EXPRESSION_SLICE_INFO,
EXPRESSION_STRUCT_FIELD_OFFSET,
EXPRESSION_MAP_DESCRIPTOR,
EXPRESSION_LABEL_ADDR
@@ -339,6 +340,22 @@ class Expression
static Expression*
make_type_info(Type* type, Type_info);
+ // Make an expression that evaluates to some characteristic of a
+ // slice. For simplicity, the enum values must match the field indexes
+ // in the underlying struct.
+ enum Slice_info
+ {
+ // The underlying data of the slice.
+ SLICE_INFO_VALUE_POINTER,
+ // The length of the slice.
+ SLICE_INFO_LENGTH,
+ // The capacity of the slice.
+ SLICE_INFO_CAPACITY
+ };
+
+ static Expression*
+ make_slice_info(Expression* slice, Slice_info, Location);
+
// Make an expression which evaluates to the offset of a field in a
// struct. This is only used for type descriptors, so there is no
// location parameter.
@@ -544,6 +561,10 @@ class Expression
bool
is_nonconstant_composite_literal() const;
+ // Return true if this is a variable or temporary variable.
+ bool
+ is_variable() const;
+
// Return true if this is a reference to a local variable.
bool
is_local_variable() const;
@@ -575,6 +596,18 @@ class Expression
int iota_value)
{ return this->do_lower(gogo, function, inserter, iota_value); }
+ // Flatten an expression. This is called after order_evaluation.
+ // FUNCTION is the function we are in; it will be NULL for an
+ // expression initializing a global variable. INSERTER may be used
+ // to insert statements before the statement or initializer
+ // containing this expression; it is normally used to create
+ // temporary variables. This function must resolve expressions
+ // which could not be fully parsed into their final form. It
+ // returns the same Expression or a new one.
+ Expression*
+ flatten(Gogo* gogo, Named_object* function, Statement_inserter* inserter)
+ { return this->do_flatten(gogo, function, inserter); }
+
// Determine the real type of an expression with abstract integer,
// floating point, or complex type. TYPE_CONTEXT describes the
// expected type.
@@ -698,6 +731,12 @@ class Expression
do_lower(Gogo*, Named_object*, Statement_inserter*, int)
{ return this; }
+ // Return a flattened expression.
+ virtual Expression*
+ do_flatten(Gogo*, Named_object*, Statement_inserter*)
+ { return this; }
+
+
// Return whether this is a constant expression.
virtual bool
do_is_constant() const
diff --git a/gcc/go/gofrontend/go.cc b/gcc/go/gofrontend/go.cc
index 55b4dca85792..26e83a1db64f 100644
--- a/gcc/go/gofrontend/go.cc
+++ b/gcc/go/gofrontend/go.cc
@@ -119,12 +119,15 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
// Use temporary variables to force order of evaluation.
::gogo->order_evaluations();
+ // Flatten the parse tree.
+ ::gogo->flatten();
+
// Build thunks for functions which call recover.
::gogo->build_recover_thunks();
// Convert complicated go and defer statements into simpler ones.
::gogo->simplify_thunk_statements();
-
+
// Dump ast, use filename[0] as the base name
::gogo->dump_ast(filenames[0]);
}
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index e46bf9c4193d..6ecc6cd0f0f4 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -2703,6 +2703,178 @@ Gogo::order_evaluations()
this->traverse(&order_eval);
}
+// Traversal to flatten parse tree after order of evaluation rules are applied.
+
+class Flatten : public Traverse
+{
+ public:
+ Flatten(Gogo* gogo, Named_object* function)
+ : Traverse(traverse_variables
+ | traverse_functions
+ | traverse_statements
+ | traverse_expressions),
+ gogo_(gogo), function_(function), inserter_()
+ { }
+
+ void
+ set_inserter(const Statement_inserter* inserter)
+ { this->inserter_ = *inserter; }
+
+ int
+ variable(Named_object*);
+
+ int
+ function(Named_object*);
+
+ int
+ statement(Block*, size_t* pindex, Statement*);
+
+ int
+ expression(Expression**);
+
+ private:
+ // General IR.
+ Gogo* gogo_;
+ // The function we are traversing.
+ Named_object* function_;
+ // Current statement inserter for use by expressions.
+ Statement_inserter inserter_;
+};
+
+// Flatten variables.
+
+int
+Flatten::variable(Named_object* no)
+{
+ if (!no->is_variable())
+ return TRAVERSE_CONTINUE;
+
+ if (no->is_variable() && no->var_value()->is_global())
+ {
+ // Global variables can have loops in their initialization
+ // expressions. This is handled in flatten_init_expression.
+ no->var_value()->flatten_init_expression(this->gogo_, this->function_,
+ &this->inserter_);
+ return TRAVERSE_CONTINUE;
+ }
+
+ go_assert(!no->var_value()->has_pre_init());
+
+ return TRAVERSE_SKIP_COMPONENTS;
+}
+
+// Flatten the body of a function. Record the function while flattening it,
+// so that we can pass it down when flattening an expression.
+
+int
+Flatten::function(Named_object* no)
+{
+ go_assert(this->function_ == NULL);
+ this->function_ = no;
+ int t = no->func_value()->traverse(this);
+ this->function_ = NULL;
+
+ if (t == TRAVERSE_EXIT)
+ return t;
+ return TRAVERSE_SKIP_COMPONENTS;
+}
+
+// Flatten statement parse trees.
+
+int
+Flatten::statement(Block* block, size_t* pindex, Statement* sorig)
+{
+ // Because we explicitly traverse the statement's contents
+ // ourselves, we want to skip block statements here. There is
+ // nothing to flatten in a block statement.
+ if (sorig->is_block_statement())
+ return TRAVERSE_CONTINUE;
+
+ Statement_inserter hold_inserter(this->inserter_);
+ this->inserter_ = Statement_inserter(block, pindex);
+
+ // Flatten the expressions first.
+ int t = sorig->traverse_contents(this);
+ if (t == TRAVERSE_EXIT)
+ {
+ this->inserter_ = hold_inserter;
+ return t;
+ }
+
+ // Keep flattening until nothing changes.
+ Statement* s = sorig;
+ while (true)
+ {
+ Statement* snew = s->flatten(this->gogo_, this->function_, block,
+ &this->inserter_);
+ if (snew == s)
+ break;
+ s = snew;
+ t = s->traverse_contents(this);
+ if (t == TRAVERSE_EXIT)
+ {
+ this->inserter_ = hold_inserter;
+ return t;
+ }
+ }
+
+ if (s != sorig)
+ block->replace_statement(*pindex, s);
+
+ this->inserter_ = hold_inserter;
+ return TRAVERSE_SKIP_COMPONENTS;
+}
+
+// Flatten expression parse trees.
+
+int
+Flatten::expression(Expression** pexpr)
+{
+ // Keep flattening until nothing changes.
+ while (true)
+ {
+ Expression* e = *pexpr;
+ if (e->traverse_subexpressions(this) == TRAVERSE_EXIT)
+ return TRAVERSE_EXIT;
+
+ Expression* enew = e->flatten(this->gogo_, this->function_,
+ &this->inserter_);
+ if (enew == e)
+ break;
+ *pexpr = enew;
+ }
+ return TRAVERSE_SKIP_COMPONENTS;
+}
+
+// Flatten a block.
+
+void
+Gogo::flatten_block(Named_object* function, Block* block)
+{
+ Flatten flatten(this, function);
+ block->traverse(&flatten);
+}
+
+// Flatten an expression. INSERTER may be NULL, in which case the
+// expression had better not need to create any temporaries.
+
+void
+Gogo::flatten_expression(Named_object* function, Statement_inserter* inserter,
+ Expression** pexpr)
+{
+ Flatten flatten(this, function);
+ if (inserter != NULL)
+ flatten.set_inserter(inserter);
+ flatten.expression(pexpr);
+}
+
+void
+Gogo::flatten()
+{
+ Flatten flatten(this, NULL);
+ this->traverse(&flatten);
+}
+
// Traversal to convert calls to the predeclared recover function to
// pass in an argument indicating whether it can recover from a panic
// or not.
@@ -4286,10 +4458,11 @@ Variable::Variable(Type* type, Expression* init, bool is_global,
backend_(NULL), is_global_(is_global), is_parameter_(is_parameter),
is_receiver_(is_receiver), is_varargs_parameter_(false), is_used_(false),
is_address_taken_(false), is_non_escaping_address_taken_(false),
- seen_(false), init_is_lowered_(false), type_from_init_tuple_(false),
- type_from_range_index_(false), type_from_range_value_(false),
- type_from_chan_element_(false), is_type_switch_var_(false),
- determined_type_(false), in_unique_section_(false)
+ seen_(false), init_is_lowered_(false), init_is_flattened_(false),
+ type_from_init_tuple_(false), type_from_range_index_(false),
+ type_from_range_value_(false), type_from_chan_element_(false),
+ is_type_switch_var_(false), determined_type_(false),
+ in_unique_section_(false)
{
go_assert(type != NULL || init != NULL);
go_assert(!is_parameter || init == NULL);
@@ -4351,6 +4524,40 @@ Variable::lower_init_expression(Gogo* gogo, Named_object* function,
}
}
+// Flatten the initialization expression after ordering evaluations.
+
+void
+Variable::flatten_init_expression(Gogo* gogo, Named_object* function,
+ Statement_inserter* inserter)
+{
+ Named_object* dep = gogo->var_depends_on(this);
+ if (dep != NULL && dep->is_variable())
+ dep->var_value()->flatten_init_expression(gogo, function, inserter);
+
+ if (this->init_ != NULL && !this->init_is_flattened_)
+ {
+ if (this->seen_)
+ {
+ // We will give an error elsewhere, this is just to prevent
+ // an infinite loop.
+ return;
+ }
+ this->seen_ = true;
+
+ Statement_inserter global_inserter;
+ if (this->is_global_)
+ {
+ global_inserter = Statement_inserter(gogo, this);
+ inserter = &global_inserter;
+ }
+
+ gogo->flatten_expression(function, inserter, &this->init_);
+
+ this->seen_ = false;
+ this->init_is_flattened_ = true;
+ }
+}
+
// Get the preinit block.
Block*
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index a9a56815c178..3f2808781b74 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -487,6 +487,14 @@ class Gogo
void
lower_constant(Named_object*);
+ // Flatten all the statements in a block.
+ void
+ flatten_block(Named_object* function, Block*);
+
+ // Flatten an expression.
+ void
+ flatten_expression(Named_object* function, Statement_inserter*, Expression**);
+
// Create all necessary function descriptors.
void
create_function_descriptors();
@@ -531,6 +539,10 @@ class Gogo
void
order_evaluations();
+ // Flatten parse tree.
+ void
+ flatten();
+
// Build thunks for functions which call recover.
void
build_recover_thunks();
@@ -1447,6 +1459,10 @@ class Variable
void
lower_init_expression(Gogo*, Named_object*, Statement_inserter*);
+ // Flatten the initialization expression after ordering evaluations.
+ void
+ flatten_init_expression(Gogo*, Named_object*, Statement_inserter*);
+
// A special case: the init value is used only to determine the
// type. This is used if the variable is defined using := with the
// comma-ok form of a map index or a receive expression. The init
@@ -1580,6 +1596,8 @@ class Variable
bool seen_ : 1;
// True if we have lowered the initialization expression.
bool init_is_lowered_ : 1;
+ // True if we have flattened the initialization expression.
+ bool init_is_flattened_ : 1;
// True if init is a tuple used to set the type.
bool type_from_init_tuple_ : 1;
// True if init is a range clause and the type is the index type.
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 3a0bc3b9739e..d195ab9845a1 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -246,6 +246,16 @@ Variable_declaration_statement::do_lower(Gogo* gogo, Named_object* function,
return this;
}
+// Flatten the variable's initialization expression.
+
+Statement*
+Variable_declaration_statement::do_flatten(Gogo* gogo, Named_object* function,
+ Block*, Statement_inserter* inserter)
+{
+ this->var_->var_value()->flatten_init_expression(gogo, function, inserter);
+ return this;
+}
+
// Convert a variable declaration to the backend representation.
Bstatement*
@@ -2461,6 +2471,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
gogo->add_block(b, location);
gogo->lower_block(function, b);
+ gogo->flatten_block(function, b);
// We already ran the determine_types pass, so we need to run it
// just for the call statement now. The other types are known.
diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h
index b128fa0a8eb1..7d9bcfde8b70 100644
--- a/gcc/go/gofrontend/statements.h
+++ b/gcc/go/gofrontend/statements.h
@@ -306,6 +306,16 @@ class Statement
Statement_inserter* inserter)
{ return this->do_lower(gogo, function, block, inserter); }
+ // Flatten a statement. This is called immediately after the order of
+ // evaluation rules are applied to statements. It returns the same
+ // Statement or a new one. FUNCTION is the function containing this
+ // statement. BLOCK is the block containing this statement.
+ // INSERTER can be used to insert new statements before this one.
+ Statement*
+ flatten(Gogo* gogo, Named_object* function, Block* block,
+ Statement_inserter* inserter)
+ { return this->do_flatten(gogo, function, block, inserter); }
+
// Set type information for unnamed constants.
void
determine_types();
@@ -412,6 +422,12 @@ class Statement
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*)
{ return this; }
+ // Implemented by the child class: lower this statement to a simpler
+ // one.
+ virtual Statement*
+ do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*)
+ { return this; }
+
// Implemented by child class: set type information for unnamed
// constants. Any statement which includes an expression needs to
// implement this.
@@ -583,6 +599,9 @@ class Variable_declaration_statement : public Statement
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
+ Statement*
+ do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
+
Bstatement*
do_get_backend(Translate_context*);
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index d079565d18bc..2935523dd2aa 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -6000,84 +6000,53 @@ Array_type::finish_backend_element(Gogo* gogo)
}
}
-// Return a tree for a pointer to the values in ARRAY.
+// Return an expression for a pointer to the values in ARRAY.
-tree
-Array_type::value_pointer_tree(Gogo*, tree array) const
+Expression*
+Array_type::get_value_pointer(Gogo*, Expression* array) const
{
- tree ret;
if (this->length() != NULL)
{
// Fixed array.
- ret = fold_convert(build_pointer_type(TREE_TYPE(TREE_TYPE(array))),
- build_fold_addr_expr(array));
+ go_assert(array->type()->array_type() != NULL);
+ Type* etype = array->type()->array_type()->element_type();
+ array = Expression::make_unary(OPERATOR_AND, array, array->location());
+ return Expression::make_cast(Type::make_pointer_type(etype), array,
+ array->location());
}
- else
- {
- // Open array.
- tree field = TYPE_FIELDS(TREE_TYPE(array));
- go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)),
- "__values") == 0);
- ret = fold_build3(COMPONENT_REF, TREE_TYPE(field), array, field,
- NULL_TREE);
- }
- if (TREE_CONSTANT(array))
- TREE_CONSTANT(ret) = 1;
- return ret;
+
+ // Open array.
+ return Expression::make_slice_info(array,
+ Expression::SLICE_INFO_VALUE_POINTER,
+ array->location());
}
-// Return a tree for the length of the array ARRAY which has this
+// Return an expression for the length of the array ARRAY which has this
// type.
-tree
-Array_type::length_tree(Gogo* gogo, tree array)
+Expression*
+Array_type::get_length(Gogo*, Expression* array) const
{
if (this->length_ != NULL)
- {
- if (TREE_CODE(array) == SAVE_EXPR)
- return this->get_length_tree(gogo);
- else
- {
- tree len = this->get_length_tree(gogo);
- return omit_one_operand(TREE_TYPE(len), len, array);
- }
- }
+ return this->length_;
// This is an open array. We need to read the length field.
-
- tree type = TREE_TYPE(array);
- go_assert(TREE_CODE(type) == RECORD_TYPE);
-
- tree field = DECL_CHAIN(TYPE_FIELDS(type));
- go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__count") == 0);
-
- tree ret = build3(COMPONENT_REF, TREE_TYPE(field), array, field, NULL_TREE);
- if (TREE_CONSTANT(array))
- TREE_CONSTANT(ret) = 1;
- return ret;
+ return Expression::make_slice_info(array, Expression::SLICE_INFO_LENGTH,
+ array->location());
}
-// Return a tree for the capacity of the array ARRAY which has this
+// Return an expression for the capacity of the array ARRAY which has this
// type.
-tree
-Array_type::capacity_tree(Gogo* gogo, tree array)
+Expression*
+Array_type::get_capacity(Gogo*, Expression* array) const
{
if (this->length_ != NULL)
- {
- tree len = this->get_length_tree(gogo);
- return omit_one_operand(TREE_TYPE(len), len, array);
- }
+ return this->length_;
// This is an open array. We need to read the capacity field.
-
- tree type = TREE_TYPE(array);
- go_assert(TREE_CODE(type) == RECORD_TYPE);
-
- tree field = DECL_CHAIN(DECL_CHAIN(TYPE_FIELDS(type)));
- go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__capacity") == 0);
-
- return build3(COMPONENT_REF, TREE_TYPE(field), array, field, NULL_TREE);
+ return Expression::make_slice_info(array, Expression::SLICE_INFO_CAPACITY,
+ array->location());
}
// Export.
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 9f9659161319..980436a10379 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -2312,17 +2312,17 @@ class Array_type : public Type
array_has_hidden_fields(const Named_type* within, std::string* reason) const
{ return this->element_type_->has_hidden_fields(within, reason); }
- // Return a tree for the pointer to the values in an array.
- tree
- value_pointer_tree(Gogo*, tree array) const;
+ // Return an expression for the pointer to the values in an array.
+ Expression*
+ get_value_pointer(Gogo*, Expression* array) const;
- // Return a tree for the length of an array with this type.
- tree
- length_tree(Gogo*, tree array);
+ // Return an expression for the length of an array with this type.
+ Expression*
+ get_length(Gogo*, Expression* array) const;
- // Return a tree for the capacity of an array with this type.
- tree
- capacity_tree(Gogo*, tree array);
+ // Return an expression for the capacity of an array with this type.
+ Expression*
+ get_capacity(Gogo*, Expression* array) const;
// Import an array type.
static Array_type*
diff --git a/gcc/hash-table.h b/gcc/hash-table.h
index 2b04067f74a6..034385c19f27 100644
--- a/gcc/hash-table.h
+++ b/gcc/hash-table.h
@@ -1050,10 +1050,7 @@ hash_table <Descriptor, Allocator>::end ()
/* Iterate through the elements of hash_table HTAB,
using hash_table <....>::iterator ITER,
- storing each element in RESULT, which is of type TYPE.
-
- This macro has this form for compatibility with the
- FOR_EACH_HTAB_ELEMENT currently defined in tree-flow.h. */
+ storing each element in RESULT, which is of type TYPE. */
#define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \
for ((ITER) = (HTAB).begin (); \
diff --git a/gcc/hw-doloop.c b/gcc/hw-doloop.c
index ab4899db6322..cc8f9b775052 100644
--- a/gcc/hw-doloop.c
+++ b/gcc/hw-doloop.c
@@ -661,6 +661,7 @@ reorg_loops (bool do_reorder, struct hw_doloop_hooks *hooks)
}
free_loops (loops);
+ bitmap_obstack_release (&loop_stack);
if (dump_file)
print_rtl (dump_file, get_insns ());
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 398453547318..51293651e9cc 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -118,7 +118,7 @@ count_bb_insns (const_basic_block bb)
while (1)
{
- if (CALL_P (insn) || NONJUMP_INSN_P (insn))
+ if (active_insn_p (insn) && !JUMP_P (insn))
count++;
if (insn == BB_END (bb))
@@ -522,7 +522,10 @@ cond_exec_process_if_block (ce_if_block * ce_info,
n_insns -= 2 * n_matching;
}
- if (then_start && else_start)
+ if (then_start
+ && else_start
+ && then_n_insns > n_matching
+ && else_n_insns > n_matching)
{
int longest_match = MIN (then_n_insns - n_matching,
else_n_insns - n_matching);
@@ -3153,6 +3156,20 @@ merge_if_block (struct ce_if_block * ce_info)
if (then_bb)
{
+ /* If THEN_BB has no successors, then there's a BARRIER after it.
+ If COMBO_BB has more than one successor (THEN_BB), then that BARRIER
+ is no longer needed, and in fact it is incorrect to leave it in
+ the insn stream. */
+ if (EDGE_COUNT (then_bb->succs) == 0
+ && EDGE_COUNT (combo_bb->succs) > 1)
+ {
+ rtx end = NEXT_INSN (BB_END (then_bb));
+ while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end))
+ end = NEXT_INSN (end);
+
+ if (end && BARRIER_P (end))
+ delete_insn (end);
+ }
merge_blocks (combo_bb, then_bb);
num_true_changes++;
}
@@ -3162,6 +3179,20 @@ merge_if_block (struct ce_if_block * ce_info)
get their addresses taken. */
if (else_bb)
{
+ /* If ELSE_BB has no successors, then there's a BARRIER after it.
+ If COMBO_BB has more than one successor (ELSE_BB), then that BARRIER
+ is no longer needed, and in fact it is incorrect to leave it in
+ the insn stream. */
+ if (EDGE_COUNT (else_bb->succs) == 0
+ && EDGE_COUNT (combo_bb->succs) > 1)
+ {
+ rtx end = NEXT_INSN (BB_END (else_bb));
+ while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end))
+ end = NEXT_INSN (end);
+
+ if (end && BARRIER_P (end))
+ delete_insn (end);
+ }
merge_blocks (combo_bb, else_bb);
num_true_changes++;
}
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 63c50370a0a6..a6a44e6d81ac 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -2281,7 +2281,7 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node,
{
bool agg_contents = ie->indirect_info->agg_contents;
bool polymorphic = ie->indirect_info->polymorphic;
- bool param_index = ie->indirect_info->param_index;
+ int param_index = ie->indirect_info->param_index;
struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target);
found = true;
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index ff465f9e963f..a9efe584187e 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -542,7 +542,7 @@ method_class_type (tree t)
void
build_type_inheritance_graph (void)
{
- struct cgraph_node *n;
+ struct symtab_node *n;
FILE *inheritance_dump_file;
int flags;
@@ -554,10 +554,37 @@ build_type_inheritance_graph (void)
/* We reconstruct the graph starting of types of all methods seen in the
the unit. */
- FOR_EACH_FUNCTION (n)
- if (DECL_VIRTUAL_P (n->decl)
+ FOR_EACH_SYMBOL (n)
+ if (is_a <cgraph_node> (n)
+ && DECL_VIRTUAL_P (n->decl)
&& symtab_real_symbol_p (n))
get_odr_type (method_class_type (TREE_TYPE (n->decl)), true);
+
+ /* Look also for virtual tables of types that do not define any methods.
+
+ We need it in a case where class B has virtual base of class A
+ re-defining its virtual method and there is class C with no virtual
+ methods with B as virtual base.
+
+ Here we output B's virtual method in two variant - for non-virtual
+ and virtual inheritance. B's virtual table has non-virtual version,
+ while C's has virtual.
+
+ For this reason we need to know about C in order to include both
+ variants of B. More correctly, record_target_from_binfo should
+ add both variants of the method when walking B, but we have no
+ link in between them.
+
+ We rely on fact that either the method is exported and thus we
+ assume it is called externally or C is in anonymous namespace and
+ thus we will see the vtable. */
+
+ else if (is_a <varpool_node> (n)
+ && DECL_VIRTUAL_P (n->decl)
+ && TREE_CODE (DECL_CONTEXT (n->decl)) == RECORD_TYPE
+ && TYPE_BINFO (DECL_CONTEXT (n->decl))
+ && polymorphic_type_binfo_p (TYPE_BINFO (DECL_CONTEXT (n->decl))))
+ get_odr_type (DECL_CONTEXT (n->decl), true);
if (inheritance_dump_file)
{
dump_type_inheritance_graph (inheritance_dump_file);
@@ -614,10 +641,8 @@ maybe_record_node (vec <cgraph_node *> &nodes,
This match what get_binfo_at_offset does, but with offset
being unknown.
- TYPE_BINFO is binfo holding an virtual table matching
- BINFO's type. In the case of single inheritance, this
- is binfo of BINFO's type ancestor (vtable is shared),
- otherwise it is binfo of BINFO's type.
+ TYPE_BINFOS is a stack of BINFOS of types with defined
+ virtual table seen on way from class type to BINFO.
MATCHED_VTABLES tracks virtual tables we already did lookup
for virtual function in. INSERTED tracks nodes we already
@@ -630,7 +655,7 @@ static void
record_target_from_binfo (vec <cgraph_node *> &nodes,
tree binfo,
tree otr_type,
- tree type_binfo,
+ vec <tree> &type_binfos,
HOST_WIDE_INT otr_token,
tree outer_type,
HOST_WIDE_INT offset,
@@ -642,10 +667,32 @@ record_target_from_binfo (vec <cgraph_node *> &nodes,
int i;
tree base_binfo;
- gcc_checking_assert (BINFO_VTABLE (type_binfo));
+ if (BINFO_VTABLE (binfo))
+ type_binfos.safe_push (binfo);
if (types_same_for_odr (type, outer_type))
{
+ int i;
+ tree type_binfo = NULL;
+
+ /* Lookup BINFO with virtual table. For normal types it is always last
+ binfo on stack. */
+ for (i = type_binfos.length () - 1; i >= 0; i--)
+ if (BINFO_OFFSET (type_binfos[i]) == BINFO_OFFSET (binfo))
+ {
+ type_binfo = type_binfos[i];
+ break;
+ }
+ if (BINFO_VTABLE (binfo))
+ type_binfos.pop ();
+ /* If this is duplicated BINFO for base shared by virtual inheritance,
+ we may not have its associated vtable. This is not a problem, since
+ we will walk it on the other path. */
+ if (!type_binfo)
+ {
+ gcc_assert (BINFO_VIRTUAL_P (binfo));
+ return;
+ }
tree inner_binfo = get_binfo_at_offset (type_binfo,
offset, otr_type);
/* For types in anonymous namespace first check if the respective vtable
@@ -676,12 +723,11 @@ record_target_from_binfo (vec <cgraph_node *> &nodes,
/* Walking bases that have no virtual method is pointless excercise. */
if (polymorphic_type_binfo_p (base_binfo))
record_target_from_binfo (nodes, base_binfo, otr_type,
- /* In the case of single inheritance,
- the virtual table is shared with
- the outer type. */
- BINFO_VTABLE (base_binfo) ? base_binfo : type_binfo,
+ type_binfos,
otr_token, outer_type, offset, inserted,
matched_vtables, anonymous);
+ if (BINFO_VTABLE (binfo))
+ type_binfos.pop ();
}
/* Lookup virtual methods matching OTR_TYPE (with OFFSET and OTR_TOKEN)
@@ -701,11 +747,13 @@ possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes,
{
tree binfo = TYPE_BINFO (type->type);
unsigned int i;
+ vec <tree> type_binfos = vNULL;
- record_target_from_binfo (nodes, binfo, otr_type, binfo, otr_token,
+ record_target_from_binfo (nodes, binfo, otr_type, type_binfos, otr_token,
outer_type, offset,
inserted, matched_vtables,
type->anonymous_namespace);
+ type_binfos.release ();
for (i = 0; i < type->derived_types.length (); i++)
possible_polymorphic_call_targets_1 (nodes, inserted,
matched_vtables,
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 2fb224631287..f39e8c132416 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -2127,8 +2127,11 @@ ipa_analyze_params_uses (struct cgraph_node *node,
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, ddef)
if (!is_gimple_call (USE_STMT (use_p)))
{
- controlled_uses = IPA_UNDESCRIBED_USE;
- break;
+ if (!is_gimple_debug (USE_STMT (use_p)))
+ {
+ controlled_uses = IPA_UNDESCRIBED_USE;
+ break;
+ }
}
else
controlled_uses++;
@@ -3326,6 +3329,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
{
int c;
+ fprintf (f, " ");
ipa_dump_param (f, info, i);
if (ipa_is_param_used (info, i))
fprintf (f, " used");
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index ad51a4746ff9..152fa233e9e7 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,14 @@
+2014-01-09 Richard Biener <rguenther@suse.de>
+
+ * lto.c (gimple_canonical_types_compatible_p): Fix comment.
+
+2014-01-09 Richard Biener <rguenther@suse.de>
+
+ PR lto/45586
+ * lto.c (hash_canonical_type): Do not hash TREE_ADDRESSABLE,
+ TYPE_ALIGN, TYPE_RESTRICT or TYPE_REF_CAN_ALIAS_ALL.
+ (gimple_canonical_types_compatible_p): Do not compare them either.
+
2014-01-02 Richard Sandiford <rdsandiford@googlemail.com>
Update copyright years
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 6abb4f456b4c..8ec4ae095c8e 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -280,8 +280,6 @@ hash_canonical_type (tree type)
only existing types having the same features as the new type will be
checked. */
v = iterative_hash_hashval_t (TREE_CODE (type), 0);
- v = iterative_hash_hashval_t (TREE_ADDRESSABLE (type), v);
- v = iterative_hash_hashval_t (TYPE_ALIGN (type), v);
v = iterative_hash_hashval_t (TYPE_MODE (type), v);
/* Incorporate common features of numerical types. */
@@ -308,9 +306,7 @@ hash_canonical_type (tree type)
pointed to but do not recurse to the pointed-to type. */
if (POINTER_TYPE_P (type))
{
- v = iterative_hash_hashval_t (TYPE_REF_CAN_ALIAS_ALL (type), v);
v = iterative_hash_hashval_t (TYPE_ADDR_SPACE (TREE_TYPE (type)), v);
- v = iterative_hash_hashval_t (TYPE_RESTRICT (type), v);
v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v);
}
@@ -447,9 +443,6 @@ gimple_canonical_types_compatible_p (tree t1, tree t2)
if (TREE_CODE (t1) != TREE_CODE (t2))
return false;
- if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2))
- return false;
-
/* Qualifiers do not matter for canonical type comparison purposes. */
/* Void types and nullptr types are always the same. */
@@ -457,9 +450,8 @@ gimple_canonical_types_compatible_p (tree t1, tree t2)
|| TREE_CODE (t1) == NULLPTR_TYPE)
return true;
- /* Can't be the same type if they have different alignment, or mode. */
- if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2)
- || TYPE_MODE (t1) != TYPE_MODE (t2))
+ /* Can't be the same type if they have different mode. */
+ if (TYPE_MODE (t1) != TYPE_MODE (t2))
return false;
/* Non-aggregate types can be handled cheaply. */
@@ -486,18 +478,10 @@ gimple_canonical_types_compatible_p (tree t1, tree t2)
useless_type_conversion_p would do. */
if (POINTER_TYPE_P (t1))
{
- /* If the two pointers have different ref-all attributes,
- they can't be the same type. */
- if (TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
- return false;
-
if (TYPE_ADDR_SPACE (TREE_TYPE (t1))
!= TYPE_ADDR_SPACE (TREE_TYPE (t2)))
return false;
- if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
- return false;
-
if (TREE_CODE (TREE_TYPE (t1)) != TREE_CODE (TREE_TYPE (t2)))
return false;
}
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index 8d63e97078b9..7ba3ddb66989 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -766,6 +766,9 @@ schedule_reg_moves (partial_schedule_ptr ps)
distance1_uses = distances[1] ? sbitmap_alloc (g->num_nodes) : NULL;
+ if (distance1_uses)
+ bitmap_clear (distance1_uses);
+
/* Every use of the register defined by node may require a different
copy of this register, depending on the time the use is scheduled.
Record which uses require which move results. */
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 5daa28178dad..66686692913d 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -7534,12 +7534,21 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
loadedi = loaded_val;
}
+ fncode = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
+ tree loaddecl = builtin_decl_explicit (fncode);
+ if (loaddecl)
+ initial
+ = fold_convert (TREE_TYPE (TREE_TYPE (iaddr)),
+ build_call_expr (loaddecl, 2, iaddr,
+ build_int_cst (NULL_TREE,
+ MEMMODEL_RELAXED)));
+ else
+ initial = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)), iaddr,
+ build_int_cst (TREE_TYPE (iaddr), 0));
+
initial
- = force_gimple_operand_gsi (&si,
- build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)),
- iaddr,
- build_int_cst (TREE_TYPE (iaddr), 0)),
- true, NULL_TREE, true, GSI_SAME_STMT);
+ = force_gimple_operand_gsi (&si, initial, true, NULL_TREE, true,
+ GSI_SAME_STMT);
/* Move the value to the LOADEDI temporary. */
if (gimple_in_ssa_p (cfun))
@@ -11535,7 +11544,7 @@ simd_clone_adjust (struct cgraph_node *node)
unsigned int alignment = node->simdclone->args[i].alignment;
tree orig_arg = node->simdclone->args[i].orig_arg;
tree def = ssa_default_def (cfun, orig_arg);
- if (!has_zero_uses (def))
+ if (def && !has_zero_uses (def))
{
tree fn = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
gimple_seq seq = NULL;
@@ -11585,7 +11594,7 @@ simd_clone_adjust (struct cgraph_node *node)
tree def = ssa_default_def (cfun, orig_arg);
gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
|| POINTER_TYPE_P (TREE_TYPE (orig_arg)));
- if (!has_zero_uses (def))
+ if (def && !has_zero_uses (def))
{
iter1 = make_ssa_name (orig_arg, NULL);
iter2 = make_ssa_name (orig_arg, NULL);
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 45c728b5506d..fcd2c7216b44 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -6242,7 +6242,7 @@ init_tree_optimization_optabs (tree optnode)
/* If the optabs changed, record it. */
if (memcmp (tmp_optabs, this_target_optabs, sizeof (struct target_optabs)))
- TREE_OPTIMIZATION_OPTABS (optnode) = (unsigned char *) tmp_optabs;
+ TREE_OPTIMIZATION_OPTABS (optnode) = tmp_optabs;
else
{
TREE_OPTIMIZATION_OPTABS (optnode) = NULL;
diff --git a/gcc/params.def b/gcc/params.def
index af89dd9f3881..abfda73ca874 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -1049,7 +1049,37 @@ DEFPARAM (PARAM_MAX_SLSR_CANDIDATE_SCAN,
"strength reduction",
50, 1, 999999)
+DEFPARAM (PARAM_ASAN_STACK,
+ "asan-stack",
+ "Enable asan stack protection",
+ 1, 0, 1)
+
+DEFPARAM (PARAM_ASAN_GLOBALS,
+ "asan-globals",
+ "Enable asan globals protection",
+ 1, 0, 1)
+
+DEFPARAM (PARAM_ASAN_INSTRUMENT_WRITES,
+ "asan-instrument-writes",
+ "Enable asan store operations protection",
+ 1, 0, 1)
+
+DEFPARAM (PARAM_ASAN_INSTRUMENT_READS,
+ "asan-instrument-reads",
+ "Enable asan load operations protection",
+ 1, 0, 1)
+
+DEFPARAM (PARAM_ASAN_MEMINTRIN,
+ "asan-memintrin",
+ "Enable asan builtin functions protection",
+ 1, 0, 1)
+
+DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN,
+ "asan-use-after-return",
+ "Enable asan builtin functions protection",
+ 1, 0, 1)
/*
+
Local variables:
mode:c
End:
diff --git a/gcc/params.h b/gcc/params.h
index 82870585293c..64f3a0fcbae0 100644
--- a/gcc/params.h
+++ b/gcc/params.h
@@ -218,5 +218,17 @@ extern void init_param_values (int *params);
PARAM_VALUE (PARAM_ALLOW_PACKED_LOAD_DATA_RACES)
#define ALLOW_PACKED_STORE_DATA_RACES \
PARAM_VALUE (PARAM_ALLOW_PACKED_STORE_DATA_RACES)
+#define ASAN_STACK \
+ PARAM_VALUE (PARAM_ASAN_STACK)
+#define ASAN_GLOBALS \
+ PARAM_VALUE (PARAM_ASAN_GLOBALS)
+#define ASAN_INSTRUMENT_READS \
+ PARAM_VALUE (PARAM_ASAN_INSTRUMENT_READS)
+#define ASAN_INSTRUMENT_WRITES \
+ PARAM_VALUE (PARAM_ASAN_INSTRUMENT_WRITES)
+#define ASAN_MEMINTRIN \
+ PARAM_VALUE (PARAM_ASAN_MEMINTRIN)
+#define ASAN_USE_AFTER_RETURN \
+ PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN)
#endif /* ! GCC_PARAMS_H */
diff --git a/gcc/ree.c b/gcc/ree.c
index 152cc5aa914c..63cc8cc7c32e 100644
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -282,8 +282,20 @@ static bool
combine_set_extension (ext_cand *cand, rtx curr_insn, rtx *orig_set)
{
rtx orig_src = SET_SRC (*orig_set);
- rtx new_reg = gen_rtx_REG (cand->mode, REGNO (SET_DEST (*orig_set)));
rtx new_set;
+ rtx cand_pat = PATTERN (cand->insn);
+
+ /* If the extension's source/destination registers are not the same
+ then we need to change the original load to reference the destination
+ of the extension. Then we need to emit a copy from that destination
+ to the original destination of the load. */
+ rtx new_reg;
+ bool copy_needed
+ = (REGNO (SET_DEST (cand_pat)) != REGNO (XEXP (SET_SRC (cand_pat), 0)));
+ if (copy_needed)
+ new_reg = gen_rtx_REG (cand->mode, REGNO (SET_DEST (cand_pat)));
+ else
+ new_reg = gen_rtx_REG (cand->mode, REGNO (SET_DEST (*orig_set)));
/* Merge constants by directly moving the constant into the register under
some conditions. Recall that RTL constants are sign-extended. */
@@ -342,7 +354,8 @@ combine_set_extension (ext_cand *cand, rtx curr_insn, rtx *orig_set)
if (dump_file)
{
fprintf (dump_file,
- "Tentatively merged extension with definition:\n");
+ "Tentatively merged extension with definition %s:\n",
+ (copy_needed) ? "(copy needed)" : "");
print_rtl_single (dump_file, curr_insn);
}
return true;
@@ -567,27 +580,21 @@ make_defs_and_copies_lists (rtx extend_insn, const_rtx set_pat,
return ret;
}
-/* Merge the DEF_INSN with an extension. Calls combine_set_extension
- on the SET pattern. */
-
-static bool
-merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state)
+/* If DEF_INSN has single SET expression, possibly buried inside
+ a PARALLEL, return the address of the SET expression, else
+ return NULL. This is similar to single_set, except that
+ single_set allows multiple SETs when all but one is dead. */
+static rtx *
+get_sub_rtx (rtx def_insn)
{
- enum machine_mode ext_src_mode;
- enum rtx_code code;
- rtx *sub_rtx;
- rtx s_expr;
- int i;
-
- ext_src_mode = GET_MODE (XEXP (SET_SRC (cand->expr), 0));
- code = GET_CODE (PATTERN (def_insn));
- sub_rtx = NULL;
+ enum rtx_code code = GET_CODE (PATTERN (def_insn));
+ rtx *sub_rtx = NULL;
if (code == PARALLEL)
{
- for (i = 0; i < XVECLEN (PATTERN (def_insn), 0); i++)
+ for (int i = 0; i < XVECLEN (PATTERN (def_insn), 0); i++)
{
- s_expr = XVECEXP (PATTERN (def_insn), 0, i);
+ rtx s_expr = XVECEXP (PATTERN (def_insn), 0, i);
if (GET_CODE (s_expr) != SET)
continue;
@@ -596,7 +603,7 @@ merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state)
else
{
/* PARALLEL with multiple SETs. */
- return false;
+ return NULL;
}
}
}
@@ -605,10 +612,27 @@ merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state)
else
{
/* It is not a PARALLEL or a SET, what could it be ? */
- return false;
+ return NULL;
}
gcc_assert (sub_rtx != NULL);
+ return sub_rtx;
+}
+
+/* Merge the DEF_INSN with an extension. Calls combine_set_extension
+ on the SET pattern. */
+
+static bool
+merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state)
+{
+ enum machine_mode ext_src_mode;
+ rtx *sub_rtx;
+
+ ext_src_mode = GET_MODE (XEXP (SET_SRC (cand->expr), 0));
+ sub_rtx = get_sub_rtx (def_insn);
+
+ if (sub_rtx == NULL)
+ return false;
if (REG_P (SET_DEST (*sub_rtx))
&& (GET_MODE (SET_DEST (*sub_rtx)) == ext_src_mode
@@ -662,6 +686,72 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
if (!outcome)
return false;
+ /* If the destination operand of the extension is a different
+ register than the source operand, then additional restrictions
+ are needed. */
+ if ((REGNO (SET_DEST (PATTERN (cand->insn)))
+ != REGNO (XEXP (SET_SRC (PATTERN (cand->insn)), 0))))
+ {
+ /* In theory we could handle more than one reaching def, it
+ just makes the code to update the insn stream more complex. */
+ if (state->defs_list.length () != 1)
+ return false;
+
+ /* We require the candidate not already be modified. This may
+ be overly conservative. */
+ if (state->modified[INSN_UID (cand->insn)].kind != EXT_MODIFIED_NONE)
+ return false;
+
+ /* Transformation of
+ (set (reg1) (expression))
+ (set (reg2) (any_extend (reg1)))
+ into
+ (set (reg2) (any_extend (expression)))
+ (set (reg1) (reg2))
+ is only valid for scalar integral modes, as it relies on the low
+ subreg of reg1 to have the value of (expression), which is not true
+ e.g. for vector modes. */
+ if (!SCALAR_INT_MODE_P (GET_MODE (SET_DEST (PATTERN (cand->insn)))))
+ return false;
+
+ /* There's only one reaching def. */
+ rtx def_insn = state->defs_list[0];
+
+ /* The defining statement must not have been modified either. */
+ if (state->modified[INSN_UID (def_insn)].kind != EXT_MODIFIED_NONE)
+ return false;
+
+ /* The defining statement and candidate insn must be in the same block.
+ This is merely to keep the test for safety and updating the insn
+ stream simple. Also ensure that within the block the candidate
+ follows the defining insn. */
+ if (BLOCK_FOR_INSN (cand->insn) != BLOCK_FOR_INSN (def_insn)
+ || DF_INSN_LUID (def_insn) > DF_INSN_LUID (cand->insn))
+ return false;
+
+ /* If there is an overlap between the destination of DEF_INSN and
+ CAND->insn, then this transformation is not safe. Note we have
+ to test in the widened mode. */
+ rtx *dest_sub_rtx = get_sub_rtx (def_insn);
+ if (dest_sub_rtx == NULL
+ || !REG_P (SET_DEST (*dest_sub_rtx)))
+ return false;
+
+ rtx tmp_reg = gen_rtx_REG (GET_MODE (SET_DEST (PATTERN (cand->insn))),
+ REGNO (SET_DEST (*dest_sub_rtx)));
+ if (reg_overlap_mentioned_p (tmp_reg, SET_DEST (PATTERN (cand->insn))))
+ return false;
+
+ /* The destination register of the extension insn must not be
+ used or set between the def_insn and cand->insn exclusive. */
+ if (reg_used_between_p (SET_DEST (PATTERN (cand->insn)),
+ def_insn, cand->insn)
+ || reg_set_between_p (SET_DEST (PATTERN (cand->insn)),
+ def_insn, cand->insn))
+ return false;
+ }
+
+
/* If cand->insn has been already modified, update cand->mode to a wider
mode if possible, or punt. */
if (state->modified[INSN_UID (cand->insn)].kind != EXT_MODIFIED_NONE)
@@ -778,8 +868,7 @@ add_removable_extension (const_rtx expr, rtx insn,
if (REG_P (dest)
&& (code == SIGN_EXTEND || code == ZERO_EXTEND)
- && REG_P (XEXP (src, 0))
- && REGNO (dest) == REGNO (XEXP (src, 0)))
+ && REG_P (XEXP (src, 0)))
{
struct df_link *defs, *def;
ext_cand *cand;
@@ -863,6 +952,7 @@ find_and_remove_re (void)
int num_re_opportunities = 0, num_realized = 0, i;
vec<ext_cand> reinsn_list;
auto_vec<rtx> reinsn_del_list;
+ auto_vec<rtx> reinsn_copy_list;
ext_state state;
/* Construct DU chain to get all reaching definitions of each
@@ -899,11 +989,41 @@ find_and_remove_re (void)
if (dump_file)
fprintf (dump_file, "Eliminated the extension.\n");
num_realized++;
- reinsn_del_list.safe_push (curr_cand->insn);
+ if (REGNO (SET_DEST (PATTERN (curr_cand->insn)))
+ != REGNO (XEXP (SET_SRC (PATTERN (curr_cand->insn)), 0)))
+ {
+ reinsn_copy_list.safe_push (curr_cand->insn);
+ reinsn_copy_list.safe_push (state.defs_list[0]);
+ }
+ reinsn_del_list.safe_push (curr_cand->insn);
state.modified[INSN_UID (curr_cand->insn)].deleted = 1;
}
}
+ /* The copy list contains pairs of insns which describe copies we
+ need to insert into the INSN stream.
+
+ The first insn in each pair is the extension insn, from which
+ we derive the source and destination of the copy.
+
+ The second insn in each pair is the memory reference where the
+ extension will ultimately happen. We emit the new copy
+ immediately after this insn.
+
+ It may first appear that the arguments for the copy are reversed.
+ Remember that the memory reference will be changed to refer to the
+ destination of the extention. So we're actually emitting a copy
+ from the new destination to the old destination. */
+ for (unsigned int i = 0; i < reinsn_copy_list.length (); i += 2)
+ {
+ rtx curr_insn = reinsn_copy_list[i];
+ rtx pat = PATTERN (curr_insn);
+ rtx new_reg = gen_rtx_REG (GET_MODE (SET_DEST (pat)),
+ REGNO (XEXP (SET_SRC (pat), 0)));
+ rtx set = gen_rtx_SET (VOIDmode, new_reg, SET_DEST (pat));
+ emit_insn_after (set, reinsn_copy_list[i + 1]);
+ }
+
/* Delete all useless extensions here in one sweep. */
FOR_EACH_VEC_ELT (reinsn_del_list, i, curr_insn)
delete_insn (curr_insn);
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 740da4a83c6c..de332323ae1c 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -1093,6 +1093,7 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
int used_annul = 0;
int i;
struct resources cc_set;
+ bool *redundant;
/* We can't do anything if there are more delay slots in SEQ than we
can handle, or if we don't know that it will be a taken branch.
@@ -1133,6 +1134,7 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
return delay_list;
#endif
+ redundant = XALLOCAVEC (bool, XVECLEN (seq, 0));
for (i = 1; i < XVECLEN (seq, 0); i++)
{
rtx trial = XVECEXP (seq, 0, i);
@@ -1154,7 +1156,8 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
/* If this insn was already done (usually in a previous delay slot),
pretend we put it in our delay slot. */
- if (redundant_insn (trial, insn, new_delay_list))
+ redundant[i] = redundant_insn (trial, insn, new_delay_list);
+ if (redundant[i])
continue;
/* We will end up re-vectoring this branch, so compute flags
@@ -1187,6 +1190,12 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
return delay_list;
}
+ /* Record the effect of the instructions that were redundant and which
+ we therefore decided not to copy. */
+ for (i = 1; i < XVECLEN (seq, 0); i++)
+ if (redundant[i])
+ update_block (XVECEXP (seq, 0, i), insn);
+
/* Show the place to which we will be branching. */
*pnew_thread = first_active_target_insn (JUMP_LABEL (XVECEXP (seq, 0, 0)));
@@ -1250,6 +1259,7 @@ steal_delay_list_from_fallthrough (rtx insn, rtx condition, rtx seq,
/* If this insn was already done, we don't need it. */
if (redundant_insn (trial, insn, delay_list))
{
+ update_block (trial, insn);
delete_from_delay_slot (trial);
continue;
}
@@ -3236,6 +3246,7 @@ relax_delay_slots (rtx first)
to reprocess this insn. */
if (redundant_insn (XVECEXP (pat, 0, 1), delay_insn, 0))
{
+ update_block (XVECEXP (pat, 0, 1), insn);
delete_from_delay_slot (XVECEXP (pat, 0, 1));
next = prev_active_insn (next);
continue;
@@ -3355,6 +3366,7 @@ relax_delay_slots (rtx first)
&& redirect_with_delay_slots_safe_p (delay_insn, target_label,
insn))
{
+ update_block (XVECEXP (PATTERN (trial), 0, 1), insn);
reorg_redirect_jump (delay_insn, target_label);
next = insn;
continue;
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 2c6bc3693a20..66d3c79e3e8b 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -2762,7 +2762,21 @@ get_mode_bounds (enum machine_mode mode, int sign,
gcc_assert (size <= HOST_BITS_PER_WIDE_INT);
- if (sign)
+ /* Special case BImode, which has values 0 and STORE_FLAG_VALUE. */
+ if (mode == BImode)
+ {
+ if (STORE_FLAG_VALUE < 0)
+ {
+ min_val = STORE_FLAG_VALUE;
+ max_val = 0;
+ }
+ else
+ {
+ min_val = 0;
+ max_val = STORE_FLAG_VALUE;
+ }
+ }
+ else if (sign)
{
min_val = -((unsigned HOST_WIDE_INT) 1 << (size - 1));
max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1;
diff --git a/gcc/target-globals.c b/gcc/target-globals.c
index 2cfe257d567b..8d3eaa89041e 100644
--- a/gcc/target-globals.c
+++ b/gcc/target-globals.c
@@ -68,30 +68,47 @@ struct target_globals *
save_target_globals (void)
{
struct target_globals *g;
- struct target_optabs *saved_this_fn_optabs = this_fn_optabs;
-
- g = ggc_alloc_target_globals ();
- g->flag_state = XCNEW (struct target_flag_state);
- g->regs = XCNEW (struct target_regs);
+ struct target_globals_extra {
+ struct target_globals g;
+ struct target_flag_state flag_state;
+ struct target_optabs optabs;
+ struct target_cfgloop cfgloop;
+ struct target_builtins builtins;
+ struct target_gcse gcse;
+ struct target_bb_reorder bb_reorder;
+ struct target_lower_subreg lower_subreg;
+ } *p;
+ p = (struct target_globals_extra *)
+ ggc_internal_cleared_alloc_stat (sizeof (struct target_globals_extra)
+ PASS_MEM_STAT);
+ g = (struct target_globals *) p;
+ g->flag_state = &p->flag_state;
+ g->regs = ggc_internal_cleared_alloc_stat (sizeof (struct target_regs)
+ PASS_MEM_STAT);
g->rtl = ggc_alloc_cleared_target_rtl ();
- g->hard_regs = XCNEW (struct target_hard_regs);
- g->reload = XCNEW (struct target_reload);
- g->expmed = XCNEW (struct target_expmed);
- g->optabs = XCNEW (struct target_optabs);
+ g->hard_regs
+ = ggc_internal_cleared_alloc_stat (sizeof (struct target_hard_regs)
+ PASS_MEM_STAT);
+ g->reload = ggc_internal_cleared_alloc_stat (sizeof (struct target_reload)
+ PASS_MEM_STAT);
+ g->expmed = ggc_internal_cleared_alloc_stat (sizeof (struct target_expmed)
+ PASS_MEM_STAT);
+ g->optabs = &p->optabs;
g->libfuncs = ggc_alloc_cleared_target_libfuncs ();
- g->cfgloop = XCNEW (struct target_cfgloop);
- g->ira = XCNEW (struct target_ira);
- g->ira_int = XCNEW (struct target_ira_int);
- g->lra_int = XCNEW (struct target_lra_int);
- g->builtins = XCNEW (struct target_builtins);
- g->gcse = XCNEW (struct target_gcse);
- g->bb_reorder = XCNEW (struct target_bb_reorder);
- g->lower_subreg = XCNEW (struct target_lower_subreg);
+ g->cfgloop = &p->cfgloop;
+ g->ira = ggc_internal_cleared_alloc_stat (sizeof (struct target_ira)
+ PASS_MEM_STAT);
+ g->ira_int = ggc_internal_cleared_alloc_stat (sizeof (struct target_ira_int)
+ PASS_MEM_STAT);
+ g->lra_int = ggc_internal_cleared_alloc_stat (sizeof (struct target_lra_int)
+ PASS_MEM_STAT);
+ g->builtins = &p->builtins;
+ g->gcse = &p->gcse;
+ g->bb_reorder = &p->bb_reorder;
+ g->lower_subreg = &p->lower_subreg;
restore_target_globals (g);
- this_fn_optabs = this_target_optabs;
init_reg_sets ();
target_reinit ();
- this_fn_optabs = saved_this_fn_optabs;
return g;
}
diff --git a/gcc/target-globals.h b/gcc/target-globals.h
index b84d2902d9c2..e848a01677c0 100644
--- a/gcc/target-globals.h
+++ b/gcc/target-globals.h
@@ -37,26 +37,28 @@ extern struct target_builtins *this_target_builtins;
extern struct target_gcse *this_target_gcse;
extern struct target_bb_reorder *this_target_bb_reorder;
extern struct target_lower_subreg *this_target_lower_subreg;
+#endif
struct GTY(()) target_globals {
struct target_flag_state *GTY((skip)) flag_state;
- struct target_regs *GTY((skip)) regs;
+ void *GTY((atomic)) regs;
struct target_rtl *rtl;
- struct target_hard_regs *GTY((skip)) hard_regs;
- struct target_reload *GTY((skip)) reload;
- struct target_expmed *GTY((skip)) expmed;
+ void *GTY((atomic)) hard_regs;
+ void *GTY((atomic)) reload;
+ void *GTY((atomic)) expmed;
struct target_optabs *GTY((skip)) optabs;
struct target_libfuncs *libfuncs;
struct target_cfgloop *GTY((skip)) cfgloop;
- struct target_ira *GTY((skip)) ira;
- struct target_ira_int *GTY((skip)) ira_int;
- struct target_lra_int *GTY((skip)) lra_int;
+ void *GTY((atomic)) ira;
+ void *GTY((atomic)) ira_int;
+ void *GTY((atomic)) lra_int;
struct target_builtins *GTY((skip)) builtins;
struct target_gcse *GTY((skip)) gcse;
struct target_bb_reorder *GTY((skip)) bb_reorder;
struct target_lower_subreg *GTY((skip)) lower_subreg;
};
+#if SWITCHABLE_TARGET
extern struct target_globals default_target_globals;
extern struct target_globals *save_target_globals (void);
@@ -66,17 +68,17 @@ static inline void
restore_target_globals (struct target_globals *g)
{
this_target_flag_state = g->flag_state;
- this_target_regs = g->regs;
+ this_target_regs = (struct target_regs *) g->regs;
this_target_rtl = g->rtl;
- this_target_hard_regs = g->hard_regs;
- this_target_reload = g->reload;
- this_target_expmed = g->expmed;
+ this_target_hard_regs = (struct target_hard_regs *) g->hard_regs;
+ this_target_reload = (struct target_reload *) g->reload;
+ this_target_expmed = (struct target_expmed *) g->expmed;
this_target_optabs = g->optabs;
this_target_libfuncs = g->libfuncs;
this_target_cfgloop = g->cfgloop;
- this_target_ira = g->ira;
- this_target_ira_int = g->ira_int;
- this_target_lra_int = g->lra_int;
+ this_target_ira = (struct target_ira *) g->ira;
+ this_target_ira_int = (struct target_ira_int *) g->ira_int;
+ this_target_lra_int = (struct target_lra_int *) g->lra_int;
this_target_builtins = g->builtins;
this_target_gcse = g->gcse;
this_target_bb_reorder = g->bb_reorder;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ebf40341ef5f..126e6f037271 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,408 @@
+2014-01-13 Richard Biener <rguenther@suse.de>
+
+ * g++.dg/lto/lto.exp: Do check_effective_target_lto check before
+ adjusting mathlib options.
+ * gfortran.dg/lto/lto.exp: Likewise.
+
+2014-01-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/loop_optimization17.adb: New test.
+ * gnat.dg/loop_optimization17_pkg.ad[sb]: New helper.
+
+2014-01-13 Christian Bruel <christian.bruel@st.com>
+
+ * gcc.target/sh/cmpstrn.c: New case.
+
+2014-01-13 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.dg/vect/vect-simd-clone-10.c: Add dg-do run.
+ * gcc.dg/vect/vect-simd-clone-12.c: Likewise.
+
+2014-01-12 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/58026
+ * gfortran.dg/alloc_comp_basics_6.f90: New.
+
+2014-01-11 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/59700
+ * gfortran.dg/pr59700.f90: New test.
+
+2014-01-11 Dominique d'Humieres <dominiq@lps.ens.fr>
+
+ * gfortran.dg/binding_label_tests_10_main.f03: Cleanup mod file.
+ * gfortran.dg/use_only_3.f90: Likewise.
+ * gfortran.dg/inquire_10.f90: Delete opened file.
+ * gfortran.dg/inquire_15.f90: Likewise.
+ * gfortran.dg/pr16597.f90: Likewise.
+ * gfortran.dg/open_negative_unit_1.f90: Likewise + test
+ for PR59419.
+
+2014-01-10 Jeff Law <law@redhat.com>
+
+ PR middle-end/59743
+ * gcc.c-torture/compile/pr59743.c: New test.
+
+2014-01-10 Jan Hubicka <jh@suse.cz>
+
+ PR ipa/58585
+ * g++.dg/torture/pr58585.C: New testcase.
+
+2014-01-10 Hans-Peter Nilsson <hp@axis.com>
+
+ * gcc.dg/pr46309.c: Disable for cris*-*-*.
+
+2014-01-10 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.target/arm/neon-nested-apcs.c: Tweak dg directives.
+
+2014-01-10 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/59744
+ * gcc.target/aarch64/cmn-neg.c: Use equality comparisons.
+ * gcc.target/aarch64/cmn-neg2.c: New test.
+
+2014-01-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59374
+ * gcc.dg/torture/pr59374-3.c: New testcase.
+
+2014-01-10 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * lib/target-supports.exp
+ (check_effective_target_arm_crypto_ok_nocache): New.
+ (check_effective_target_arm_crypto_ok): Use above procedure.
+ (add_options_for_arm_crypto): Use et_arm_crypto_flags.
+
+2014-01-10 Jan Hubicka <hubicka@ucw.cz>
+
+ PR ipa/58252
+ PR ipa/59226
+ * g++.dg/ipa/devirt-20.C: New testcase.
+ * g++.dg/torture/pr58252.C: Likewise.
+ * g++.dg/torture/pr59226.C: Likewise.
+
+2014-01-10 Max Ostapenko <m.ostapenko@partner.samsung.com>
+
+ * c-c++-common/asan/no-asan-stack.c: New test.
+
+2014-01-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/59670
+ * gcc.dg/pr59670.c: New test.
+
+2014-01-09 Steve Ellcey <sellcey@mips.com>
+
+ * gcc.dg/delay-slot-1.c: Restrict -mabi=64 to 64 bit processors.
+
+2014-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/47735
+ * gcc.target/i386/pr47735.c: New test.
+
+ PR tree-optimization/59622
+ * g++.dg/opt/pr59622-2.C: New test.
+ * g++.dg/opt/pr59622-3.C: New test.
+ * g++.dg/opt/pr59622-4.C: New test.
+ * g++.dg/opt/pr59622-5.C: New test.
+
+ PR sanitizer/59136
+ * c-c++-common/asan/strip-path-prefix-1.c: Allow also the
+ filename:line instead of (modulename+offset) form with stripped
+ initial / from the filename.
+
+2014-01-09 Ian Lance Taylor <iant@google.com>
+
+ * go.test/go-test.exp (go-gc-tests): Skip nilptr tests that test
+ the other Go compiler.
+
+2014-01-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59730
+ * g++.dg/cpp0x/variadic145.C: New.
+
+2014-01-09 Uros Bizjak <ubizjak@gmail.com>
+
+ * go.test/go-test.exp (go-gc-tests): Don't run peano.go on systems
+ which don't support -fsplit-stack. Skip rotate[0123].go tests.
+
+2014-01-09 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR testsuite/59524
+ * gcc.dg/cilk-plus/cilk-plus.exp: Make sure the cilk keywords tests
+ are run only if the Cilk library is available/enabled.
+ * g++.dg/cilk-plus/cilk-plus.exp: Likewise.
+ * lib/target-supports.exp (check_libcilkrts_available): New function.
+
+2014-01-09 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR c++/59631
+ * gcc.dg/cilk-plus/cilk-plus.exp: Removed "-fcilkplus" from flags list.
+ * g++.dg/cilk-plus/cilk-plus.exp: Likewise.
+ * c-c++-common/cilk-plus/CK/spawnee_inline.c: Replaced second dg-option
+ with dg-additional-options.
+ * c-c++-common/cilk-plus/CK/varargs_test.c: Likewise.
+ * c-c++-common/cilk-plus/CK/steal_check.c: Likewise.
+ * c-c++-common/cilk-plus/CK/spawner_inline.c: Likewise.
+ * c-c++-common/cilk-plus/CK/spawning_arg.c: Likewise.
+ * c-c++-common/cilk-plus/CK/invalid_spawns.c: Added a dg-options tag.
+ * c-c++-common/cilk-plus/CK/pr59631.c: New testcase.
+
+2014-01-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59715
+ * gcc.dg/torture/pr59715.c: New testcase.
+
+2014-01-09 Max Ostapenko <m.ostapenko@partner.samsung.com>
+
+ * c-c++-common/asan/no-asan-globals.c: New test.
+ * c-c++-common/asan/no-instrument-reads.c: Likewise.
+ * c-c++-common/asan/no-instrument-writes.c: Likewise.
+ * c-c++-common/asan/use-after-return-1.c: Likewise.
+ * c-c++-common/asan/no-use-after-return.c: Likewise.
+
+2014-01-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/weak2.ad[sb]: New test.
+
+2014-01-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/59471
+ * gcc.dg/pr59471.c (foo): Avoid vector type arguments or return
+ type, use pointers to vector type instead.
+
+2014-01-08 Catherine Moore <clm@codesourcery.com>
+
+ * gcc.target/mips/umips-branch-3.c: New test.
+ * gcc.target/mips/umips-branch-4.c: New test.
+
+2014-01-08 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.dg/tree-ssa/reassoc-32.c, gcc.dg/tree-ssa/reassoc-33.c,
+ gcc.dg/tree-ssa/reassoc-34.c, gcc.dg/tree-ssa/reassoc-35.c,
+ gcc.dg/tree-ssa/reassoc-36.c: Extend -mbranch-cost handling to MIPS.
+ * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c,
+ gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c,
+ gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c,
+ gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c,
+ gcc.dg/tree-ssa/vrp87.c, gcc.dg/tree-ssa/forwprop-28.c: Skip for MIPS.
+
+2014-01-08 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR rtl-optimization/59137
+ * gcc.target/mips/pr59137.c: New test.
+
+2014-01-08 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.target/i386/asm-1.c (dg-options): Remove -m32.
+ * gcc.target/i386/incoming-5.c (dg-options): Ditto.
+ * gcc.target/i386/pr55433.c (dg-options): Ditto.
+ * gcc.target/i386/pr57848.c (dg-options): Ditto.
+ * gcc.target/i386/pr59099.c (dg-options): Ditto.
+ Require fpic effective target.
+ * gcc.target/i386/pr56246.c (dg-do): Compile for fpic target only.
+
+2014-01-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR ipa/59722
+ * gcc.dg/pr59722.c: New test.
+
+2014-01-08 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR middle-end/57748
+ * gcc.dg/torture/pr57748-3.c: New test.
+ * gcc.dg/torture/pr57748-4.c: New test.
+
+2014-01-08 Marek Polacek <polacek@redhat.com>
+
+ PR middle-end/59669
+ * gcc.dg/gomp/pr59669-1.c: New test.
+ * gcc.dg/gomp/pr59669-2.c: New test.
+
+2014-01-08 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/59610
+ * gcc.dg/ipa/pr59610.c: New test.
+
+2014-01-08 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/58182
+ * gfortran.dg/binding_label_tests_26a.f90: New.
+ * gfortran.dg/binding_label_tests_26b.f90: New.
+
+2014-01-08 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/59667
+ * c-c++-common/ubsan/pr59667.c: New test.
+
+2014-01-08 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/59630
+ * gcc.dg/pr59630.c: New testcase.
+
+2014-01-08 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/59471
+ * gcc.dg/pr59471.c: New testcase.
+
+2014-01-07 Jeff Law <law@redhat.com>
+
+ PR middle-end/53623
+ * gcc.target/i386/pr53623.c: New test.
+
+2014-01-07 Adam Butcher <adam@jessamine.co.uk>
+
+ * g++.dg/cpp1y/pr58500.C: Hoist PR reference to first line and remove
+ blanks at EOF.
+ * g++.dg/cpp1y/pr58534.C: Likewise.
+ * g++.dg/cpp1y/pr58536.C: Likewise.
+ * g++.dg/cpp1y/pr58548.C: Likewise.
+ * g++.dg/cpp1y/pr58549.C: Likewise.
+ * g++.dg/cpp1y/pr58637.C: Likewise.
+ * g++.dg/cpp1y/pr59112.C: Likewise.
+ * g++.dg/cpp1y/pr59113.C: Likewise.
+ * g++.dg/cpp1y/pr59629.C: Likewise.
+ * g++.dg/cpp1y/pr59635.C: Likewise.
+ * g++.dg/cpp1y/pr59636.C: Likewise.
+ * g++.dg/cpp1y/pr59638.C: Likewise.
+
+2014-01-07 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * gcc.target/arm/neon/vst1Q_laneu64-1.c: New test.
+
+2014-01-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.target/i386/intrinsics_4.c (bar): New function.
+
+2014-01-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * g++.dg/ext/is_base_of_incomplete-2.C: New.
+
+2014-01-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/58668
+ * gcc.dg/pr58668.c: New test.
+
+ PR tree-optimization/59643
+ * gcc.dg/pr59643.c: New test.
+ * gcc.c-torture/execute/pr59643.c: New test.
+
+2014-01-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/59589
+ * gfortran.dg/class_allocate_16.f90: New.
+
+2014-01-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/59644
+ * gcc.target/i386/pr59644.c: New test.
+
+2014-01-06 Marek Polacek <polacek@redhat.com>
+
+ PR c/57773
+ * gcc.dg/pr57773.c: New test.
+
+2014-01-06 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/59635
+ PR c++/59636
+ PR c++/59629
+ PR c++/59638
+ * g++.dg/cpp1y/pr59635.C: New testcase.
+ * g++.dg/cpp1y/pr59636.C: New testcase.
+ * g++.dg/cpp1y/pr59629.C: New testcase.
+ * g++.dg/cpp1y/pr59638.C: New testcase.
+
+2014-01-06 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/59008
+ * gcc.dg/ipa/pr59008.c: New test.
+
+2014-01-06 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.dg/vect/vect.exp: Add clearcap_ldflags to DEFAULT_VECTCFLAGS
+ if supported.
+
+2014-01-06 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.target/i386/avx512f-vcmppd-2.c: Add -std=c99.
+ Require c99_runtime.
+ * gcc.target/i386/avx512f-vcmpps-2.c: Likewise.
+
+ * gcc.target/i386/avx512f-vfixupimmpd-2.c: Add -std=gnu99.
+ Require c99_runtime.
+ * gcc.target/i386/avx512f-vfixupimmps-2.c: Likewise.
+ * gcc.target/i386/avx512f-vfixupimmsd-2.c: Likewise.
+ * gcc.target/i386/avx512f-vfixupimmss-2.c: Likewise.
+
+ * gcc.target/i386/avx512f-vgetmantpd-2.c: Add -std=c99.
+ Require c99_runtime.
+ Make CALC void static.
+ * gcc.target/i386/avx512f-vgetmantps-2.c: Likewise.
+
+ * gcc.target/i386/avx512f-vgetmantsd-2.c: Add -std=c99.
+ Require c99_runtime.
+ * gcc.target/i386/avx512f-vgetmantss-2.c: Likewise.
+
+2014-01-06 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.target/i386/pr59501-1.c: Require avx effective target.
+ * gcc.target/i386/pr59501-2.c: Likewise.
+ * gcc.target/i386/pr59501-3.c: Likewise.
+ * gcc.target/i386/pr59501-4.c: Likewise.
+ * gcc.target/i386/pr59501-5.c: Likewise.
+ * gcc.target/i386/pr59501-6.c: Likewise.
+
+2014-01-06 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.target/i386/pr59390.c: Replace math.h by fma declaration.
+ * gcc.target/i386/pr59390_1.c: Likewise.
+ * gcc.target/i386/pr59390_2.c: Likewise.
+
+2014-01-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/pr59350.c: Tweak.
+ * gcc.dg/pr59350-2.c: New test.
+ * g++.dg/pr59510.C: Likewise.
+
+2014-01-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/59023
+ * gfortran.dg/bind_c_procs_2.f90: New.
+
+2014-01-05 John David Anglin <danglin@gcc.gnu.org>
+
+ * gcc.dg/tree-ssa/reassoc-33.c: Don't run on hppa*-*-*.
+ * gcc.dg/tree-ssa/reassoc-34.c: Likewise.
+ * gcc.dg/tree-ssa/reassoc-35.c: Likewise.
+ * gcc.dg/tree-ssa/reassoc-36.c: Likewise.
+ * gcc.dg/tree-ssa/forwprop-28.c: Skip compile on hppa*-*-*.
+ * gcc.dg/tree-ssa/vrp47.c: Likewise.
+ * gcc.dg/tree-ssa/vrp87.c: Likewise.
+
+2014-01-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.target/arm/neon-nested-apcs.c: New test.
+
+2014-01-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59519
+ * gcc.dg/vect/pr59519-1.c: New test.
+ * gcc.dg/vect/pr59519-2.c: New test.
+
+ * gcc.target/i386/avx512f-vmovdqu32-1.c: Allow vmovdqu64 instead of
+ vmovdqu32.
+
+2014-01-04 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/59547
+ * gfortran.dg/typebound_proc_32.f90: New.
+
+2014-01-03 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/58950
+ * g++.dg/pr58950.C: New file.
+
2014-01-03 Tobias Burnus <burnus@net-b.de>
PR c++/58567
diff --git a/gcc/testsuite/c-c++-common/asan/no-asan-globals.c b/gcc/testsuite/c-c++-common/asan/no-asan-globals.c
new file mode 100644
index 000000000000..70a1f95a3a31
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/no-asan-globals.c
@@ -0,0 +1,13 @@
+/* { dg-do assemble } */
+/* { dg-options "-save-temps --param asan-globals=0" } */
+
+volatile int ten = 10;
+
+int main() {
+ volatile static char XXX[10];
+ XXX[ten];
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "__asan_register_globals" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-asan-stack.c b/gcc/testsuite/c-c++-common/asan/no-asan-stack.c
new file mode 100644
index 000000000000..0f65ab3f7acf
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/no-asan-stack.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { { i?86-*-linux* x86_64-*-linux* } && lp64 } } } */
+/* { dg-options "--param asan-stack=0" } */
+#include <string.h>
+
+volatile int one = 1;
+
+int
+main ()
+{
+ volatile char a1[] = {one, 2, 3, 4};
+ volatile char a2[] = {1, 2*one, 3, 4};
+ volatile int res = memcmp ((void *)a1,(void *)a2, 5 + one);
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "0x41b58ab3|0x41B58AB3|1102416563" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-instrument-reads.c b/gcc/testsuite/c-c++-common/asan/no-instrument-reads.c
new file mode 100644
index 000000000000..df75878de2f4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/no-instrument-reads.c
@@ -0,0 +1,13 @@
+/* { dg-do assemble } */
+/* { dg-options "--param asan-instrument-reads=0 -save-temps" } */
+
+volatile int ten = 10;
+
+int main() {
+ volatile char x[10];
+ x[ten];
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "__asan_load" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-instrument-writes.c b/gcc/testsuite/c-c++-common/asan/no-instrument-writes.c
new file mode 100644
index 000000000000..c1500b9fb321
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/no-instrument-writes.c
@@ -0,0 +1,13 @@
+/* { dg-do assemble } */
+/* { dg-options "--param asan-instrument-writes=0 -save-temps" } */
+
+volatile int ten = 10;
+
+int main() {
+ volatile char x[10];
+ x[ten] = 1;
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "__asan_store" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-use-after-return.c b/gcc/testsuite/c-c++-common/asan/no-use-after-return.c
new file mode 100644
index 000000000000..f326e0caee4e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/no-use-after-return.c
@@ -0,0 +1,13 @@
+/* { dg-do assemble } */
+/* { dg-options "--param asan-use-after-return=0 -save-temps" } */
+
+extern void f(char *);
+
+int main() {
+ char buf[64];
+ f(buf);
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "__asan_option_detect_stack_use_after_return" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c b/gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c
index ea8e933c03bf..812aa37e2d0e 100644
--- a/gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c
+++ b/gcc/testsuite/c-c++-common/asan/strip-path-prefix-1.c
@@ -12,4 +12,4 @@ int main() {
}
/* { dg-output "heap-use-after-free.*(\n|\r\n|\r)" } */
-/* { dg-output " #0 0x\[0-9a-f\]+ \[(\]\[^/\]\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output " #0 0x\[0-9a-f\]+ \[(\]?\[^/\]\[^\n\r]*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/asan/use-after-return-1.c b/gcc/testsuite/c-c++-common/asan/use-after-return-1.c
new file mode 100644
index 000000000000..435637d53231
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/use-after-return-1.c
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "detect_stack_use_after_return=1" } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdio.h>
+#include <pthread.h>
+
+#ifndef kSize
+# define kSize 1
+#endif
+
+#ifndef UseThread
+# define UseThread 0
+#endif
+
+__attribute__((noinline))
+char *Ident(char *x) {
+ fprintf(stderr, "1: %p\n", x);
+ return x;
+}
+
+__attribute__((noinline))
+char *Func1() {
+ char local[kSize];
+ return Ident(local);
+}
+
+__attribute__((noinline))
+void Func2(char *x) {
+ fprintf(stderr, "2: %p\n", x);
+ *x = 1;
+}
+
+void *Thread(void *unused) {
+ Func2(Func1());
+ return NULL;
+}
+
+int main(int argc, char **argv) {
+#if UseThread
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ pthread_join(t, 0);
+#else
+ Func2(Func1());
+#endif
+ return 0;
+}
+
+/* { dg-output "WRITE of size 1 at .* thread T0.*" } */
+/* { dg-output " #0.*Func2.*use-after-return-1.c:31.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'local\' <== Memory access at offset 32 is inside this variable" } */
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c
index 90dd5c130b41..ba9e6193627e 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c
@@ -1,3 +1,5 @@
+/* { dg-options "-fcilkplus" } */
+
extern int foo ();
int bar = _Cilk_spawn foo (); /* { dg-error "may only be used inside a function" } */
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/pr59631.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/pr59631.c
new file mode 100644
index 000000000000..389ee7c5dab0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/pr59631.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options " " } */
+
+/* Tests the errors when Cilk keywords are used without -fcilkplus. */
+
+void foo()
+{
+ _Cilk_spawn foo(); /* { dg-error "must be enabled to use" } */
+}
+
+void foo2 ()
+{
+ _Cilk_spawn foo (); /* { dg-error "must be enabled to use" } */
+ _Cilk_sync; /* { dg-error "must be enabled to use" } */
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/spawnee_inline.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/spawnee_inline.c
index 8060c6ceb15c..233a371f140e 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/CK/spawnee_inline.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/spawnee_inline.c
@@ -1,6 +1,6 @@
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
/* { dg-options "-fcilkplus -w" } */
-/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
#include <stdio.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/spawner_inline.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/spawner_inline.c
index eab9e4206a05..55ec223abb35 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/CK/spawner_inline.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/spawner_inline.c
@@ -1,6 +1,6 @@
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
/* { dg-options "-fcilkplus" } */
-/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
#include <stdlib.h>
#define DEFAULT_VALUE 30
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c
index ac3795283795..95e6cab02c13 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c
@@ -1,6 +1,6 @@
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
/* { dg-options "-fcilkplus" } */
-/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
void f0(volatile int *steal_flag)
{
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c
index 21d6797857dc..6e2876531c3a 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c
@@ -1,6 +1,6 @@
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
/* { dg-options "-fcilkplus" } */
-/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
// #include <cilk/cilk_api.h>
extern void __cilkrts_set_param (char *, char *);
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/varargs_test.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/varargs_test.c
index ab5d63a3f4c6..271460024409 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/CK/varargs_test.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/varargs_test.c
@@ -1,6 +1,6 @@
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
/* { dg-options "-fcilkplus" } */
-/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
#include <stdarg.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr59667.c b/gcc/testsuite/c-c++-common/ubsan/pr59667.c
new file mode 100644
index 000000000000..367e3034629d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/pr59667.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined" } */
+/* { dg-shouldfail "ubsan" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+
+int
+main (void)
+{
+ unsigned int len = 1;
+ float (*P)[len][len] = 0;
+ (*P)[0][0] = 1;
+ return 0;
+}
+
+/* { dg-output "store to null pointer of type 'float'(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag5.C b/gcc/testsuite/g++.dg/abi/abi-tag5.C
index de5580239dd7..95e367ef935f 100644
--- a/gcc/testsuite/g++.dg/abi/abi-tag5.C
+++ b/gcc/testsuite/g++.dg/abi/abi-tag5.C
@@ -1,6 +1,7 @@
// { dg-options -Wabi-tag }
+// { dg-final { scan-assembler "_Z1f1BI1AB3fooE" } }
struct __attribute__ ((abi_tag ("foo"))) A { };
template <class T> struct B: T { };
-B<A> b;
+void f(B<A>) {}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp b/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
index e201fd227cfd..37b8ccbe70ae 100644
--- a/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
+++ b/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
@@ -47,9 +47,7 @@ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -O3 -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " "
-dg-finish
-dg-init
dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -O0 -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -O1 -fcilkplus" " "
@@ -61,25 +59,17 @@ dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -g -O1
dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -g -O2 -ftree-vectorize -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -g -O3 -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -O3 -ftree-vectorize -fcilkplus -g" " "
-dg-finish
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -O1 -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -O2 -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -O3 -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -g -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -g -O2 -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -g -O3 -fcilkplus" " "
-dg-finish
+if { [check_libcilkrts_available] } {
+ dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -O1 -fcilkplus" " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -O3 -fcilkplus" " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -g -fcilkplus" " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -g -O2 -fcilkplus" " "
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O1 -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -O2 -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -O3 -fcilkplus" " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O1" " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3" " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g" " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -O2" " "
+ }
dg-finish
unset TEST_EXTRA_LIBS
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-39.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-39.C
new file mode 100644
index 000000000000..9fe553861886
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-39.C
@@ -0,0 +1,11 @@
+// PR c++/58856
+// { dg-require-effective-target c++11 }
+
+template <typename T>
+struct U1 {};
+
+template <typename T1, typename... Ts>
+using U2 = U1<T1>;
+
+template <typename T1, typename... Ts>
+using U3 = U2<T1, Ts...>;
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-union3.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-union3.C
new file mode 100644
index 000000000000..35f6509df786
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-union3.C
@@ -0,0 +1,10 @@
+// PR c++/58965
+// { dg-require-effective-target c++11 }
+
+void foo()
+{
+ static union
+ {
+ int i = i;
+ };
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic145.C b/gcc/testsuite/g++.dg/cpp0x/variadic145.C
new file mode 100644
index 000000000000..65edda59fd85
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic145.C
@@ -0,0 +1,13 @@
+// PR c++/59730
+// { dg-do compile { target c++11 } }
+
+template <typename> void declval();
+template <typename> void forward();
+template <typename> class D;
+template <typename _Functor, typename... _Bound_args>
+class D <_Functor(_Bound_args...)> {
+ template <typename... _Args, decltype(declval<_Functor>)>
+ void operator()(...) {
+ 0(forward<_Args>...);
+ }
+};
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58500.C b/gcc/testsuite/g++.dg/cpp1y/pr58500.C
index b9d4a26d4159..7adb1b8ae4c7 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr58500.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58500.C
@@ -1,8 +1,7 @@
+// PR c++/58500
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
-// PR c++/58500
-
struct A {};
void foo(auto (A::*)());
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58534.C b/gcc/testsuite/g++.dg/cpp1y/pr58534.C
index 4aa4f4301898..3319f6969568 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr58534.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58534.C
@@ -1,9 +1,7 @@
+// PR c++/58534
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
-// PR c++/58534
-
template<typename> void foo(const auto&) {}
template<typename, typename...T> void foo(const auto&, T...) {}
-
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58536.C b/gcc/testsuite/g++.dg/cpp1y/pr58536.C
index 8050c1957c83..be0043823a0f 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr58536.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58536.C
@@ -1,12 +1,10 @@
+// PR c++/58536
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
-// PR c++/58536
-
struct A
{
A(auto);
};
A::A(auto) {}
-
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58548.C b/gcc/testsuite/g++.dg/cpp1y/pr58548.C
index 0ac2e1c341d0..ad6f726a33cc 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr58548.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58548.C
@@ -1,10 +1,8 @@
+// PR c++/58548
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
-// PR c++/58548
-
void foo(auto)
{
struct A { int i; };
}
-
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58549.C b/gcc/testsuite/g++.dg/cpp1y/pr58549.C
index b71bac9975af..b9825b51abc8 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr58549.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58549.C
@@ -1,10 +1,8 @@
+// PR c++/58549
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
-// PR c++/58549
-
void foo(auto)
{
void bar();
}
-
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58637.C b/gcc/testsuite/g++.dg/cpp1y/pr58637.C
index 46200ff1c5dd..29297bb93dbf 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr58637.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58637.C
@@ -1,7 +1,5 @@
+// PR c++/58637
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
-// PR c++/58637
-
template<> void foo(auto); // { dg-error "auto|not a template" }
-
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr59112.C b/gcc/testsuite/g++.dg/cpp1y/pr59112.C
index e7326ac31130..12fef4b9fac7 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr59112.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr59112.C
@@ -1,8 +1,7 @@
+// PR c++/59112
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
-// PR c++/59112
-
void foo()
{
struct A
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr59113.C b/gcc/testsuite/g++.dg/cpp1y/pr59113.C
index f909a76bd358..19bab2cedcc9 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr59113.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr59113.C
@@ -1,8 +1,7 @@
+// PR c++/59113
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
-// PR c++/59113
-
void foo()
{
void bar(auto) {} // { dg-error "function-definition|auto|not permitted" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr59629.C b/gcc/testsuite/g++.dg/cpp1y/pr59629.C
new file mode 100644
index 000000000000..c0e01c1c75de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr59629.C
@@ -0,0 +1,5 @@
+// PR c++/59629
+// { dg-do compile }
+// { dg-options "-std=c++1y" }
+
+void foo(int i = []{ auto 0; }()); // { dg-error "expected|could not convert" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr59635.C b/gcc/testsuite/g++.dg/cpp1y/pr59635.C
new file mode 100644
index 000000000000..16a3481b99dc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr59635.C
@@ -0,0 +1,7 @@
+// PR c++/59635
+// { dg-do compile }
+// { dg-options "-std=c++1y" }
+
+auto f = [] (auto, ...) { return 0; };
+
+int (*p) (int, ...) = f; // { dg-message "unimplemented" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr59636.C b/gcc/testsuite/g++.dg/cpp1y/pr59636.C
new file mode 100644
index 000000000000..bb7d9b546d44
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr59636.C
@@ -0,0 +1,5 @@
+// PR c++/59636
+// { dg-do compile }
+// { dg-options "-std=c++1y" }
+
+auto f = []() { return []<>() {}; }; // { dg-error "expected identifier" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr59638.C b/gcc/testsuite/g++.dg/cpp1y/pr59638.C
new file mode 100644
index 000000000000..22af1398a13b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr59638.C
@@ -0,0 +1,14 @@
+// PR c++/59638
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+void (*a)(auto); // { dg-error "template declaration" }
+
+void (*b)(auto) = 0; // { dg-error "template declaration" }
+
+typedef void (*f)(auto); // { dg-error "template declaration" }
+
+struct A
+{
+ int i;
+};
diff --git a/gcc/testsuite/g++.dg/ext/is_base_of_incomplete-2.C b/gcc/testsuite/g++.dg/ext/is_base_of_incomplete-2.C
new file mode 100644
index 000000000000..54862585d099
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_base_of_incomplete-2.C
@@ -0,0 +1,5 @@
+struct T;
+
+int check1[__is_base_of(T, T) ? 1 : -1];
+int check2[__is_base_of(T, const T) ? 1 : -1];
+int check3[__is_base_of(volatile T, T) ? 1 : -1];
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-20.C b/gcc/testsuite/g++.dg/ipa/devirt-20.C
new file mode 100644
index 000000000000..aee95147a634
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-20.C
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-release_ssa" } */
+namespace {
+struct A
+{ int a; virtual int foo() {return a;} void bar() {a=7;} };
+struct B
+{ int b; virtual int foo2() {return b;} void bar2() {b=9;} };
+struct C : public virtual A, public virtual B { };
+struct D : public virtual B, public virtual A { };
+struct E : public C, public D { void bar2() {b=9;} }; }
+int
+main(void)
+{
+ struct E e;
+ struct C *c = &e;
+ struct D *d = &e;
+ struct A *a = &e;
+ struct B *b = &e;
+ e.bar();
+ e.bar2();
+ if (e.foo() + e.foo2() != 16)
+ abort ();
+ if (c->foo() + d->foo2() != 16)
+ abort ();
+ if (a->foo() + b->foo2() != 16)
+ abort ();
+ return 0;
+}
+/* { dg-final { scan-tree-dump-not "abort" "release_ssa" } } */
+/* { dg-final { cleanup-ipa-dump "release_ssa" } } */
diff --git a/gcc/testsuite/g++.dg/lto/lto.exp b/gcc/testsuite/g++.dg/lto/lto.exp
index 9145af782480..4d7d727b9870 100644
--- a/gcc/testsuite/g++.dg/lto/lto.exp
+++ b/gcc/testsuite/g++.dg/lto/lto.exp
@@ -35,6 +35,11 @@ load_lib target-libpath.exp
# Load the language-independent compabibility support procedures.
load_lib lto.exp
+# If LTO has not been enabled, bail.
+if { ![check_effective_target_lto] } {
+ return
+}
+
g++_init
lto_init no-mathlib
@@ -42,11 +47,6 @@ lto_init no-mathlib
# with other lto tests running at the same time.
set sid "cp_lto"
-# If LTO has not been enabled, bail.
-if { ![check_effective_target_lto] } {
- return
-}
-
# Main loop.
foreach src [lsort [find $srcdir/$subdir *_0.\[cC\]]] {
# If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/g++.dg/opt/pr59622-2.C b/gcc/testsuite/g++.dg/opt/pr59622-2.C
new file mode 100644
index 000000000000..8096eebca40b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr59622-2.C
@@ -0,0 +1,21 @@
+// PR tree-optimization/59622
+// { dg-do compile }
+// { dg-options "-O2" }
+
+namespace
+{
+ struct A
+ {
+ A () {}
+ virtual A *bar (int) = 0;
+ A *baz (int x) { return bar (x); }
+ };
+}
+
+A *a;
+
+void
+foo ()
+{
+ a->baz (0);
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr59622-3.C b/gcc/testsuite/g++.dg/opt/pr59622-3.C
new file mode 100644
index 000000000000..0af86050c23a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr59622-3.C
@@ -0,0 +1,21 @@
+// PR tree-optimization/59622
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct C { int a; int b; };
+
+namespace
+{
+ struct A
+ {
+ virtual C foo ();
+ C bar () { return foo (); }
+ };
+}
+
+C
+baz ()
+{
+ A a;
+ return a.bar ();
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr59622-4.C b/gcc/testsuite/g++.dg/opt/pr59622-4.C
new file mode 100644
index 000000000000..f72af1641c86
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr59622-4.C
@@ -0,0 +1,23 @@
+// PR tree-optimization/59622
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct C { int a; int b; };
+
+namespace
+{
+ struct A
+ {
+ A () {}
+ virtual C bar (int) = 0;
+ C baz (int x) { return bar (x); }
+ };
+}
+
+A *a;
+
+C
+foo ()
+{
+ return a->baz (0);
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr59622-5.C b/gcc/testsuite/g++.dg/opt/pr59622-5.C
new file mode 100644
index 000000000000..bcb2591a64c0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr59622-5.C
@@ -0,0 +1,26 @@
+// PR tree-optimization/59622
+// { dg-do compile }
+// { dg-options "-O2" }
+
+namespace
+{
+ struct A
+ {
+ A () {}
+ virtual A *bar (int);
+ A *baz (int x) { return bar (x); }
+ };
+
+ __attribute__((noreturn)) A *A::bar (int)
+ {
+ __builtin_exit (0);
+ }
+}
+
+A *a;
+
+void
+foo ()
+{
+ a->baz (0);
+}
diff --git a/gcc/testsuite/g++.dg/pr58950.C b/gcc/testsuite/g++.dg/pr58950.C
new file mode 100644
index 000000000000..10a2032440f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr58950.C
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+void f(){
+ int i __attribute__((vector_size(2*sizeof(int)))) = { 2, 3 };
+ __builtin_shuffle (i, i); /* { dg-warning "value computed is not used" } */
+ ++i?1:0; /* { dg-warning "value computed is not used" } */
+}
diff --git a/gcc/testsuite/g++.dg/pr59510.C b/gcc/testsuite/g++.dg/pr59510.C
new file mode 100644
index 000000000000..dcdf860dcf73
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr59510.C
@@ -0,0 +1,82 @@
+// PR debug/59510
+// { dg-do compile }
+// { dg-options "-O2 -g --param=large-stack-frame-growth=1" }
+
+template <typename _Iterator>
+struct _Iter_base
+{
+ typedef _Iterator iterator_type;
+};
+template <typename _CharT>
+struct basic_ostream;
+template <typename _CharT>
+struct basic_ostringstream;
+template <typename _CharT>
+struct ostreambuf_iterator;
+typedef basic_ostringstream <char>ostringstream;
+template <typename _Iterator> struct _Miter_base : _Iter_base <_Iterator>
+{
+};
+template <typename _Iterator>
+typename _Miter_base <_Iterator>::iterator_type __miter_base (_Iterator);
+template <typename _CharT>
+ostreambuf_iterator <_CharT>
+__copy_move_a2 (ostreambuf_iterator <_CharT>);
+template <typename _II, typename _OI>
+_OI copy (_II __first, _II __last, _OI __result)
+{
+ __copy_move_a2 <false> (__first, __miter_base (__last), __result);
+}
+struct ios_base {
+ struct _Words {
+ int *_M_pword;
+ long _M_iword;
+ };
+ _Words _M_local_word[8];
+};
+template <typename _CharT>
+struct basic_streambuf
+{
+ typedef _CharT char_type;
+ int sputn (char_type *, int);
+};
+template <typename _CharT>
+struct ostreambuf_iterator
+{
+ typedef basic_streambuf <_CharT> streambuf_type;
+ typedef basic_ostream <_CharT> ostream_type;
+ streambuf_type *_M_sbuf;
+ bool _M_failed;
+ ostreambuf_iterator (ostream_type __s) : _M_sbuf (__s.rdbuf ()), _M_failed () {}
+ void _M_put (_CharT * __ws, int __len)
+ {
+ if (_M_failed && _M_sbuf->sputn (__ws, __len) != __len) _M_failed = true;
+ }
+};
+template <bool, typename _CharT>
+void __copy_move_a2 (_CharT * __first,_CharT * __last,ostreambuf_iterator <_CharT> __result)
+{
+ int __num = __last - __first;
+ __result._M_put (__first, __num);
+}
+template <typename _CharT>
+struct basic_ios : ios_base
+{
+ basic_streambuf <_CharT> *rdbuf ();
+};
+template <typename _CharT>
+struct basic_ostream : public basic_ios <_CharT>
+{
+};
+template <typename _CharT>
+struct basic_ostringstream : public basic_ostream <_CharT>
+{
+};
+void
+test01 () {
+ char data1[] = "foo";
+ char *beg1 = data1;
+ ostringstream oss1;
+ ostreambuf_iterator <char> out1 (oss1);
+ out1 = copy (beg1, beg1, out1);
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr58252.C b/gcc/testsuite/g++.dg/torture/pr58252.C
new file mode 100644
index 000000000000..d38a7a7ea4be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr58252.C
@@ -0,0 +1,142 @@
+// { dg-do compile }
+// { dg-options "-fpermissive" }
+typedef long unsigned int size_t;
+ typedef bool _CORBA_Boolean;
+ typedef unsigned int _CORBA_ULong;
+ template <class T> class _CORBA_Sequence {
+ public: typedef _CORBA_Sequence<T> T_seq;
+ inline T_seq &operator= (const T_seq &s) {
+ for (unsigned long i=0;
+ i < pd_len;
+ i++) {
+ }
+ }
+ _CORBA_ULong pd_len;
+ };
+ template <class T> class _CORBA_Unbounded_Sequence : public _CORBA_Sequence<T> {
+ inline _CORBA_Unbounded_Sequence_WChar() { // { dg-warning "forbids declaration" }
+ }
+ };
+ class _CORBA_ObjRef_Var_base {
+ };
+ template <class T, class T_Helper> class _CORBA_ObjRef_Var : public _CORBA_ObjRef_Var_base {
+ public: typedef T* ptr_t;
+ typedef T* T_ptr;
+ inline _CORBA_ObjRef_Var() : pd_objref(T_Helper::_nil()) {
+ }
+ inline _CORBA_ObjRef_Var(T_ptr p) : pd_objref(p) {
+ }
+ private: T_ptr pd_objref;
+ };
+ class omniLocalIdentity;
+ class omniObjRef {
+ };
+ class omniServant {
+ public: virtual ~omniServant();
+ virtual void* _ptrToInterface(const char* repoId);
+ };
+ namespace CORBA {
+ class NVList {
+ };
+ class Object {
+ };
+ struct StructMember {
+ };
+ class StructMemberSeq : public _CORBA_Unbounded_Sequence< StructMember > {
+ };
+ class _objref_IRObject : public virtual ::CORBA::Object, public virtual omniObjRef {
+ };
+ class _impl_IRObject : public virtual omniServant {
+ };
+ class _objref_Container;
+ typedef _objref_Container* Container_ptr;
+ class _impl_Contained : public virtual _impl_IRObject {
+ };
+ class _objref_ExceptionDef;
+ typedef _objref_ExceptionDef* ExceptionDef_ptr;
+ class ExceptionDef_Helper {
+ public: typedef ExceptionDef_ptr _ptr_type;
+ static _ptr_type _nil();
+ };
+ typedef _CORBA_ObjRef_Var<_objref_ExceptionDef, ExceptionDef_Helper> ExceptionDef_var;
+ class Container {
+ public: typedef Container_ptr _ptr_type;
+ static const char* _PD_repoId;
+ };
+ class _objref_Container : public virtual _objref_IRObject {
+ ExceptionDef_ptr create_exception(const char* id, const char* name, const char* version, const ::CORBA::StructMemberSeq& members);
+ };
+ class _impl_Container : public virtual _impl_IRObject {
+ public: virtual ~_impl_Container();
+ virtual ExceptionDef_ptr create_exception(const char* id, const char* name, const char* version, const ::CORBA::StructMemberSeq& members) = 0;
+ };
+ class _impl_IDLType : public virtual _impl_IRObject {
+ };
+ class _impl_TypedefDef : public virtual _impl_Contained, public virtual _impl_IDLType {
+ };
+ class _impl_StructDef : public virtual _impl_TypedefDef, public virtual _impl_Container {
+ };
+ }
+ namespace PortableServer {
+ class ServantBase : public virtual omniServant {
+ };
+ }
+ namespace POA_CORBA {
+ class IRObject : public virtual CORBA::_impl_IRObject, public virtual ::PortableServer::ServantBase {
+ };
+ class Contained : public virtual CORBA::_impl_Contained, public virtual IRObject {
+ };
+ class Container : public virtual CORBA::_impl_Container, public virtual IRObject {
+ };
+ class IDLType : public virtual CORBA::_impl_IDLType, public virtual IRObject {
+ };
+ class TypedefDef : public virtual CORBA::_impl_TypedefDef, public virtual Contained, public virtual IDLType {
+ };
+ class StructDef : public virtual CORBA::_impl_StructDef, public virtual TypedefDef, public virtual Container {
+ public: virtual ~StructDef();
+ };
+ }
+ namespace omni {
+ class omniOrbPOA;
+ class giopAddress;
+ }
+ class omniCallDescriptor {
+ public: typedef void (*LocalCallFn)(omniCallDescriptor*, omniServant*);
+ inline omniCallDescriptor(LocalCallFn lcfn, const char* op_, int op_len_, _CORBA_Boolean oneway, const char*const* user_excns_, int n_user_excns_, _CORBA_Boolean is_upcall_) : pd_localCall(lcfn), pd_op(op_), pd_oplen(op_len_), pd_user_excns(user_excns_), pd_n_user_excns(n_user_excns_), pd_is_oneway(oneway), pd_is_upcall(is_upcall_), pd_contains_values(0), pd_first_address_used(0), pd_current_address(0), pd_objref(0), pd_poa(0), pd_localId(0), pd_deadline_secs(0), pd_deadline_nanosecs(0) {
+ }
+ private: LocalCallFn pd_localCall;
+ const char* pd_op;
+ size_t pd_oplen;
+ const char*const* pd_user_excns;
+ int pd_n_user_excns;
+ _CORBA_Boolean pd_is_oneway;
+ _CORBA_Boolean pd_is_upcall;
+ _CORBA_Boolean pd_contains_values;
+ const omni::giopAddress* pd_first_address_used;
+ const omni::giopAddress* pd_current_address;
+ omniObjRef* pd_objref;
+ omni::omniOrbPOA* pd_poa;
+ omniLocalIdentity* pd_localId;
+ unsigned long pd_deadline_secs;
+ unsigned long pd_deadline_nanosecs;
+ };
+ class _0RL_cd_7963219a43724a61_f2000000 : public omniCallDescriptor {
+ public: inline _0RL_cd_7963219a43724a61_f2000000(LocalCallFn lcfn,const char* op_,size_t oplen,_CORBA_Boolean upcall=0): omniCallDescriptor(lcfn, op_, oplen, 0, _user_exns, 0, upcall) {
+ }
+ static const char* const _user_exns[];
+ const char* arg_0;
+ const char* arg_1;
+ const char* arg_2;
+ const CORBA::StructMemberSeq* arg_3;
+ CORBA::ExceptionDef_var result;
+ };
+ static void _0RL_lcfn_7963219a43724a61_03000000(omniCallDescriptor* cd, omniServant* svnt) {
+ _0RL_cd_7963219a43724a61_f2000000* tcd = (_0RL_cd_7963219a43724a61_f2000000*)cd;
+ CORBA::_impl_Container* impl = (CORBA::_impl_Container*) svnt->_ptrToInterface(CORBA::Container::_PD_repoId);
+ tcd->result = impl->create_exception(tcd->arg_0, tcd->arg_1, tcd->arg_2, *tcd->arg_3);
+ }
+ CORBA::ExceptionDef_ptr CORBA::_objref_Container::create_exception(const char* id, const char* name, const char* version, const ::CORBA::StructMemberSeq& members) {
+ _0RL_cd_7963219a43724a61_f2000000 _call_desc(_0RL_lcfn_7963219a43724a61_03000000, "create_exception", 17);
+ }
+ POA_CORBA::StructDef::~StructDef() {
+ }
diff --git a/gcc/testsuite/g++.dg/torture/pr58585.C b/gcc/testsuite/g++.dg/torture/pr58585.C
new file mode 100644
index 000000000000..69fcf04ddc1b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr58585.C
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-options "-fpic" { target fpic } }
+struct A
+{
+ virtual void foo() {}
+ void bar();
+};
+void A::bar() { foo(); }
+
+struct B : virtual A
+{
+ virtual void foo() {}
+ char c;
+};
+
+struct C : virtual B
+{
+ C();
+};
+C::C() { bar(); }
diff --git a/gcc/testsuite/g++.dg/torture/pr59226.C b/gcc/testsuite/g++.dg/torture/pr59226.C
new file mode 100644
index 000000000000..cb0ebbe35f9f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr59226.C
@@ -0,0 +1,27 @@
+// { dg-do compile }
+struct A
+{
+ virtual void foo() {}
+};
+
+struct B
+{
+ virtual void foo() {}
+};
+
+struct C : virtual A {};
+
+struct D : virtual A, B
+{
+ virtual void foo() {}
+};
+
+struct E : C, D
+{
+ virtual void foo() {}
+};
+
+void bar(A* p)
+{
+ p->foo();
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr59743.c b/gcc/testsuite/gcc.c-torture/compile/pr59743.c
new file mode 100644
index 000000000000..8dadba594e59
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr59743.c
@@ -0,0 +1,23 @@
+/* PR middle-end/59743 */
+
+typedef union {
+ long all;
+ struct {
+ int low;
+ int high;
+ } s;
+} udwords;
+int a, b, c, d;
+void __udivmoddi4() {
+ udwords r;
+ d = __builtin_clz(0);
+ r.s.low = 0;
+ for (; d; --d) {
+ r.s.high = r.s.high << 1 | r.s.low >> a;
+ r.s.low = r.s.low << b >> 1;
+ int s = -r.all;
+ c = s;
+ r.all--;
+ }
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr59643.c b/gcc/testsuite/gcc.c-torture/execute/pr59643.c
new file mode 100644
index 000000000000..e3e8a6a38fca
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr59643.c
@@ -0,0 +1,39 @@
+/* PR tree-optimization/59643 */
+
+#define N 32
+
+__attribute__((noinline, noclone)) void
+foo (double *a, double *b, double *c, double d, double e, int n)
+{
+ int i;
+ for (i = 1; i < n - 1; i++)
+ a[i] = d * (b[i] + c[i] + a[i - 1] + a[i + 1]) + e * a[i];
+}
+
+double expected[] = {
+ 0.0, 10.0, 44.0, 110.0, 232.0, 490.0, 1020.0, 2078.0, 4152.0, 8314.0,
+ 16652.0, 33326.0, 66664.0, 133354.0, 266748.0, 533534.0, 1067064.0,
+ 2134138.0, 4268300.0, 8536622.0, 17073256.0, 34146538.0, 68293116.0,
+ 136586270.0, 273172536.0, 546345082.0, 1092690188.0, 2185380398.0,
+ 4370760808.0, 8741521642.0, 17483043324.0, 6.0
+};
+
+int
+main ()
+{
+ int i;
+ double a[N], b[N], c[N];
+ if (__DBL_MANT_DIG__ <= 35)
+ return 0;
+ for (i = 0; i < N; i++)
+ {
+ a[i] = (i & 3) * 2.0;
+ b[i] = (i & 7) - 4;
+ c[i] = i & 7;
+ }
+ foo (a, b, c, 2.0, 3.0, N);
+ for (i = 0; i < N; i++)
+ if (a[i] != expected[i])
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp b/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp
index c370ec645e6a..61085fd8f1f1 100644
--- a/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp
+++ b/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp
@@ -51,13 +51,15 @@ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -f
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -O3 -std=c99" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -g -O0 -std=c99" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O1 -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -std=c99 -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -ftree-vectorize -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -g -fcilkplus" " "
-if { [check_effective_target_lto] } {
- dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -flto -g -fcilkplus" " "
+if { [check_libcilkrts_available] } {
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g " " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O1 " " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -std=c99 " " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -ftree-vectorize " " "
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -g " " "
+ if { [check_effective_target_lto] } {
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -flto -g " " "
+ }
}
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/SE/*.c]] " -g" " "
diff --git a/gcc/testsuite/gcc.dg/delay-slot-1.c b/gcc/testsuite/gcc.dg/delay-slot-1.c
index f3bcd8ec7564..bfc0273e4ff5 100644
--- a/gcc/testsuite/gcc.dg/delay-slot-1.c
+++ b/gcc/testsuite/gcc.dg/delay-slot-1.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
-/* { dg-options "-O2 -mabi=64" { target mips-*-linux-* } } */
+/* { dg-options "-O2 -mabi=64" { target { mips*-*-linux* && mips64 } } } */
struct offset_v1 {
int k_uniqueness;
diff --git a/gcc/testsuite/gcc.dg/gomp/pr59669-1.c b/gcc/testsuite/gcc.dg/gomp/pr59669-1.c
new file mode 100644
index 000000000000..c72156d4bd0b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr59669-1.c
@@ -0,0 +1,9 @@
+/* PR middle-end/59669 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+#pragma omp declare simd linear(a)
+void
+foo (int a)
+{
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr59669-2.c b/gcc/testsuite/gcc.dg/gomp/pr59669-2.c
new file mode 100644
index 000000000000..f6aad8998f1f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr59669-2.c
@@ -0,0 +1,9 @@
+/* PR middle-end/59669 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+#pragma omp declare simd uniform(a) aligned(a:32)
+void
+bar (int *a)
+{
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/pr59008.c b/gcc/testsuite/gcc.dg/ipa/pr59008.c
new file mode 100644
index 000000000000..b7296724300f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr59008.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+typedef int (*funct)(int, int, int);
+
+extern int f(int, int, int);
+extern int g(int, int, int);
+extern int h(int, funct, funct);
+
+static int baz(int x, int y, int z)
+{
+ return x + y + z;
+}
+
+static int bar(int n, funct f1, funct f2)
+{
+ return h(n, f1, f2) + f1(0, 1, 2);
+}
+
+static int foo(int n, funct f1, funct f2)
+{
+ return bar(n, f1, f2) + f2(0, 1, 2);
+}
+
+int main(void)
+{
+ return foo(0, f, g)
+#ifndef ICE2
+ + foo(0, baz, g)
+#endif
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/pr59610.c b/gcc/testsuite/gcc.dg/ipa/pr59610.c
new file mode 100644
index 000000000000..fc0933441e82
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr59610.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct A { int a; };
+extern void *y;
+
+__attribute__((optimize (0))) void
+foo (void *p, struct A x)
+{
+ foo (y, x);
+}
diff --git a/gcc/testsuite/gcc.dg/pr46309.c b/gcc/testsuite/gcc.dg/pr46309.c
index ee154ccd2f3c..9275015049e2 100644
--- a/gcc/testsuite/gcc.dg/pr46309.c
+++ b/gcc/testsuite/gcc.dg/pr46309.c
@@ -1,5 +1,5 @@
/* PR tree-optimization/46309 */
-/* { dg-do compile } */
+/* { dg-do compile { target { ! { cris*-*-* } } } } */
/* { dg-options "-O2 -fdump-tree-reassoc-details" } */
/* The transformation depends on BRANCH_COST being greater than 1
(see the notes in the PR), so try to force that. */
diff --git a/gcc/testsuite/gcc.dg/pr57773.c b/gcc/testsuite/gcc.dg/pr57773.c
new file mode 100644
index 000000000000..1c309506d108
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr57773.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -Wpedantic" } */
+
+enum e { A };
+struct { enum e b: 2; } s1;
+struct { signed char b: 2; } s2;
+struct { unsigned char b: 2; } s3;
+struct { short b: 2; } s4;
+struct { unsigned short b: 2; } s5;
+struct { long int b: 2; } s6;
+struct { unsigned long int b: 2; } s7;
+struct { long long int b: 2; } s8;
+struct { unsigned long long int b: 2; } s9;
diff --git a/gcc/testsuite/gcc.dg/pr58668.c b/gcc/testsuite/gcc.dg/pr58668.c
new file mode 100644
index 000000000000..3e09508dc16e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr58668.c
@@ -0,0 +1,25 @@
+/* PR rtl-optimization/58668 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-mthumb" { target { { arm*-*-* } && arm_thumb2_ok } } } */
+
+void *fn1 (void *);
+void *fn2 (void *, const char *);
+void fn3 (void *);
+void fn4 (void *, int);
+
+void *
+test (void *x)
+{
+ void *a, *b;
+ if (!(a = fn1 (x)))
+ return (void *) 0;
+ if (!(b = fn2 (a, "w")))
+ {
+ fn3 (a);
+ return (void *) 0;
+ }
+ fn3 (a);
+ fn4 (b, 1);
+ return b;
+}
diff --git a/gcc/testsuite/gcc.dg/pr59350-2.c b/gcc/testsuite/gcc.dg/pr59350-2.c
new file mode 100644
index 000000000000..2fea85fcf719
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr59350-2.c
@@ -0,0 +1,29 @@
+/* PR debug/59350 */
+
+/* { dg-do compile } */
+/* { dg-options "-O -g " } */
+
+typedef struct
+{
+ void *v;
+ int len;
+ int sign;
+} ZVALUE;
+
+extern int pred (ZVALUE);
+
+static unsigned long
+small_factor (ZVALUE z)
+{
+ if (z.len > 0)
+ return 0;
+
+ return pred (z) ? -1 : 0;
+}
+
+unsigned long
+zfactor (ZVALUE z)
+{
+ z.sign = 0;
+ return small_factor (z);
+}
diff --git a/gcc/testsuite/gcc.dg/pr59350.c b/gcc/testsuite/gcc.dg/pr59350.c
index be186873ac58..fa632454ae1e 100644
--- a/gcc/testsuite/gcc.dg/pr59350.c
+++ b/gcc/testsuite/gcc.dg/pr59350.c
@@ -1,4 +1,4 @@
-/* PR rtl-optimization/59350 */
+/* PR debug/59350 */
/* Testcase by Ryan Mansfield <rmansfield@qnx.com> */
/* { dg-do compile } */
diff --git a/gcc/testsuite/gcc.dg/pr59471.c b/gcc/testsuite/gcc.dg/pr59471.c
new file mode 100644
index 000000000000..7f2a7870a0e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr59471.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+typedef unsigned char uint8x4_t
+__attribute__ ((__vector_size__ (4)));
+
+typedef unsigned short uint16x8_t
+__attribute__ ((__vector_size__ (16)));
+
+typedef unsigned int uint32x4_t
+__attribute__ ((__vector_size__ (16)));
+
+void
+foo (uint16x8_t *x, uint8x4_t *y)
+{
+ *y = (uint8x4_t) ((uint32x4_t) (*x))[0];
+}
diff --git a/gcc/testsuite/gcc.dg/pr59630.c b/gcc/testsuite/gcc.dg/pr59630.c
new file mode 100644
index 000000000000..6a3c72552f5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr59630.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+_Bool foo()
+{
+ _Bool (*f)(int) = __builtin_abs; /* { dg-warning "" } */
+ return f(0);
+}
diff --git a/gcc/testsuite/gcc.dg/pr59643.c b/gcc/testsuite/gcc.dg/pr59643.c
new file mode 100644
index 000000000000..f4df5e5b2212
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr59643.c
@@ -0,0 +1,15 @@
+/* PR tree-optimization/59643 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-pcom-details" } */
+
+void
+foo (double *a, double *b, double *c, double d, double e, int n)
+{
+ int i;
+ for (i = 1; i < n - 1; i++)
+ a[i] = d * (b[i] + c[i] + a[i - 1] + a[i + 1]) + e * a[i];
+}
+
+/* { dg-final { scan-tree-dump-times "Before commoning:" 1 "pcom" } } */
+/* { dg-final { scan-tree-dump-times "Unrolling 2 times" 1 "pcom" } } */
+/* { dg-final { cleanup-tree-dump "pcom" } } */
diff --git a/gcc/testsuite/gcc.dg/pr59670.c b/gcc/testsuite/gcc.dg/pr59670.c
new file mode 100644
index 000000000000..a68253b4b637
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr59670.c
@@ -0,0 +1,15 @@
+/* PR middle-end/59670 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fopenmp-simd" } */
+
+int d[1024];
+
+int
+foo (int j, int b)
+{
+ int l, c = 0;
+#pragma omp simd reduction(+: c)
+ for (l = 0; l < b; ++l)
+ c += d[j + l];
+ return c;
+}
diff --git a/gcc/testsuite/gcc.dg/pr59722.c b/gcc/testsuite/gcc.dg/pr59722.c
new file mode 100644
index 000000000000..7626fd22e1d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr59722.c
@@ -0,0 +1,36 @@
+/* PR ipa/59722 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+extern void abrt (const char *, int) __attribute__((noreturn));
+void baz (int *, int *);
+
+static inline int
+bar (void)
+{
+ return 1;
+}
+
+static inline void
+foo (int *x, int y (void))
+{
+ while (1)
+ {
+ int a = 0;
+ if (*x)
+ {
+ baz (x, &a);
+ while (a && !y ())
+ ;
+ break;
+ }
+ abrt ("", 1);
+ }
+}
+
+void
+test (int x)
+{
+ foo (&x, bar);
+ foo (&x, bar);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57748-3.c b/gcc/testsuite/gcc.dg/torture/pr57748-3.c
new file mode 100644
index 000000000000..5ddb6099c2cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57748-3.c
@@ -0,0 +1,40 @@
+/* PR middle-end/57748 */
+/* { dg-do run } */
+/* wrong code in expand_expr_real_1. */
+
+#include <stdlib.h>
+
+extern void abort (void);
+
+typedef long long V
+ __attribute__ ((vector_size (2 * sizeof (long long)), may_alias));
+
+typedef struct S { V a; V b[0]; } P __attribute__((aligned (1)));
+
+struct __attribute__((packed)) T { char c; P s; };
+
+void __attribute__((noinline, noclone))
+check (P *p)
+{
+ if (p->b[0][0] != 3 || p->b[0][1] != 4)
+ abort ();
+}
+
+void __attribute__((noinline, noclone))
+foo (struct T *t)
+{
+ V a = { 3, 4 };
+ t->s.b[0] = a;
+}
+
+int
+main ()
+{
+ struct T *t = (struct T *) calloc (128, 1);
+
+ foo (t);
+ check (&t->s);
+
+ free (t);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57748-4.c b/gcc/testsuite/gcc.dg/torture/pr57748-4.c
new file mode 100644
index 000000000000..455cb3d3278b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57748-4.c
@@ -0,0 +1,40 @@
+/* PR middle-end/57748 */
+/* { dg-do run } */
+/* wrong code in expand_expr_real_1. */
+
+#include <stdlib.h>
+
+extern void abort (void);
+
+typedef long long V
+ __attribute__ ((vector_size (2 * sizeof (long long)), may_alias));
+
+typedef struct S { V b[1]; } P __attribute__((aligned (1)));
+
+struct __attribute__((packed)) T { char c; P s; };
+
+void __attribute__((noinline, noclone))
+check (P *p)
+{
+ if (p->b[1][0] != 3 || p->b[1][1] != 4)
+ abort ();
+}
+
+void __attribute__((noinline, noclone))
+foo (struct T *t)
+{
+ V a = { 3, 4 };
+ t->s.b[1] = a;
+}
+
+int
+main ()
+{
+ struct T *t = (struct T *) calloc (128, 1);
+
+ foo (t);
+ check (&t->s);
+
+ free (t);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr59374-3.c b/gcc/testsuite/gcc.dg/torture/pr59374-3.c
new file mode 100644
index 000000000000..ab0014d8f13f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr59374-3.c
@@ -0,0 +1,21 @@
+extern void abort (void);
+
+static struct X { void *a; void *b; } a, b;
+
+void __attribute__((noinline)) foo (void)
+{
+ void *tem = a.b;
+ a.b = (void *)0;
+ b.b = tem;
+ b.a = a.a;
+ a.a = tem;
+}
+
+int main()
+{
+ a.b = &a;
+ foo ();
+ if (b.b != &a)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr59715.c b/gcc/testsuite/gcc.dg/torture/pr59715.c
new file mode 100644
index 000000000000..19c09de55d7e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr59715.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+int a = 2, b;
+
+int
+main ()
+{
+ int c;
+ if (!b)
+ {
+ b = a;
+ c = a == 0 ? 1 : 1 % a;
+ if (c)
+ b = 0;
+ }
+ if (b != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
index 1a4bf4a4444f..59951e2bf810 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-* hppa*-*-* mips*-*-*"} } } */
/* { dg-options "-O2 -fdump-tree-forwprop1" } */
/* Skip on ARM Cortex-M, where LOGICAL_OP_NON_SHORT_CIRCUIT is set to false,
leading to two conditional jumps when evaluating an && condition. Forwprop1
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c
index 303b3f32bd9f..865ab0b617c5 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c
@@ -1,7 +1,7 @@
/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
/* { dg-options "-O2 -fno-inline -fdump-tree-reassoc1-details" } */
-/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
+/* { dg-additional-options "-mbranch-cost=2" { target mips*-*-* avr-*-* } } */
int test (int a, int b, int c)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-33.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-33.c
index bb27daa8c14e..6782972365f9 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-33.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-33.c
@@ -1,7 +1,7 @@
-/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
+/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* hppa*-*-*"} } } */
/* { dg-options "-O2 -fno-inline -fdump-tree-reassoc1-details" } */
-/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
+/* { dg-additional-options "-mbranch-cost=2" { target mips*-*-* avr-*-* } } */
int test (int a, int b, int c)
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-34.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-34.c
index 156e18242222..272455b371db 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-34.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-34.c
@@ -1,7 +1,7 @@
-/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
+/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* hppa*-*-*"} } } */
/* { dg-options "-O2 -fno-inline -fdump-tree-reassoc1-details" } */
-/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
+/* { dg-additional-options "-mbranch-cost=2" { target mips*-*-* avr-*-* } } */
int test (int a, int b, int c)
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-35.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-35.c
index c486b783dce2..8e03ad6b1a53 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-35.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-35.c
@@ -1,7 +1,7 @@
-/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
+/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* hppa*-*-*"} } } */
/* { dg-options "-O2 -fno-inline -fdump-tree-reassoc1-details" } */
-/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
+/* { dg-additional-options "-mbranch-cost=2" { target mips*-*-* avr-*-* } } */
int test (unsigned int a, int b, int c)
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-36.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-36.c
index 930dbe289fb4..8bd507ce3acf 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-36.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-36.c
@@ -1,7 +1,7 @@
-/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
+/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* hppa*-*-*"} } } */
/* { dg-options "-O2 -fno-inline -fdump-tree-reassoc1-details" } */
-/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
+/* { dg-additional-options "-mbranch-cost=2" { target mips*-*-* avr-*-* } } */
int test (int a, int b, int c)
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c
index efc8a7133c9e..4b09c5db09d8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-* mips*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c
index 3be2310e9b5b..8d42dfb31a05 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-* mips*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c
index c22a0e04c113..858bed1e640e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-* mips*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c
index aa0970dee7f6..fecb510c0097 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-* mips*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c
index 5a09fa0f49d5..cbff587f5dd7 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c
@@ -3,7 +3,7 @@
/* Skip on S/390 and avr. Lower values in BRANCH_COST lead to two conditional
jumps when evaluating an && condition. VRP is not able to optimize
this. */
-/* { dg-do compile { target { ! "mips*-*-* arc*-*-* s390*-*-* avr-*-* mn10300-*-*" } } } */
+/* { dg-do compile { target { ! "mips*-*-* arc*-*-* s390*-*-* avr-*-* mn10300-*-* hppa*-*-*" } } } */
/* { dg-options "-O2 -fdump-tree-vrp1 -fdump-tree-dom1 -fdump-tree-vrp2" } */
/* { dg-additional-options "-march=i586" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
/* Skip on ARM Cortex-M, where LOGICAL_OP_NON_SHORT_CIRCUIT is set to false,
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
index 9aff0a6c46f8..a51d696316d2 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
@@ -1,7 +1,7 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-* hppa*-*-* mips*-*-*"} } } */
/* { dg-options "-O2 -fdump-tree-vrp2-details -fdump-tree-cddce2-details" } */
-/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
+/* { dg-additional-options "-mbranch-cost=2" { target mips*-*-* avr-*-* } } */
/* Skip on ARM Cortex-M, where LOGICAL_OP_NON_SHORT_CIRCUIT is set to false,
leading to two conditional jumps when evaluating an && condition. VRP is
not able to optimize this. */
diff --git a/gcc/testsuite/gcc.dg/vect/pr59519-1.c b/gcc/testsuite/gcc.dg/vect/pr59519-1.c
new file mode 100644
index 000000000000..428d4ec32e7b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr59519-1.c
@@ -0,0 +1,19 @@
+/* PR tree-optimization/59519 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+
+int a, b, c, d;
+
+void
+foo (void)
+{
+ for (; d; d++)
+ for (b = 0; b < 14; b++)
+ {
+ c |= 1;
+ if (a)
+ break;
+ }
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr59519-2.c b/gcc/testsuite/gcc.dg/vect/pr59519-2.c
new file mode 100644
index 000000000000..2b109d2557d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr59519-2.c
@@ -0,0 +1,20 @@
+/* PR tree-optimization/59519 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+
+struct S { int f0; } d;
+int a[8] = { 0 }, b, c, e;
+
+void
+foo (void)
+{
+ for (; e < 1; e++)
+ for (b = 0; b < 7; b++)
+ {
+ c |= (a[b + 1] != 0);
+ if (d.f0)
+ break;
+ }
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-clone-10.c b/gcc/testsuite/gcc.dg/vect/vect-simd-clone-10.c
index 923a9453c25f..93cb9f993c0d 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-simd-clone-10.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-clone-10.c
@@ -1,3 +1,4 @@
+/* { dg-do run } */
/* { dg-require-effective-target vect_simd_clones } */
/* { dg-additional-options "-fopenmp-simd" } */
/* { dg-additional-options "-mavx" { target avx_runtime } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-clone-12.c b/gcc/testsuite/gcc.dg/vect/vect-simd-clone-12.c
index 279abd7c6824..0fd5890e9291 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-simd-clone-12.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-clone-12.c
@@ -1,3 +1,4 @@
+/* { dg-do run } */
/* { dg-require-effective-target vect_simd_clones } */
/* { dg-additional-options "-fopenmp-simd" } */
/* { dg-additional-options "-mavx" { target avx_runtime } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp
index b0b7e2237c3a..fa11e7e5eea6 100644
--- a/gcc/testsuite/gcc.dg/vect/vect.exp
+++ b/gcc/testsuite/gcc.dg/vect/vect.exp
@@ -41,6 +41,28 @@ if ![check_vect_support_and_set_flags] {
# These flags are used for all targets.
lappend DEFAULT_VECTCFLAGS "-ftree-vectorize" "-fno-vect-cost-model" "-fno-common"
+# If the linker used understands -M <mapfile>, pass it to clear hardware
+# capabilities set by the Sun assembler.
+# Try mapfile syntax v2 first which is the only way to clear hwcap_2 flags.
+set clearcap_ldflags "-Wl,-M,$srcdir/gcc.target/i386/clearcapv2.map"
+
+if ![check_no_compiler_messages mapfilev2 executable {
+ int main (void) { return 0; }
+} $clearcap_ldflags ] {
+ # If this doesn't work, fall back to the less capable v1 syntax.
+ set clearcap_ldflags "-Wl,-M,$srcdir/gcc.target/i386/clearcap.map"
+
+ if ![check_no_compiler_messages mapfile executable {
+ int main (void) { return 0; }
+ } $clearcap_ldflags ] {
+ unset clearcap_ldflags
+ }
+}
+
+if [info exists clearcap_ldflags] {
+ lappend DEFAULT_VECTCFLAGS $clearcap_ldflags
+}
+
# Initialize `dg'.
dg-init
diff --git a/gcc/testsuite/gcc.target/aarch64/cmn-neg.c b/gcc/testsuite/gcc.target/aarch64/cmn-neg.c
index 05c8bbff5be9..ab264e798efa 100644
--- a/gcc/testsuite/gcc.target/aarch64/cmn-neg.c
+++ b/gcc/testsuite/gcc.target/aarch64/cmn-neg.c
@@ -6,7 +6,7 @@ extern void abort (void);
void __attribute__ ((noinline))
foo_s32 (int a, int b)
{
- if (a < -b)
+ if (a == -b)
abort ();
}
/* { dg-final { scan-assembler "cmn\tw\[0-9\]" } } */
@@ -14,7 +14,7 @@ foo_s32 (int a, int b)
void __attribute__ ((noinline))
foo_s64 (long long a, long long b)
{
- if (a < -b)
+ if (a == -b)
abort ();
}
/* { dg-final { scan-assembler "cmn\tx\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/cmn-neg2.c b/gcc/testsuite/gcc.target/aarch64/cmn-neg2.c
new file mode 100644
index 000000000000..ca45a53435f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cmn-neg2.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+
+/* It's unsafe to use CMN in these comparisons. */
+
+void __attribute__ ((noinline))
+foo_s32 (int a, int b)
+{
+ if (a < -b)
+ abort ();
+}
+
+void __attribute__ ((noinline))
+foo_s64 (unsigned long long a, unsigned long long b)
+{
+ if (a > -b)
+ abort ();
+}
+
+
+int
+main (void)
+{
+ int a = 30;
+ int b = 42;
+ foo_s32 (a, b);
+ foo_s64 (a, b);
+ return 0;
+}
+/* { dg-final { scan-assembler-not "cmn\t" } } */
+
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon-nested-apcs.c b/gcc/testsuite/gcc.target/arm/neon-nested-apcs.c
new file mode 100644
index 000000000000..cd92d7d33e7a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon-nested-apcs.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_hw } */
+/* { dg-options "-fno-omit-frame-pointer -mapcs-frame -O" }
+/* { dg-add-options arm_neon } */
+
+extern void abort (void);
+
+float data;
+
+void __attribute__((noinline, noclone)) bar (float f)
+{
+ data = f;
+}
+
+float __attribute__((noinline, noclone)) foo (float f)
+{
+ int error_reported = 0;
+
+ void __attribute__((noinline, noclone))
+ nested (int a, int b, int c, int d, float f0, float f1, float f2, float f3)
+ {
+ float e;
+
+ if (f3 > f2)
+ e = f3;
+ else
+ e = f2;
+
+ if (f0 - f1 > e)
+ {
+ error_reported = a + b + c + d;
+ bar (f0);
+ bar (e);
+ }
+ }
+
+ nested (1, 2, 3, 4, 1.0, 1.0, 3.5, 4.2);
+ return f + (float)error_reported;
+}
+
+#define PI 3.1415927f
+
+int main (void)
+{
+ if (foo (PI) != PI)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/arm/neon/vst1Q_laneu64-1.c b/gcc/testsuite/gcc.target/arm/neon/vst1Q_laneu64-1.c
new file mode 100644
index 000000000000..5f4c927b6e0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vst1Q_laneu64-1.c
@@ -0,0 +1,25 @@
+/* Test the `vst1Q_laneu64' ARM Neon intrinsic. */
+
+/* Detect ICE in the case of unaligned memory address. */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+
+unsigned char dummy_store[1000];
+
+void
+foo (char* addr)
+{
+ uint8x16_t vdata = vld1q_u8 (addr);
+ vst1q_lane_u64 ((uint64_t*) &dummy_store, vreinterpretq_u64_u8 (vdata), 0);
+}
+
+uint64_t
+bar (uint64x2_t vdata)
+{
+ vdata = vld1q_lane_u64 ((uint64_t*) &dummy_store, vdata, 0);
+ return vgetq_lane_u64 (vdata, 0);
+}
diff --git a/gcc/testsuite/gcc.target/i386/asm-1.c b/gcc/testsuite/gcc.target/i386/asm-1.c
index 999c5767966d..cd60a09bd7fe 100644
--- a/gcc/testsuite/gcc.target/i386/asm-1.c
+++ b/gcc/testsuite/gcc.target/i386/asm-1.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-require-effective-target ia32 } */
-/* { dg-options "-m32" } */
+/* { dg-options "" } */
register unsigned int EAX asm ("r14"); /* { dg-error "register name" } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vcmppd-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vcmppd-2.c
index 333a83576b2a..add23d07a19e 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vcmppd-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vcmppd-2.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
-/* { dg-options "-O2 -mavx512f" } */
+/* { dg-options "-O2 -mavx512f -std=c99" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target c99_runtime } */
#define AVX512F
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vcmpps-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vcmpps-2.c
index 5ffd470dbe2f..15c314e2d60e 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vcmpps-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vcmpps-2.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
-/* { dg-options "-O2 -mavx512f" } */
+/* { dg-options "-O2 -mavx512f -std=c99" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target c99_runtime } */
#define AVX512F
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmpd-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmpd-2.c
index 263fecd5f71b..d4ddd32145b2 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmpd-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmpd-2.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
-/* { dg-options "-O2 -mavx512f" } */
+/* { dg-options "-O2 -mavx512f -std=gnu99" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target c99_runtime } */
#define AVX512F
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmps-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmps-2.c
index 9fca53705de0..6c2539d0f4e8 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmps-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmps-2.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
-/* { dg-options "-O2 -mavx512f" } */
+/* { dg-options "-O2 -mavx512f -std=gnu99" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target c99_runtime } */
#define AVX512F
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmsd-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmsd-2.c
index ebd288ed2686..1344c7fd1bc8 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmsd-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmsd-2.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
-/* { dg-options "-mavx512f -O2" } */
+/* { dg-options "-mavx512f -O2 -std=gnu99" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target c99_runtime } */
#include "avx512f-check.h"
#include "avx512f-helper.h"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmss-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmss-2.c
index 50830b8bd365..25e165ff51dd 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmss-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmss-2.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
-/* { dg-options "-mavx512f -O2" } */
+/* { dg-options "-mavx512f -O2 -std=gnu99" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target c99_runtime } */
#include "avx512f-check.h"
#include "avx512f-helper.h"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vgetmantpd-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vgetmantpd-2.c
index 473466b1e53a..0209021b8b18 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vgetmantpd-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vgetmantpd-2.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
-/* { dg-options "-O2 -mavx512f" } */
+/* { dg-options "-O2 -mavx512f -std=c99" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target c99_runtime } */
#define AVX512F
@@ -72,6 +73,7 @@ get_norm_mant (double source, int signctrl, int interv)
}
#endif
+void static
CALC (double *r, double *s, int interv, int signctrl)
{
int i;
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vgetmantps-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vgetmantps-2.c
index b8ea24d891b8..25e41d182175 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vgetmantps-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vgetmantps-2.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
-/* { dg-options "-O2 -mavx512f" } */
+/* { dg-options "-O2 -mavx512f -std=c99" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target c99_runtime } */
#define AVX512F
@@ -73,6 +74,7 @@ get_norm_mant (float source, int signctrl, int interv)
}
#endif
+void static
CALC (float *r, float *s, int interv, int signctrl)
{
int i;
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vgetmantsd-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vgetmantsd-2.c
index 50d98a45df4c..563d3cc221c6 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vgetmantsd-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vgetmantsd-2.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
-/* { dg-options "-mavx512f -O2" } */
+/* { dg-options "-mavx512f -O2 -std=c99" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target c99_runtime } */
#include "avx512f-check.h"
#include "avx512f-helper.h"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vgetmantss-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vgetmantss-2.c
index 291c0df77e79..3ffab4ee1552 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vgetmantss-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vgetmantss-2.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
-/* { dg-options "-mavx512f -O2" } */
+/* { dg-options "-mavx512f -O2 -std=c99" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target c99_runtime } */
#include "avx512f-check.h"
#include "avx512f-helper.h"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-1.c b/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-1.c
index b8af781834e8..79dbf9dd37a0 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-1.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-mavx512f -O2" } */
-/* { dg-final { scan-assembler-times "vmovdqu32\[ \\t\]+\[^\n\]*\\)\[^\n\]*%zmm\[0-9\]\[^\{\]" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[36\]\[24\]\[ \\t\]+\[^\n\]*\\)\[^\n\]*%zmm\[0-9\]\[^\{\]" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu32\[ \\t\]+\[^\n\]*\\)\[^\n\]*%zmm\[0-9\]\{%k\[1-7\]\}\[^\{\]" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu32\[ \\t\]+\[^\n\]*\\)\[^\n\]*%zmm\[0-9\]\{%k\[1-7\]\}\{z\}" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu32\[ \\t\]+\[^\n\]*%zmm\[0-9\]\[^\n\]*\\)\[^\{\]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/incoming-5.c b/gcc/testsuite/gcc.target/i386/incoming-5.c
index 9bbecdb95e13..f68eefcb9094 100644
--- a/gcc/testsuite/gcc.target/i386/incoming-5.c
+++ b/gcc/testsuite/gcc.target/i386/incoming-5.c
@@ -1,6 +1,6 @@
/* PR middle-end/37009 */
/* { dg-do compile { target { { ! *-*-darwin* } && ia32 } } } */
-/* { dg-options "-m32 -mincoming-stack-boundary=2 -mpreferred-stack-boundary=2" } */
+/* { dg-options "-mincoming-stack-boundary=2 -mpreferred-stack-boundary=2" } */
extern void bar (double *);
diff --git a/gcc/testsuite/gcc.target/i386/intrinsics_4.c b/gcc/testsuite/gcc.target/i386/intrinsics_4.c
index 4e124c90ef84..e7c074b31cb3 100644
--- a/gcc/testsuite/gcc.target/i386/intrinsics_4.c
+++ b/gcc/testsuite/gcc.target/i386/intrinsics_4.c
@@ -12,3 +12,10 @@ foo (void)
{
a[0] = _mm256_and_ps (b[0], c[0]);
}
+
+/* Try again with a combination of target and optimization attributes. */
+void __attribute__((target ("avx"), optimize(3)))
+bar (void)
+{
+ a[0] = _mm256_and_ps (b[0], c[0]);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr47735.c b/gcc/testsuite/gcc.target/i386/pr47735.c
new file mode 100644
index 000000000000..0d44df4d5c9e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr47735.c
@@ -0,0 +1,16 @@
+/* PR middle-end/47735 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+unsigned
+mulh (unsigned a, unsigned b)
+{
+ unsigned long long l __attribute__ ((aligned (32)))
+ = ((unsigned long long) a * (unsigned long long) b) >> 32;
+ return l;
+}
+
+/* No need to dynamically realign the stack here. */
+/* { dg-final { scan-assembler-not "and\[^\n\r]*%\[re\]sp" } } */
+/* Nor use a frame pointer. */
+/* { dg-final { scan-assembler-not "%\[re\]bp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr53623.c b/gcc/testsuite/gcc.target/i386/pr53623.c
new file mode 100644
index 000000000000..35c578bd618f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr53623.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target {! ia32 } } } */
+/* { dg-options "-O2 -fdump-rtl-ree" } */
+
+
+#include <stdint.h>
+
+typedef (*inst_t)(int64_t rdi, int64_t rsi, int64_t rdx);
+
+int16_t code[256];
+inst_t dispatch[256];
+
+void an_inst(int64_t rdi, int64_t rsi, int64_t rdx) {
+ rdx = code[rdx];
+ uint8_t inst = (uint8_t) rdx;
+ rdx >>= 8;
+ dispatch[inst](rdi, rsi, rdx);
+}
+
+int main(void) {
+ return 0;
+}
+
+/* { dg-final { scan-rtl-dump "copy needed" "ree" } } */
+/* { dg-final { cleanup-rtl-dump "ree" } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/pr55433.c b/gcc/testsuite/gcc.target/i386/pr55433.c
index b79b16dabdff..6a2602ad424c 100644
--- a/gcc/testsuite/gcc.target/i386/pr55433.c
+++ b/gcc/testsuite/gcc.target/i386/pr55433.c
@@ -1,5 +1,5 @@
-/* { dg-do compile {target { *-*-darwin* } } } */
-/* { dg-options "-O1 -m32" } */
+/* { dg-do compile { target { *-*-darwin* } } } */
+/* { dg-options "-O1" } */
typedef unsigned long long tick_t;
extern int foo(void);
diff --git a/gcc/testsuite/gcc.target/i386/pr56246.c b/gcc/testsuite/gcc.target/i386/pr56246.c
index 64a2527a5496..b4d527396d65 100644
--- a/gcc/testsuite/gcc.target/i386/pr56246.c
+++ b/gcc/testsuite/gcc.target/i386/pr56246.c
@@ -1,5 +1,5 @@
/* PR target/56225 */
-/* { dg-do compile { target { ia32 } } } */
+/* { dg-do compile { target { ia32 && fpic } } } */
/* { dg-options "-O2 -fno-omit-frame-pointer -march=i686 -fpic" } */
void NoBarrier_AtomicExchange (long long *ptr) {
diff --git a/gcc/testsuite/gcc.target/i386/pr57848.c b/gcc/testsuite/gcc.target/i386/pr57848.c
index d26b84c1b487..c686b372824b 100644
--- a/gcc/testsuite/gcc.target/i386/pr57848.c
+++ b/gcc/testsuite/gcc.target/i386/pr57848.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O1 -m32" } */
+/* { dg-options "-O1" } */
extern unsigned int __builtin_ia32_crc32si (unsigned int, unsigned int);
#pragma GCC target("sse4.2")
diff --git a/gcc/testsuite/gcc.target/i386/pr59099.c b/gcc/testsuite/gcc.target/i386/pr59099.c
index 7dc12ff3f7c7..cf4a8da7db1c 100644
--- a/gcc/testsuite/gcc.target/i386/pr59099.c
+++ b/gcc/testsuite/gcc.target/i386/pr59099.c
@@ -1,5 +1,6 @@
/* { dg-do run } */
-/* { dg-options "-O2 -fPIC -m32" } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -fPIC" } */
void (*pfn)(void);
diff --git a/gcc/testsuite/gcc.target/i386/pr59390.c b/gcc/testsuite/gcc.target/i386/pr59390.c
index 49ce02d1a218..7dc925ae9fbb 100644
--- a/gcc/testsuite/gcc.target/i386/pr59390.c
+++ b/gcc/testsuite/gcc.target/i386/pr59390.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-std=c99 -O3" } */
-#include "math.h"
+extern double fma (double, double, double);
void fun() __attribute__((target("fma")));
void
diff --git a/gcc/testsuite/gcc.target/i386/pr59390_1.c b/gcc/testsuite/gcc.target/i386/pr59390_1.c
index 2bd32a4ebdbd..632eb6f9a4f2 100644
--- a/gcc/testsuite/gcc.target/i386/pr59390_1.c
+++ b/gcc/testsuite/gcc.target/i386/pr59390_1.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-std=c99 -O3" } */
-#include "math.h"
+extern double fma (double, double, double);
void fun() __attribute__((target("fma")));
__attribute__((target("fma")))
diff --git a/gcc/testsuite/gcc.target/i386/pr59390_2.c b/gcc/testsuite/gcc.target/i386/pr59390_2.c
index 55a181a8ad48..6142a085eedb 100644
--- a/gcc/testsuite/gcc.target/i386/pr59390_2.c
+++ b/gcc/testsuite/gcc.target/i386/pr59390_2.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-std=c99 -O3 -mfma" } */
-#include "math.h"
+extern double fma (double, double, double);
void fun() __attribute__((target("fma")));
void
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-1.c b/gcc/testsuite/gcc.target/i386/pr59501-1.c
index 6a104eef1adc..18db93a9be4f 100644
--- a/gcc/testsuite/gcc.target/i386/pr59501-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr59501-1.c
@@ -1,6 +1,7 @@
/* PR target/59501 */
/* { dg-do run } */
/* { dg-options "-O2 -mavx -mno-accumulate-outgoing-args" } */
+/* { dg-require-effective-target avx } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-2.c b/gcc/testsuite/gcc.target/i386/pr59501-2.c
index 8ce177deb8e4..1d53d2ead6a0 100644
--- a/gcc/testsuite/gcc.target/i386/pr59501-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr59501-2.c
@@ -1,5 +1,6 @@
/* PR target/59501 */
/* { dg-do run } */
/* { dg-options "-O2 -mavx -maccumulate-outgoing-args" } */
+/* { dg-require-effective-target avx } */
#include "pr59501-1.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-3.c b/gcc/testsuite/gcc.target/i386/pr59501-3.c
index 0bf5ef6139a3..f27e9b3bb25c 100644
--- a/gcc/testsuite/gcc.target/i386/pr59501-3.c
+++ b/gcc/testsuite/gcc.target/i386/pr59501-3.c
@@ -1,6 +1,7 @@
/* PR target/59501 */
/* { dg-do run } */
/* { dg-options "-O2 -mavx -mno-accumulate-outgoing-args" } */
+/* { dg-require-effective-target avx } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-4.c b/gcc/testsuite/gcc.target/i386/pr59501-4.c
index 43a5ad2428aa..57da1078034b 100644
--- a/gcc/testsuite/gcc.target/i386/pr59501-4.c
+++ b/gcc/testsuite/gcc.target/i386/pr59501-4.c
@@ -1,5 +1,6 @@
/* PR target/59501 */
/* { dg-do run } */
/* { dg-options "-O2 -mavx -maccumulate-outgoing-args" } */
+/* { dg-require-effective-target avx } */
#include "pr59501-3.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-5.c b/gcc/testsuite/gcc.target/i386/pr59501-5.c
index f2feca8ec4f0..2ec9f0cb579a 100644
--- a/gcc/testsuite/gcc.target/i386/pr59501-5.c
+++ b/gcc/testsuite/gcc.target/i386/pr59501-5.c
@@ -1,6 +1,7 @@
/* PR target/59501 */
/* { dg-do run } */
/* { dg-options "-O2 -mavx -mno-accumulate-outgoing-args" } */
+/* { dg-require-effective-target avx } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-6.c b/gcc/testsuite/gcc.target/i386/pr59501-6.c
index d0ac2425b902..8d166cef2d71 100644
--- a/gcc/testsuite/gcc.target/i386/pr59501-6.c
+++ b/gcc/testsuite/gcc.target/i386/pr59501-6.c
@@ -1,5 +1,6 @@
/* PR target/59501 */
/* { dg-do run } */
/* { dg-options "-O2 -mavx -maccumulate-outgoing-args" } */
+/* { dg-require-effective-target avx } */
#include "pr59501-5.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr59644.c b/gcc/testsuite/gcc.target/i386/pr59644.c
new file mode 100644
index 000000000000..96006b3e338d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr59644.c
@@ -0,0 +1,42 @@
+/* PR target/59644 */
+/* { dg-do run { target lp64 } } */
+/* { dg-options "-O2 -ffreestanding -mno-sse -mpreferred-stack-boundary=3 -maccumulate-outgoing-args -mno-red-zone" } */
+
+/* This test uses __builtin_trap () instead of e.g. abort,
+ because due to -mpreferred-stack-boundary=3 it should not call
+ any library function from within main (). */
+
+#include <stdarg.h>
+
+__attribute__((noinline, noclone))
+int
+bar (int x, int y, int z, int w, const char *fmt, va_list ap)
+{
+ if (x != 1 || y != 2 || z != 3 || w != 4)
+ __builtin_trap ();
+ if (fmt[0] != 'f' || fmt[1] != 'o' || fmt[2] != 'o' || fmt[3])
+ __builtin_trap ();
+ if (va_arg (ap, int) != 5 || va_arg (ap, int) != 6
+ || va_arg (ap, long long) != 7LL)
+ __builtin_trap ();
+ return 9;
+}
+
+__attribute__((noinline, noclone, optimize ("Os")))
+int
+foo (const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ int r = bar (1, 2, 3, 4, fmt, ap);
+ va_end (ap);
+ return r;
+}
+
+int
+main ()
+{
+ if (foo ("foo", 5, 6, 7LL) != 9)
+ __builtin_trap ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/mips/pr59137.c b/gcc/testsuite/gcc.target/mips/pr59137.c
new file mode 100644
index 000000000000..898650656806
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr59137.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-options "-mno-plt" } */
+
+extern void abort (void);
+
+struct lispstruct
+{
+ int e;
+ int t;
+};
+
+struct lispstruct Cnil_body;
+struct lispstruct Ct_body;
+int nvalues;
+
+struct lispstruct * __attribute__ ((noinline))
+fLlistp (struct lispstruct *x0)
+{
+ if (x0 == &Cnil_body
+ || (((unsigned long) x0 >= 0x80000000) ? 0
+ : (!x0->e ? (x0 != &Cnil_body) : x0->t)))
+ x0 = &Ct_body;
+ else
+ x0 = &Cnil_body;
+ nvalues = 1;
+ return x0;
+}
+
+int main ()
+{
+ if (fLlistp ((struct lispstruct *) 0xa0000001) != &Cnil_body)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/mips/umips-branch-3.c b/gcc/testsuite/gcc.target/mips/umips-branch-3.c
new file mode 100644
index 000000000000..8717362e044b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/umips-branch-3.c
@@ -0,0 +1,10 @@
+/* { dg-options "(-mmicromips)" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+void MICROMIPS
+foo (void)
+{
+ return;
+}
+
+/* { dg-final { scan-assembler "\tjrc\t\\\$31\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/umips-branch-4.c b/gcc/testsuite/gcc.target/mips/umips-branch-4.c
new file mode 100644
index 000000000000..b346d11723fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/umips-branch-4.c
@@ -0,0 +1,12 @@
+/* { dg-options "(-mmicromips)" } */
+
+void foo (void);
+
+int MICROMIPS
+a (void)
+{
+ foo ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "\tjals\tfoo\n\tnop" } } */
diff --git a/gcc/testsuite/gcc.target/sh/cmpstrn.c b/gcc/testsuite/gcc.target/sh/cmpstrn.c
index bc72b2c51d22..3a1d0d1519ff 100644
--- a/gcc/testsuite/gcc.target/sh/cmpstrn.c
+++ b/gcc/testsuite/gcc.target/sh/cmpstrn.c
@@ -6,16 +6,23 @@
/* { dg-final { scan-assembler-not "jmp" } } */
/* { dg-final { scan-assembler-times "cmp/str" 1 } } */
-/* Test that the cmp/str loop is optimized out. */
-test01(const char *s1, const char *s2, int n)
+/* Test that cmp/str is not used for small lengths. */
+test01(const char *s1)
{
return __builtin_strncmp (s1, "abcde", 3);
}
/* Test that the cmp/str loop is used. */
-test02(const char *s1, const char *s2, int n)
+test02(const char *s1)
{
return __builtin_strncmp (s1, "abcdefghi", 8);
}
+/* Test that no call is generated */
+test03(const char *s1, int n)
+{
+ return __builtin_strncmp (s1, "abcde", n);
+}
+
+
diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_basics_6.f90 b/gcc/testsuite/gfortran.dg/alloc_comp_basics_6.f90
new file mode 100644
index 000000000000..3ed221db24f0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_basics_6.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+!
+! PR 58026: Bad error recovery for allocatable component of undeclared type
+!
+! Contributed by Joost VandeVondele <Joost.VandeVondele@mat.ethz.ch>
+
+ type sysmtx_t
+ type(ext_complex_t), allocatable :: S(:) ! { dg-error "has not been previously defined" }
+ end type
+
+end
diff --git a/gcc/testsuite/gfortran.dg/bind_c_procs_2.f90 b/gcc/testsuite/gfortran.dg/bind_c_procs_2.f90
new file mode 100644
index 000000000000..d3e751c3dc5e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/bind_c_procs_2.f90
@@ -0,0 +1,22 @@
+! { dg-do compile }
+!
+! PR 59023: [4.9 regression] ICE in gfc_search_interface with BIND(C)
+!
+! Contributed by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ type t
+ integer hidden
+ end type
+
+contains
+
+ subroutine bar
+ type(t) :: toto
+ interface
+ integer function helper() bind(c)
+ end function
+ end interface
+ toto = t(helper())
+ end subroutine
+
+end
diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_10_main.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_10_main.f03
index 2a4a53ba80da..5216fbedf6ae 100644
--- a/gcc/testsuite/gfortran.dg/binding_label_tests_10_main.f03
+++ b/gcc/testsuite/gfortran.dg/binding_label_tests_10_main.f03
@@ -11,3 +11,4 @@ program main
use binding_label_tests_10 ! { dg-error "Variable one from module binding_label_tests_10 with binding label c_one at .1. uses the same global identifier as entity at .2. from module binding_label_tests_10_main" }
use binding_label_tests_10_main
end program main
+! { dg-final { cleanup-modules "binding_label_tests_10" } }
diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_26a.f90 b/gcc/testsuite/gfortran.dg/binding_label_tests_26a.f90
new file mode 100644
index 000000000000..32cf07ae7c4a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/binding_label_tests_26a.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+!
+! PR 58182: [4.9 Regression] ICE with global binding name used as a FUNCTION
+!
+! Contributed by Andrew Bensons <abensonca@gmail.com>
+!
+! This file must be compiled BEFORE binding_label_tests_26b.f90, which it
+! should be because dejagnu will sort the files.
+
+module fg
+contains
+ function fffi(f)
+ interface
+ function f() bind(c)
+ end function
+ end interface
+ end function
+end module
+
+! { dg-final { keep-modules "" } }
diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_26b.f90 b/gcc/testsuite/gfortran.dg/binding_label_tests_26b.f90
new file mode 100644
index 000000000000..ad8426bc2c6f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/binding_label_tests_26b.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+!
+! PR 58182: [4.9 Regression] ICE with global binding name used as a FUNCTION
+!
+! Contributed by Andrew Bensons <abensonca@gmail.com>
+!
+! This file must be compiled AFTER binding_label_tests_26a.f90, which it
+! should be because dejagnu will sort the files.
+
+module f ! { dg-error "uses the same global identifier" }
+ use fg ! { dg-error "uses the same global identifier" }
+end module
+
+! { dg-final { cleanup-modules "fg f" } }
diff --git a/gcc/testsuite/gfortran.dg/class_allocate_16.f90 b/gcc/testsuite/gfortran.dg/class_allocate_16.f90
new file mode 100644
index 000000000000..28776084d866
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_allocate_16.f90
@@ -0,0 +1,28 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! PR 59589: [4.9 Regression] [OOP] Memory leak when deallocating polymorphic
+!
+! Contributed by Rich Townsend <townsend@astro.wisc.edu>
+
+ implicit none
+
+ type :: foo
+ real, allocatable :: x(:)
+ end type
+
+ type :: bar
+ type(foo) :: f
+ end type
+
+ class(bar), allocatable :: b
+
+ allocate(bar::b)
+ allocate(b%f%x(1000000))
+ b%f%x = 1.
+ deallocate(b)
+
+end
+
+! { dg-final { scan-tree-dump-times "__builtin_free" 4 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/inquire_10.f90 b/gcc/testsuite/gfortran.dg/inquire_10.f90
index 090653ecba59..bc7d6e36b387 100644
--- a/gcc/testsuite/gfortran.dg/inquire_10.f90
+++ b/gcc/testsuite/gfortran.dg/inquire_10.f90
@@ -10,6 +10,8 @@
inquire(file=trim(cwd) // '/cseq',number=unit)
if (unit /= 23) call abort
+ close(unit=23, status = 'delete')
+
inquire(file='foo/../cseq2',number=unit)
if (unit >= 0) call abort
inquire(file='cseq2',number=unit)
diff --git a/gcc/testsuite/gfortran.dg/inquire_15.f90 b/gcc/testsuite/gfortran.dg/inquire_15.f90
index e2aaf9ee17d3..ae94270ca8fa 100644
--- a/gcc/testsuite/gfortran.dg/inquire_15.f90
+++ b/gcc/testsuite/gfortran.dg/inquire_15.f90
@@ -22,6 +22,7 @@ open(99,access="sequential")
inquire(99, stream=str)
!print *, "str=",str
if (str /= "NO") goto 10
+close(99, status="delete")
stop
10 close(99, status="delete")
call abort
diff --git a/gcc/testsuite/gfortran.dg/lto/lto.exp b/gcc/testsuite/gfortran.dg/lto/lto.exp
index b848f9fdf3b3..3e329792eff4 100644
--- a/gcc/testsuite/gfortran.dg/lto/lto.exp
+++ b/gcc/testsuite/gfortran.dg/lto/lto.exp
@@ -34,17 +34,17 @@ load_lib gfortran-dg.exp
# Load the language-independent compabibility support procedures.
load_lib lto.exp
+# If LTO has not been enabled, bail.
+if { ![check_effective_target_lto] } {
+ return
+}
+
lto_init no-mathlib
# Define an identifier for use with this suite to avoid name conflicts
# with other lto tests running at the same time.
set sid "f_lto"
-# If LTO has not been enabled, bail.
-if { ![check_effective_target_lto] } {
- return
-}
-
# Main loop.
foreach src [lsort [glob -nocomplain $srcdir/$subdir/*_0.\[fF\]{,90,95,03,08} ]] {
# If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gfortran.dg/open_negative_unit_1.f90 b/gcc/testsuite/gfortran.dg/open_negative_unit_1.f90
index 6446436c8855..bbcf46b72a6a 100644
--- a/gcc/testsuite/gfortran.dg/open_negative_unit_1.f90
+++ b/gcc/testsuite/gfortran.dg/open_negative_unit_1.f90
@@ -6,6 +6,7 @@
program nutest
implicit none
+ logical l
integer id, ios
open(newunit=id, file="foo.txt", iostat=ios)
@@ -16,6 +17,14 @@ program nutest
close(id, status="delete")
+ open(unit=10, file="foo.txt", status="old", iostat=ios)
+ if (ios /= 0) call abort
+
+ close(10, status="delete")
+
open(-10, file="foo.txt", iostat=ios)
if (ios == 0) call abort
+
+ inquire(file="foo.txt", exist=l)
+ if (l) call abort
end program nutest
diff --git a/gcc/testsuite/gfortran.dg/pr16597.f90 b/gcc/testsuite/gfortran.dg/pr16597.f90
index c29147411a81..fc191efef7c7 100644
--- a/gcc/testsuite/gfortran.dg/pr16597.f90
+++ b/gcc/testsuite/gfortran.dg/pr16597.f90
@@ -19,7 +19,7 @@
open (UNIT=iunit,FORM='unformatted',ACCESS='direct',RECL=strlen)
write (iunit, rec=1) 'ABCD'
read (iunit, rec=1) string
- close (iunit)
+ close (iunit, status = 'delete')
if (string.ne.'ABCD') call abort
open (UNIT=iunit,FORM='unformatted',ACCESS='direct',STATUS='scratch',RECL=strlen)
diff --git a/gcc/testsuite/gfortran.dg/pr59700.f90 b/gcc/testsuite/gfortran.dg/pr59700.f90
new file mode 100644
index 000000000000..579d8a48c9ae
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr59700.f90
@@ -0,0 +1,40 @@
+! { dg-do run }
+! PR59700 Test case by Steve Kargl
+program foo
+
+ implicit none
+
+ character(len=80) msg
+ integer, parameter :: fd = 10
+ integer i1, i2, i3, i4
+ real x1, x2, x3, x4
+ complex c1, c2
+ logical a
+
+ open(unit=fd, status='scratch')
+ write(fd, '(A)') '1 2 3.4 q'
+
+ rewind(fd)
+ msg = 'ok'
+ read(fd, *, err=10, iomsg=msg) i1, i2, i3, i4
+10 if (msg /= 'Bad integer for item 3 in list input') call abort
+ rewind(fd)
+ msg = 'ok'
+ read(fd, *, err=20, iomsg=msg) x1, x2, x3, x4
+20 if (msg /= 'Bad real number in item 4 of list input') call abort
+ rewind(fd)
+ msg = 'ok'
+ read(fd, *, err=30, iomsg=msg) i1, x2, x1, a
+30 if (msg /= 'Bad logical value while reading item 4') call abort
+ rewind(fd)
+ read(fd, *, err=31, iomsg=msg) i1, x2, a, x1
+31 if (msg /= 'Bad repeat count in item 3 of list input') call abort
+ close(fd)
+ open(unit=fd, status='scratch')
+ write(fd, '(A)') '(1, 2) (3.4, q)'
+ rewind(fd)
+ msg = 'ok'
+ read(fd, *, err=40, iomsg=msg) c1, c2
+40 if (msg /= 'Bad floating point number for item 2') call abort
+ close(fd)
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/typebound_proc_32.f90 b/gcc/testsuite/gfortran.dg/typebound_proc_32.f90
new file mode 100644
index 000000000000..00ae9c732633
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_proc_32.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+!
+! PR 59547: [OOP] Problem with using tbp specification function in multiple class procedures
+!
+! Contributed by <bugs@miller-mohr.de>
+
+module classes
+
+ implicit none
+
+ type :: base_class
+ contains
+ procedure, nopass :: get_num
+ procedure :: get_array, get_array2
+ end type
+
+contains
+
+ pure integer function get_num()
+ get_num = 2
+ end function
+
+ function get_array( this ) result(array)
+ class(base_class), intent(in) :: this
+ integer, dimension( this%get_num() ) :: array
+ end function
+
+ function get_array2( this ) result(array)
+ class(base_class), intent(in) :: this
+ integer, dimension( this%get_num(), this%get_num() ) :: array
+ end function
+
+end module
+
+! { dg-final { cleanup-modules "classes" } }
diff --git a/gcc/testsuite/gfortran.dg/use_only_3.f90 b/gcc/testsuite/gfortran.dg/use_only_3.f90
index b264506d4c38..ebb39289fc48 100644
--- a/gcc/testsuite/gfortran.dg/use_only_3.f90
+++ b/gcc/testsuite/gfortran.dg/use_only_3.f90
@@ -32,3 +32,4 @@ subroutine dforceb(c0, i, betae, ipol, bec0, ctabin, gqq, gqqm, qmat, dq2, df)
& dq2, gmes
end subroutine dforceb
+! { dg-final { cleanup-modules "cell_base constants control_flags cvan electrons_base electrons_nose gvecs gvecw ions_base kinds parameters" } }
diff --git a/gcc/testsuite/gnat.dg/loop_optimization17.adb b/gcc/testsuite/gnat.dg/loop_optimization17.adb
new file mode 100644
index 000000000000..2178b65bf1f0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization17.adb
@@ -0,0 +1,22 @@
+-- { dg-do run }
+-- { dg-options "-O" }
+
+with Loop_Optimization17_Pkg; use Loop_Optimization17_Pkg;
+
+procedure Loop_Optimization17 is
+
+ Data : Arr;
+
+begin
+
+ Data := (others => (I => 0,
+ V1 => (others => 0.0),
+ V2 => (others => 0.0),
+ S => 0.0));
+
+ for I in Index_T'Range loop
+ Object (I).V1 := F (Data (I).V1);
+ Object (I).V2 := F (Data (I).V2);
+ end loop;
+
+end;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization17_pkg.adb b/gcc/testsuite/gnat.dg/loop_optimization17_pkg.adb
new file mode 100644
index 000000000000..20815af4775f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization17_pkg.adb
@@ -0,0 +1,5 @@
+package body Loop_Optimization17_Pkg is
+
+ function F (V : Vector) return Vector is begin return V; end;
+
+end Loop_Optimization17_Pkg;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization17_pkg.ads b/gcc/testsuite/gnat.dg/loop_optimization17_pkg.ads
new file mode 100644
index 000000000000..5b650dfa8864
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization17_pkg.ads
@@ -0,0 +1,29 @@
+package Loop_Optimization17_Pkg is
+
+ type vector is array (1..3) of Long_Float;
+
+ type Rec is
+ record
+ I : Integer;
+ V1, V2 : Vector;
+ S : Long_Float;
+ end record;
+
+ for Rec use
+ record
+ I at 0 range 0 .. 31;
+ V1 at 4 range 0 .. 191;
+ V2 at 28 range 0 .. 191;
+ S at 52 range 0 .. 63;
+ end record;
+ for Rec'Alignment use 4;
+ for Rec'Size use 480;
+
+ type Index_T is range 1 .. 5;
+ type Arr is array (Index_T) of Rec;
+
+ Object : Arr;
+
+ function F (V : Vector) return Vector;
+
+end Loop_Optimization17_Pkg;
diff --git a/gcc/testsuite/gnat.dg/weak2.adb b/gcc/testsuite/gnat.dg/weak2.adb
new file mode 100644
index 000000000000..9e704b50c0da
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/weak2.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+
+package body Weak2 is
+
+ function F return Integer is
+ begin
+ return Var;
+ end;
+
+end Weak2;
diff --git a/gcc/testsuite/gnat.dg/weak2.ads b/gcc/testsuite/gnat.dg/weak2.ads
new file mode 100644
index 000000000000..0a0011a6ecae
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/weak2.ads
@@ -0,0 +1,9 @@
+package Weak2 is
+
+ Var : Integer;
+ pragma Import (Ada, Var, "var_name");
+ pragma Weak_External (Var);
+
+ function F return Integer;
+
+end Weak2;
diff --git a/gcc/testsuite/go.test/go-test.exp b/gcc/testsuite/go.test/go-test.exp
index 0f95edc182d3..f1eed08bd3e1 100644
--- a/gcc/testsuite/go.test/go-test.exp
+++ b/gcc/testsuite/go.test/go-test.exp
@@ -400,17 +400,16 @@ proc go-gc-tests { } {
}
if { ( [file tail $test] == "select2.go" \
- || [file tail $test] == "stack.go" ) \
+ || [file tail $test] == "stack.go" \
+ || [file tail $test] == "peano.go" ) \
&& ! [check_effective_target_split_stack] } {
- # chan/select2.go fails on targets without split stack,
- # because they allocate a large stack segment that blows
- # out the memory calculations.
+ # These tests fails on targets without split stack.
untested $name
continue
}
- if { [file tail $test] == "rotate.go" } {
- # This test produces a temporary file that takes too long
+ if [string match "*go.test/test/rotate\[0123\].go" $test] {
+ # These tests produces a temporary file that takes too long
# to compile--5 minutes on my laptop without optimization.
# When compiling without optimization it tests nothing
# useful, since the point of the test is to see whether
@@ -1144,6 +1143,10 @@ proc go-gc-tests { } {
|| $test_line == "// \$G \$D/pkg.go && pack grcS pkg.a pkg.\$A 2> /dev/null && rm pkg.\$A && \$G -I. -u \$D/main.go" } {
# This tests the gc -u option, which gccgo does not
# support.
+ } elseif { $test_line == "// errorcheck -0 -N -d=nil" \
+ || $test_line == "// errorcheck -0 -d=nil" } {
+ # This tests gc nil pointer checks using -d=nil, which
+ # gccgo does not support.
} else {
clone_output "$name: unrecognized test line: $test_line"
unsupported $name
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 5166679dacd9..159f88f28dd8 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -1035,6 +1035,16 @@ proc check_iconv_available { test_what } {
}] $libiconv]
}
+# Return true if Cilk Library is supported on the target.
+proc check_libcilkrts_available { } {
+ return [ check_no_compiler_messages_nocache libcilkrts_available executable {
+ int main (void) {
+ __cilkrts_set_param ("nworkers", "0");
+ return 0;
+ }
+ } "-fcilkplus -lcilkrts" ]
+}
+
# Return 1 if an ASCII locale is supported on this host, 0 otherwise.
proc check_ascii_locale_available { } {
@@ -2301,19 +2311,37 @@ proc check_effective_target_arm_unaligned { } {
}
# Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8
-# -mfloat-abi=softfp.
-proc check_effective_target_arm_crypto_ok {} {
+# -mfloat-abi=softfp or equivalent options. Some multilibs may be
+# incompatible with these options. Also set et_arm_crypto_flags to the
+# best options to add.
+
+proc check_effective_target_arm_crypto_ok_nocache { } {
+ global et_arm_crypto_flags
+ set et_arm_crypto_flags ""
if { [check_effective_target_arm32] } {
- return [check_no_compiler_messages arm_crypto_ok object {
- int foo (void)
- {
- __asm__ volatile ("aese.8 q0, q0");
- return 0;
- }
- } "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"]
- } else {
- return 0
+ foreach flags {"" "-mfloat-abi=softfp" "-mfpu=crypto-neon-fp-armv8" "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"} {
+ if { [check_no_compiler_messages_nocache arm_crypto_ok object {
+ #include "arm_neon.h"
+ uint8x16_t
+ foo (uint8x16_t a, uint8x16_t b)
+ {
+ return vaeseq_u8 (a, b);
+ }
+ } "$flags"] } {
+ set et_arm_crypto_flags $flags
+ return 1
+ }
+ }
}
+
+ return 0
+}
+
+# Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8
+
+proc check_effective_target_arm_crypto_ok { } {
+ return [check_cached_effective_target arm_crypto_ok \
+ check_effective_target_arm_crypto_ok_nocache]
}
# Add options for crypto extensions.
@@ -2321,7 +2349,8 @@ proc add_options_for_arm_crypto { flags } {
if { ! [check_effective_target_arm_crypto_ok] } {
return "$flags"
}
- return "$flags -mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"
+ global et_arm_crypto_flags
+ return "$flags $et_arm_crypto_flags"
}
# Add the options needed for NEON. We need either -mfloat-abi=softfp
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 38e986c15600..c652522a3613 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -78,6 +78,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-color.h"
#include "context.h"
#include "pass_manager.h"
+#include "optabs.h"
#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
#include "dbxout.h"
@@ -1752,6 +1753,23 @@ target_reinit (void)
{
struct rtl_data saved_x_rtl;
rtx *saved_regno_reg_rtx;
+ tree saved_optimization_current_node;
+ struct target_optabs *saved_this_fn_optabs;
+
+ /* Temporarily switch to the default optimization node, so that
+ *this_target_optabs is set to the default, not reflecting
+ whatever a previous function used for the optimize
+ attribute. */
+ saved_optimization_current_node = optimization_current_node;
+ saved_this_fn_optabs = this_fn_optabs;
+ if (saved_optimization_current_node != optimization_default_node)
+ {
+ optimization_current_node = optimization_default_node;
+ cl_optimization_restore
+ (&global_options,
+ TREE_OPTIMIZATION (optimization_default_node));
+ }
+ this_fn_optabs = this_target_optabs;
/* Save *crtl and regno_reg_rtx around the reinitialization
to allow target_reinit being called even after prepare_function_start. */
@@ -1769,7 +1787,16 @@ target_reinit (void)
/* Reinitialize lang-dependent parts. */
lang_dependent_init_target ();
- /* And restore it at the end, as free_after_compilation from
+ /* Restore the original optimization node. */
+ if (saved_optimization_current_node != optimization_default_node)
+ {
+ optimization_current_node = saved_optimization_current_node;
+ cl_optimization_restore (&global_options,
+ TREE_OPTIMIZATION (optimization_current_node));
+ }
+ this_fn_optabs = saved_this_fn_optabs;
+
+ /* Restore regno_reg_rtx at the end, as free_after_compilation from
expand_dummy_function_end clears it. */
if (saved_regno_reg_rtx)
{
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 1d1a58d0f475..83cbda9f3a29 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -161,7 +161,6 @@ static void make_goto_expr_edges (basic_block);
static void make_gimple_asm_edges (basic_block);
static edge gimple_redirect_edge_and_branch (edge, basic_block);
static edge gimple_try_redirect_by_replacing_jump (edge, basic_block);
-static unsigned int split_critical_edges (void);
/* Various helpers. */
static inline bool stmt_starts_bb_p (gimple, gimple);
@@ -7931,7 +7930,7 @@ struct cfg_hooks gimple_cfg_hooks = {
/* Split all critical edges. */
-static unsigned int
+unsigned int
split_critical_edges (void)
{
basic_block bb;
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 8d045a4e2dcc..babbd2db2cab 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -93,5 +93,6 @@ extern tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code,
tree, tree);
extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
extern unsigned int execute_fixup_cfg (void);
+extern unsigned int split_critical_edges (void);
#endif /* _TREE_CFG_H */
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index fac93550e1eb..57af2377fb79 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1570,18 +1570,25 @@ struct GTY(()) tree_optimization_option {
/* Target optabs for this set of optimization options. This is of
type `struct target_optabs *'. */
- unsigned char *GTY ((atomic)) optabs;
+ void *GTY ((atomic)) optabs;
/* The value of this_target_optabs against which the optabs above were
generated. */
struct target_optabs *GTY ((skip)) base_optabs;
};
+/* Forward declaration, defined in target-globals.h. */
+
+struct GTY(()) target_globals;
+
/* Target options used by a function. */
struct GTY(()) tree_target_option {
struct tree_common common;
+ /* Target globals for the corresponding target option. */
+ struct target_globals *globals;
+
/* The optimization options used by the user. */
struct cl_target_option opts;
};
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index 3eaf81d334d9..35743cbe3bd8 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -773,10 +773,37 @@ split_data_refs_to_components (struct loop *loop,
bad = component_of (comp_father, n);
/* If both A and B are reads, we may ignore unsuitable dependences. */
- if (DR_IS_READ (dra) && DR_IS_READ (drb)
- && (ia == bad || ib == bad
- || !determine_offset (dra, drb, &dummy_off)))
- continue;
+ if (DR_IS_READ (dra) && DR_IS_READ (drb))
+ {
+ if (ia == bad || ib == bad
+ || !determine_offset (dra, drb, &dummy_off))
+ continue;
+ }
+ /* If A is read and B write or vice versa and there is unsuitable
+ dependence, instead of merging both components into a component
+ that will certainly not pass suitable_component_p, just put the
+ read into bad component, perhaps at least the write together with
+ all the other data refs in it's component will be optimizable. */
+ else if (DR_IS_READ (dra) && ib != bad)
+ {
+ if (ia == bad)
+ continue;
+ else if (!determine_offset (dra, drb, &dummy_off))
+ {
+ merge_comps (comp_father, comp_size, bad, ia);
+ continue;
+ }
+ }
+ else if (DR_IS_READ (drb) && ia != bad)
+ {
+ if (ib == bad)
+ continue;
+ else if (!determine_offset (dra, drb, &dummy_off))
+ {
+ merge_comps (comp_father, comp_size, bad, ib);
+ continue;
+ }
+ }
merge_comps (comp_father, comp_size, ia, ib);
}
@@ -2420,6 +2447,7 @@ tree_predictive_commoning_loop (struct loop *loop)
if (!components)
{
free_data_refs (datarefs);
+ free_affine_expand_cache (&name_expansions);
return false;
}
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index d5b08566f6ed..049da5fcdfa8 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -1668,50 +1668,30 @@ constant_multiple_of (tree top, tree bot, widest_int *mul)
}
}
-/* Returns true if memory reference REF with step STEP may be unaligned. */
+/* Return true if memory reference REF with step STEP may be unaligned. */
static bool
may_be_unaligned_p (tree ref, tree step)
{
- tree base;
- tree base_type;
- HOST_WIDE_INT bitsize;
- HOST_WIDE_INT bitpos;
- tree toffset;
- enum machine_mode mode;
- int unsignedp, volatilep;
- unsigned base_align;
-
/* TARGET_MEM_REFs are translated directly to valid MEMs on the target,
thus they are not misaligned. */
if (TREE_CODE (ref) == TARGET_MEM_REF)
return false;
- /* The test below is basically copy of what expr.c:normal_inner_ref
- does to check whether the object must be loaded by parts when
- STRICT_ALIGNMENT is true. */
- base = get_inner_reference (ref, &bitsize, &bitpos, &toffset, &mode,
- &unsignedp, &volatilep, true);
- base_type = TREE_TYPE (base);
- base_align = get_object_alignment (base);
- base_align = MAX (base_align, TYPE_ALIGN (base_type));
+ unsigned int align = TYPE_ALIGN (TREE_TYPE (ref));
- if (mode != BLKmode)
- {
- unsigned mode_align = GET_MODE_ALIGNMENT (mode);
-
- if (base_align < mode_align
- || (bitpos % mode_align) != 0
- || (bitpos % BITS_PER_UNIT) != 0)
- return true;
-
- if (toffset
- && (highest_pow2_factor (toffset) * BITS_PER_UNIT) < mode_align)
- return true;
+ unsigned HOST_WIDE_INT bitpos;
+ unsigned int ref_align;
+ get_object_alignment_1 (ref, &ref_align, &bitpos);
+ if (ref_align < align
+ || (bitpos % align) != 0
+ || (bitpos % BITS_PER_UNIT) != 0)
+ return true;
- if ((highest_pow2_factor (step) * BITS_PER_UNIT) < mode_align)
- return true;
- }
+ unsigned int trailing_zeros = tree_ctz (step);
+ if (trailing_zeros < HOST_BITS_PER_INT
+ && (1U << trailing_zeros) * BITS_PER_UNIT < align)
+ return true;
return false;
}
@@ -5733,18 +5713,20 @@ iv_ca_extend (struct ivopts_data *data, struct iv_ca *ivs,
}
/* Try narrowing set IVS by removing CAND. Return the cost of
- the new set and store the differences in DELTA. */
+ the new set and store the differences in DELTA. START is
+ the candidate with which we start narrowing. */
static comp_cost
iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs,
- struct iv_cand *cand, struct iv_ca_delta **delta)
+ struct iv_cand *cand, struct iv_cand *start,
+ struct iv_ca_delta **delta)
{
unsigned i, ci;
struct iv_use *use;
struct cost_pair *old_cp, *new_cp, *cp;
bitmap_iterator bi;
struct iv_cand *cnd;
- comp_cost cost;
+ comp_cost cost, best_cost, acost;
*delta = NULL;
for (i = 0; i < n_iv_uses (data); i++)
@@ -5755,13 +5737,15 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs,
if (old_cp->cand != cand)
continue;
- new_cp = NULL;
+ best_cost = iv_ca_cost (ivs);
+ /* Start narrowing with START. */
+ new_cp = get_use_iv_cost (data, use, start);
if (data->consider_all_candidates)
{
EXECUTE_IF_SET_IN_BITMAP (ivs->cands, 0, ci, bi)
{
- if (ci == cand->id)
+ if (ci == cand->id || (start && ci == start->id))
continue;
cnd = iv_cand (data, ci);
@@ -5770,20 +5754,21 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs,
if (!cp)
continue;
- if (!iv_ca_has_deps (ivs, cp))
- continue;
-
- if (!cheaper_cost_pair (cp, new_cp))
- continue;
+ iv_ca_set_cp (data, ivs, use, cp);
+ acost = iv_ca_cost (ivs);
- new_cp = cp;
+ if (compare_costs (acost, best_cost) < 0)
+ {
+ best_cost = acost;
+ new_cp = cp;
+ }
}
}
else
{
EXECUTE_IF_AND_IN_BITMAP (use->related_cands, ivs->cands, 0, ci, bi)
{
- if (ci == cand->id)
+ if (ci == cand->id || (start && ci == start->id))
continue;
cnd = iv_cand (data, ci);
@@ -5791,15 +5776,19 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs,
cp = get_use_iv_cost (data, use, cnd);
if (!cp)
continue;
- if (!iv_ca_has_deps (ivs, cp))
- continue;
- if (!cheaper_cost_pair (cp, new_cp))
- continue;
+ iv_ca_set_cp (data, ivs, use, cp);
+ acost = iv_ca_cost (ivs);
- new_cp = cp;
+ if (compare_costs (acost, best_cost) < 0)
+ {
+ best_cost = acost;
+ new_cp = cp;
+ }
}
}
+ /* Restore to old cp for use. */
+ iv_ca_set_cp (data, ivs, use, old_cp);
if (!new_cp)
{
@@ -5841,7 +5830,7 @@ iv_ca_prune (struct ivopts_data *data, struct iv_ca *ivs,
if (cand == except_cand)
continue;
- acost = iv_ca_narrow (data, ivs, cand, &act_delta);
+ acost = iv_ca_narrow (data, ivs, cand, except_cand, &act_delta);
if (compare_costs (acost, best_cost) < 0)
{
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 1637d68974f6..a48ad10424e9 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -1309,7 +1309,7 @@ dump_affine_iv (FILE *file, affine_iv *iv)
if EVERY_ITERATION is true, we know the test is executed on every iteration.
The results (number of iterations and assumptions as described in
- comments at struct tree_niter_desc in tree-flow.h) are stored to NITER.
+ comments at struct tree_niter_desc in tree-ssa-loop.h) are stored to NITER.
Returns false if it fails to determine number of iterations, true if it
was determined (possibly with some assumptions). */
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 0b940a417046..77d05624ff24 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -4798,9 +4798,11 @@ const pass_data pass_data_pre =
true, /* has_gate */
true, /* has_execute */
TV_TREE_PRE, /* tv_id */
+ /* PROP_no_crit_edges is ensured by placing pass_split_crit_edges before
+ pass_pre. */
( PROP_no_crit_edges | PROP_cfg | PROP_ssa ), /* properties_required */
0, /* properties_provided */
- 0, /* properties_destroyed */
+ PROP_no_crit_edges, /* properties_destroyed */
TODO_rebuild_alias, /* todo_flags_start */
TODO_verify_ssa, /* todo_flags_finish */
};
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index d2de147799dc..6d02975c4dda 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -567,7 +567,7 @@ static void
execute_sink_code (void)
{
loop_optimizer_init (LOOPS_NORMAL);
-
+ split_critical_edges ();
connect_infinite_loops_to_exit ();
memset (&sink_stats, 0, sizeof (sink_stats));
calculate_dominance_info (CDI_DOMINATORS);
@@ -604,7 +604,9 @@ const pass_data pass_data_sink_code =
true, /* has_gate */
true, /* has_execute */
TV_TREE_SINK, /* tv_id */
- ( PROP_no_crit_edges | PROP_cfg | PROP_ssa ), /* properties_required */
+ /* PROP_no_crit_edges is ensured by running split_critical_edges in
+ execute_sink_code. */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 26b24f9b2962..17c4279938b1 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -3318,9 +3318,10 @@ again:
{
gimple def = SSA_NAME_DEF_STMT (off);
tree reft = TREE_TYPE (DR_REF (newdr));
- if (gimple_call_internal_p (def)
- && gimple_call_internal_fn (def)
- == IFN_GOMP_SIMD_LANE)
+ if (is_gimple_call (def)
+ && gimple_call_internal_p (def)
+ && (gimple_call_internal_fn (def)
+ == IFN_GOMP_SIMD_LANE))
{
tree arg = gimple_call_arg (def, 0);
gcc_assert (TREE_CODE (arg) == SSA_NAME);
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index ecb446c02f4c..ebcbfb47c5f2 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -483,7 +483,18 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
if (!current_new_name)
continue;
}
- gcc_assert (get_current_def (current_new_name) == NULL_TREE);
+ tree new_name = get_current_def (current_new_name);
+ /* Because of peeled_chrec optimization it is possible that we have
+ set this earlier. Verify the PHI has the same value. */
+ if (new_name)
+ {
+ gimple phi = SSA_NAME_DEF_STMT (new_name);
+ gcc_assert (gimple_code (phi) == GIMPLE_PHI
+ && gimple_bb (phi) == *new_exit_bb
+ && (PHI_ARG_DEF_FROM_EDGE (phi, single_exit (loop))
+ == loop_arg));
+ continue;
+ }
set_current_def (current_new_name, PHI_RESULT (new_phi));
}
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 2b075dfea96f..372d7db3e70f 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2110,17 +2110,6 @@ vect_slp_analyze_bb_1 (basic_block bb)
vect_pattern_recog (NULL, bb_vinfo);
- if (!vect_slp_analyze_data_ref_dependences (bb_vinfo))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: unhandled data dependence "
- "in basic block.\n");
-
- destroy_bb_vec_info (bb_vinfo);
- return NULL;
- }
-
if (!vect_analyze_data_refs_alignment (NULL, bb_vinfo))
{
if (dump_enabled_p ())
@@ -2155,6 +2144,29 @@ vect_slp_analyze_bb_1 (basic_block bb)
vect_mark_slp_stmts_relevant (SLP_INSTANCE_TREE (instance));
}
+ /* Mark all the statements that we do not want to vectorize. */
+ for (gimple_stmt_iterator gsi = gsi_start_bb (BB_VINFO_BB (bb_vinfo));
+ !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ stmt_vec_info vinfo = vinfo_for_stmt (gsi_stmt (gsi));
+ if (STMT_SLP_TYPE (vinfo) != pure_slp)
+ STMT_VINFO_VECTORIZABLE (vinfo) = false;
+ }
+
+ /* Analyze dependences. At this point all stmts not participating in
+ vectorization have to be marked. Dependence analysis assumes
+ that we either vectorize all SLP instances or none at all. */
+ if (!vect_slp_analyze_data_ref_dependences (bb_vinfo))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unhandled data dependence "
+ "in basic block.\n");
+
+ destroy_bb_vec_info (bb_vinfo);
+ return NULL;
+ }
+
if (!vect_verify_datarefs_alignment (NULL, bb_vinfo))
{
if (dump_enabled_p ())
diff --git a/gcc/tree.c b/gcc/tree.c
index 18e4e369297d..914508e0cd6f 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -11419,6 +11419,28 @@ build_target_option_node (struct gcc_options *opts)
return t;
}
+/* Reset TREE_TARGET_GLOBALS cache for TARGET_OPTION_NODE.
+ Called through htab_traverse. */
+
+static int
+prepare_target_option_node_for_pch (void **slot, void *)
+{
+ tree node = (tree) *slot;
+ if (TREE_CODE (node) == TARGET_OPTION_NODE)
+ TREE_TARGET_GLOBALS (node) = NULL;
+ return 1;
+}
+
+/* Clear TREE_TARGET_GLOBALS of all TARGET_OPTION_NODE trees,
+ so that they aren't saved during PCH writing. */
+
+void
+prepare_target_option_nodes_for_pch (void)
+{
+ htab_traverse (cl_option_hash_table, prepare_target_option_node_for_pch,
+ NULL);
+}
+
/* Determine the "ultimate origin" of a block. The block may be an inlined
instance of an inlined instance of a block which is local to an inline
function, so we have to trace all of the way back through the origin chain
diff --git a/gcc/tree.h b/gcc/tree.h
index 40381646dc80..6cccb3f87542 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1117,9 +1117,6 @@ extern void protected_set_expr_location (tree, location_t);
the given label expression. */
#define LABEL_EXPR_LABEL(NODE) TREE_OPERAND (LABEL_EXPR_CHECK (NODE), 0)
-/* VDEF_EXPR accessors are specified in tree-flow.h, along with the other
- accessors for SSA operands. */
-
/* CATCH_EXPR accessors. */
#define CATCH_TYPES(NODE) TREE_OPERAND (CATCH_EXPR_CHECK (NODE), 0)
#define CATCH_BODY(NODE) TREE_OPERAND (CATCH_EXPR_CHECK (NODE), 1)
@@ -2698,9 +2695,14 @@ extern tree build_optimization_node (struct gcc_options *opts);
#define TREE_TARGET_OPTION(NODE) \
(&TARGET_OPTION_NODE_CHECK (NODE)->target_option.opts)
+#define TREE_TARGET_GLOBALS(NODE) \
+ (TARGET_OPTION_NODE_CHECK (NODE)->target_option.globals)
+
/* Return a tree node that encapsulates the target options in OPTS. */
extern tree build_target_option_node (struct gcc_options *opts);
+extern void prepare_target_option_nodes_for_pch (void);
+
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
inline tree
diff --git a/gcc/tsan.c b/gcc/tsan.c
index 2c053bd9e340..2e32cd2b32f7 100644
--- a/gcc/tsan.c
+++ b/gcc/tsan.c
@@ -609,7 +609,7 @@ instrument_gimple (gimple_stmt_iterator *gsi)
&& (gimple_call_fndecl (stmt)
!= builtin_decl_implicit (BUILT_IN_TSAN_INIT)))
{
- if (is_gimple_builtin_call (stmt))
+ if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
instrument_builtin_call (gsi);
return true;
}
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index 7cc8c180ba83..1841a947b9c6 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -311,6 +311,9 @@ ubsan_type_descriptor (tree type, bool want_pointer_type_p)
type2 = TYPE_METHOD_BASETYPE (type2);
}
+ /* If an array, get its type. */
+ type2 = strip_array_types (type2);
+
if (TYPE_NAME (type2) != NULL)
{
if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 4d6aed24b0cf..dcbbbd26f782 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -5947,6 +5947,13 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
if (type != MO_VAL_SET)
goto log_and_return;
+ v = find_use_val (oloc, mode, cui);
+
+ if (!v)
+ goto log_and_return;
+
+ resolve = preserve = !cselib_preserved_value_p (v);
+
/* We cannot track values for multiple-part variables, so we track only
locations for tracked parameters passed either by invisible reference
or directly in multiple locations. */
@@ -5960,14 +5967,15 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
&& XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) != arg_pointer_rtx)
|| (GET_CODE (DECL_INCOMING_RTL (REG_EXPR (loc))) == PARALLEL
&& XVECLEN (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) > 1)))
- goto log_and_return;
-
- v = find_use_val (oloc, mode, cui);
-
- if (!v)
- goto log_and_return;
-
- resolve = preserve = !cselib_preserved_value_p (v);
+ {
+ /* Although we don't use the value here, it could be used later by the
+ mere virtue of its existence as the operand of the reverse operation
+ that gave rise to it (typically extension/truncation). Make sure it
+ is preserved as required by vt_expand_var_loc_chain. */
+ if (preserve)
+ preserve_value (v);
+ goto log_and_return;
+ }
if (loc == stack_pointer_rtx
&& hard_frame_pointer_adjustment != -1