diff options
author | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-06-13 19:17:11 +0000 |
---|---|---|
committer | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-06-13 19:17:11 +0000 |
commit | 1f0ee7bee0a651f5b237f4aae2746ee546b6f936 (patch) | |
tree | e942205a85b1a2f2bd259b3da2e31b7303905c69 | |
parent | 1297524ea9aed947bf4daf707d2665e2cc946d19 (diff) | |
parent | 0453704977fada7e7238309b859381fb0b254cd9 (diff) |
Merge up to 237393ibm/stage-test
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ibm/stage-test@237398 138bc75d-0d04-0410-961f-82ee72b054a4
237 files changed, 7229 insertions, 1239 deletions
diff --git a/contrib/ChangeLog b/contrib/ChangeLog index edb1df7b311..c974b75e358 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,34 @@ +2016-06-13 Richard Biener <rguenther@suse.de> + + * download_prerequisites (ISL): Bump version to 0.16.1 + +2016-06-10 Alan Hayward <alan.hayward@arm.com> + + * check_GNU_style.sh: Fix paste args for BSD + +2016-06-09 David Malcolm <dmalcolm@redhat.com> + + * config-list.mk (LIST): Add OPT-enable-obsolete to avr-rtems, + h8300-rtems, m32r-rtems, mep-elf. + +2016-06-09 David Malcolm <dmalcolm@redhat.com> + + * config-list.mk (GCC_SRC_DIR): New variable. + (make-log-dir): Use GCC_SRC_DIR. + ($(LIST)): Likewise. + +2016-06-09 Martin Liska <mliska@suse.cz> + + * analyze_brprob_spec.py: New file. + +2016-06-09 Martin Liska <mliska@suse.cz> + + * analyze_brprob.py: Add new argument --sorting. + +2016-06-09 Martin Liska <mliska@suse.cz> + + * analyze_brprob.py: Cover new dump output format. + 2016-06-07 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * update-copyright.py (LibMudflapFilter): Remove. diff --git a/contrib/analyze_brprob.py b/contrib/analyze_brprob.py index 36371ff26ff..9808c46de16 100755 --- a/contrib/analyze_brprob.py +++ b/contrib/analyze_brprob.py @@ -65,6 +65,7 @@ import sys import os import re +import argparse def percentage(a, b): return 100.0 * a / b @@ -77,6 +78,9 @@ class Summary: self.hits = 0 self.fits = 0 + def get_hitrate(self): + return self.hits / self.count + def count_formatted(self): v = self.count for unit in ['','K','M','G','T','P','E','Z']: @@ -108,29 +112,37 @@ class Profile: def count_max(self): return max([v.count for k, v in self.heuristics.items()]) - def dump(self): + def dump(self, sorting): + sorter = lambda x: x[1].branches + if sorting == 'hitrate': + sorter = lambda x: x[1].get_hitrate() + elif sorting == 'coverage': + sorter = lambda x: x[1].count + print('%-36s %8s %6s %-16s %14s %8s %6s' % ('HEURISTICS', 'BRANCHES', '(REL)', 'HITRATE', 'COVERAGE', 'COVERAGE', '(REL)')) - for (k, v) in sorted(self.heuristics.items(), key = lambda x: x[1].branches): + for (k, v) in sorted(self.heuristics.items(), key = sorter): print('%-36s %8i %5.1f%% %6.2f%% / %6.2f%% %14i %8s %5.1f%%' % (k, v.branches, percentage(v.branches, self.branches_max ()), percentage(v.hits, v.count), percentage(v.fits, v.count), v.count, v.count_formatted(), percentage(v.count, self.count_max()) )) -if len(sys.argv) != 2: - print('Usage: ./analyze_brprob.py dump_file') - exit(1) +parser = argparse.ArgumentParser() +parser.add_argument('dump_file', metavar = 'dump_file', help = 'IPA profile dump file') +parser.add_argument('-s', '--sorting', dest = 'sorting', choices = ['branches', 'hitrate', 'coverage'], default = 'branches') + +args = parser.parse_args() profile = Profile(sys.argv[1]) -r = re.compile(' (.*) heuristics: (.*)%.*exec ([0-9]*) hit ([0-9]*)') -for l in open(profile.filename).readlines(): +r = re.compile(' (.*) heuristics( of edge [0-9]*->[0-9]*)?( \\(.*\\))?: (.*)%.*exec ([0-9]*) hit ([0-9]*)') +for l in open(args.dump_file).readlines(): m = r.match(l) - if m != None: + if m != None and m.group(3) == None: name = m.group(1) - prediction = float(m.group(2)) - count = int(m.group(3)) - hits = int(m.group(4)) + prediction = float(m.group(4)) + count = int(m.group(5)) + hits = int(m.group(6)) profile.add(name, prediction, count, hits) -profile.dump() +profile.dump(args.sorting) diff --git a/contrib/analyze_brprob_spec.py b/contrib/analyze_brprob_spec.py new file mode 100755 index 00000000000..a28eaac39d5 --- /dev/null +++ b/contrib/analyze_brprob_spec.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3, or (at your option) any later +# version. +# +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. */ + +import sys +import os +import subprocess +import tempfile +import argparse + +script_location = os.path.realpath(__file__) + +parser = argparse.ArgumentParser() +parser.add_argument('location', metavar = 'dump_file', help = 'Location with SPEC benchmarks') +parser.add_argument('-s', '--sorting', dest = 'sorting', choices = ['branches', 'hitrate', 'coverage'], default = 'branches') + +args = parser.parse_args() + +benchmarks = os.listdir(args.location) + +for b in sorted(benchmarks): + dumps = [] + for root, dirs, files in os.walk(os.path.join(args.location, b)): + for x in files: + if x.endswith('.profile'): + dumps.append(os.path.join(root, x)) + + if len(dumps) == 0: + continue + + temp = tempfile.NamedTemporaryFile(delete = False) + for d in dumps: + temp.write(open(d, 'rb').read()) + + temp.close() + + print() + print(b) + sys.stdout.flush() + p = [os.path.join(os.path.dirname(script_location), 'analyze_brprob.py'), temp.name, '--sorting', args.sorting] + p = subprocess.check_call(p) + sys.stdout.flush() + + os.remove(temp.name) diff --git a/contrib/check_GNU_style.sh b/contrib/check_GNU_style.sh index a7478f8f573..87a276c9cf4 100755 --- a/contrib/check_GNU_style.sh +++ b/contrib/check_GNU_style.sh @@ -191,7 +191,7 @@ col (){ # Combine prefix back with long lines. # Filter out empty lines. local found=false - paste -d '' "$tmp2" "$tmp3" \ + paste -d '\0' "$tmp2" "$tmp3" \ | grep -v '^[0-9][0-9]*:+$' \ > "$tmp" && found=true diff --git a/contrib/config-list.mk b/contrib/config-list.mk index 8210352003c..be41d3c9df8 100644 --- a/contrib/config-list.mk +++ b/contrib/config-list.mk @@ -3,13 +3,32 @@ host_options='--with-mpc=/opt/cfarm/mpc' # gcc10 TEST=all-gcc # Make sure you have a recent enough gcc (with ada support) in your path so # that --enable-werror-always will work. -# To use, create a sibling directory to the gcc sources and cd into this. +# To use, create a build directory with plenty of free disk space - a build of +# all configurations can take 450GB. +# By default, this file assumes the build directory is in a sibling directory +# to the gcc sources, but you can override GCC_SRC_DIR to specify where to +# find them. GCC_SRC_DIR is used in the directory below the build directory, +# hence the two ".." in the default value; if overriding it, it's easiest to +# supply an absolute path. +GCC_SRC_DIR=../../gcc + # Use -j / -l make arguments and nice to assure a smooth resource-efficient # load on the build machine, e.g. for 24 cores: # svn co svn://gcc.gnu.org/svn/gcc/branches/foo-branch gcc # mkdir multi-mk; cd multi-mk # nohup nice make -j25 -l36 -f ../gcc/contrib/config-list.mk > make.out 2>&1 & # +# Alternatively, if building against an existing gcc source tree: +# +# cd /somewhere/with/plenty/of/disk/space +# mkdir multi-mk; cd multi-mk +# nohup nice make \ +# -j25 -l36 \ +# -f /path/to/contrib/config-list.mk \ +# GCC_SRC_DIR=/path/to/gcc/source/tree \ +# > make.out 2>&1 & +# + # v850e1-elf is rejected by config.sub LIST = aarch64-elf aarch64-linux-gnu aarch64-rtems \ alpha-linux-gnu alpha-freebsd6 alpha-netbsd alpha-openbsd \ @@ -18,11 +37,12 @@ LIST = aarch64-elf aarch64-linux-gnu aarch64-rtems \ arc-linux-uclibcOPT-with-cpu=arc700 arceb-linux-uclibcOPT-with-cpu=arc700 \ arm-wrs-vxworks arm-netbsdelf \ arm-linux-androideabi arm-uclinux_eabi arm-eabi arm-rtems \ - arm-symbianelf avr-rtems avr-elf \ + arm-symbianelf avr-rtemsOPT-enable-obsolete avr-elf \ bfin-elf bfin-uclinux bfin-linux-uclibc bfin-rtems bfin-openbsd \ c6x-elf c6x-uclinux cr16-elf cris-elf cris-linux crisv32-elf crisv32-linux \ epiphany-elf epiphany-elfOPT-with-stack-offset=16 fido-elf \ - fr30-elf frv-elf frv-linux ft32-elf h8300-elf h8300-rtems hppa-linux-gnu \ + fr30-elf frv-elf frv-linux ft32-elf h8300-elf \ + h8300-rtemsOPT-enable-obsolete hppa-linux-gnu \ hppa-linux-gnuOPT-enable-sjlj-exceptions=yes hppa64-linux-gnu \ hppa2.0-hpux10.1 hppa64-hpux11.3 \ hppa64-hpux11.0OPT-enable-sjlj-exceptions=yes hppa2.0-hpux11.9 \ @@ -36,10 +56,11 @@ LIST = aarch64-elf aarch64-linux-gnu aarch64-rtems \ i686-wrs-vxworksae \ i686-cygwinOPT-enable-threads=yes i686-mingw32crt ia64-elf \ ia64-freebsd6 ia64-linux ia64-hpux ia64-hp-vms iq2000-elf lm32-elf \ - lm32-rtems lm32-uclinux m32c-rtems m32c-elf m32r-elf m32rle-elf m32r-rtems \ + lm32-rtems lm32-uclinux m32c-rtems m32c-elf m32r-elf m32rle-elf \ + m32r-rtemsOPT-enable-obsolete \ m32r-linux m32rle-linux m68k-elf m68k-netbsdelf \ m68k-openbsd m68k-uclinux m68k-linux m68k-rtems \ - mcore-elf mep-elf microblaze-linux microblaze-elf \ + mcore-elf mep-elfOPT-enable-obsolete microblaze-linux microblaze-elf \ mips-netbsd \ mips64el-st-linux-gnu mips64octeon-linux mipsisa64r2-linux \ mipsisa32r2-linux-gnu mipsisa64r2-sde-elf mipsisa32-elfoabi \ @@ -91,17 +112,17 @@ show: empty= -#Check for the presence of the MAINTAINERS file to make sure we are in a -#suitable current working directory. -make-log-dir: ../gcc/MAINTAINERS - mkdir log +#Check for the presence of the MAINTAINERS file to make sure we've located +#the gcc sources. +make-log-dir: $(GCC_SRC_DIR)/MAINTAINERS + -mkdir log $(LIST): make-log-dir -mkdir $@ ( \ cd $@ && \ TGT=`echo $@ | awk 'BEGIN { FS = "OPT" }; { print $$1 }'` && \ - TGT=`../../gcc/config.sub $$TGT` && \ + TGT=`$(GCC_SRC_DIR)/config.sub $$TGT` && \ case $$TGT in \ *-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix*) \ ADDITIONAL_LANGUAGES=""; \ @@ -110,7 +131,7 @@ $(LIST): make-log-dir ADDITIONAL_LANGUAGES=",go"; \ ;; \ esac && \ - ../../gcc/configure \ + $(GCC_SRC_DIR)/configure \ --target=$(subst SCRIPTS,`pwd`/../scripts/,$(subst OPT,$(empty) -,$@)) \ --enable-werror-always ${host_options} \ --enable-languages=all,ada$$ADDITIONAL_LANGUAGES; \ diff --git a/contrib/download_prerequisites b/contrib/download_prerequisites index b135f5fe5f1..917ee23f3d9 100755 --- a/contrib/download_prerequisites +++ b/contrib/download_prerequisites @@ -48,7 +48,7 @@ ln -sf $MPC mpc || exit 1 # Necessary to build GCC with the Graphite loop optimizations. if [ "$GRAPHITE_LOOP_OPT" = "yes" ] ; then - ISL=isl-0.15 + ISL=isl-0.16.1 wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$ISL.tar.bz2 || exit 1 tar xjf $ISL.tar.bz2 || exit 1 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c1a79cb90d..822e36f7816 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,401 @@ +2016-06-13 Kelvin Nilsen <kelvin@gcc.gnu.org> + + * config/rs6000/rs6000.h (RS6000_BTM_COMMON): Add the + RS6000_BTM_MODULO flag into the set of flags that are considered + to be part of the common configuration. + +2016-06-13 Kelvin Nilsen <kelvin@gcc.gnu.org> + + * config/rs6000/altivec.h (vec_absd): New macro for vector absolute + difference unsigned. + (vec_absdb): New macro for vector absolute difference unsigned + byte. + (vec_absdh): New macro for vector absolute difference unsigned + half-word. + (vec_absdw): New macro for vector absolute difference unsigned word. + * config/rs6000/altivec.md (UNSPEC_VADU): New value. + (vadu<mode>3): New insn. + (*p9_vadu<mode>3): New insn. + * config/rs6000/rs6000-builtin.def (vadub): New built-in + definition. + (vaduh): New built-in definition. + (vaduw): New built-in definition. + (vadu): New overloaded built-in definition. + (vadub): New overloaded built-in definition. + (vaduh): New overloaded built-in definition. + (vaduw): New overloaded built-in definition. + * config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add + overloaded vector absolute difference unsigned functions. + * doc/extend.texi (PowerPC AltiVec Built-in Functions): Document + the ISA 3.0 vector absolute difference unsigned built-in functions. + +2016-06-13 Eric Botcazou <ebotcazou@adacore.com> + + * tree-ssa-sccvn.c (vn_reference_lookup_3): Use a uniform test and + update shared_lookup_references only once after changing operands. + +2016-06-13 Thomas Schwinge <thomas@codesourcery.com> + + PR middle-end/71373 + * tree-nested.c (convert_nonlocal_omp_clauses) + (convert_local_omp_clauses): Document missing OMP_CLAUSE_*. + + * tree-cfg.c (edge_to_cases_cleanup): Fix CASE_CHAIN typo. + * tree.def (CASE_LABEL_EXPR): Likewise. + +2016-06-13 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR bootstrap/71481 + * input.c (test_builtins): Fix an assertion. + +2016-06-13 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/i386.md (paritydi2): Use ix86_expand_setcc. + (paritysi2): Ditto. + (isinfxf2): Ditto. + (isinf<mode>2): Ditto. + +2016-06-13 Uros Bizjak <ubizjak@gmail.com> + + * ggc-tests.c (test_finalization): Only test need_finalization_p + for GCC_VERSION >= 4003. + +2016-06-13 Andreas Krebbel <krebbel@linux.vnet.ibm.com> + + * config/s390/vecintrin.h: Fix file description in comment. + +2016-06-13 Andreas Krebbel <krebbel@linux.vnet.ibm.com> + + * config/s390/s390-builtin-types.def: Change builtin type naming + scheme to match builtin-types.def. + +2016-06-13 Marc Glisse <marc.glisse@inria.fr> + + * fold-const.c (optimize_minmax_comparison): Remove. + (fold_comparison): Remove call to the above. + * match.pd (MIN (X, Y) == X, MIN (X, 5) == 0, MIN (X, C1) < C2): + New transformations. + +2016-06-13 Alan Hayward <alan.hayward@arm.com> + + PR tree-optimization/71416 + * tree-vect-loop.c (vectorizable_live_operation): Let worklist have + multiple entries + +2016-06-13 Martin Liska <mliska@suse.cz> + + * predict.c (enum predictor_reason): Prefix enum with REASON_. + (combine_predictions_for_insn): Likewise. + (prune_predictions_for_bb): Likewise. + (combine_predictions_for_bb): Likewise. + +2016-06-13 Richard Biener <rguenther@suse.de> + + PR tree-optimization/71505 + * tree-vect-data-refs.c (vect_analyze_data_ref_accesses): Make + assert match comment. + +2016-06-13 Marek Polacek <polacek@redhat.com> + + PR middle-end/71476 + * gimplify.c (maybe_warn_switch_unreachable): Factored out of + gimplify_switch_expr. + (warn_switch_unreachable_r): New function. + +2016-06-13 Andreas Krebbel <krebbel@linux.vnet.ibm.com> + + PR target/71379 + * config/s390/s390.c (s390_expand_builtin): Increase MAX_ARGS by + one. + +2016-06-13 Richard Biener <rguenther@suse.de> + + PR middle-end/64516 + * fold-const.c (fold_unary_loc): Preserve alignment when + folding a VIEW_CONVERT_EXPR into a MEM_REF. + +2016-06-13 Martin Liska <mliska@suse.cz> + + PR sanitizer/71458 + * toplev.c (process_options): Do not enable -fcheck-pointer-bounds + w/ -fsanitize=bounds. + +2016-06-12 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/i386.c (ix86_init_builtins): Calculate + FLOAT128_FTYPE_CONST_STRING function type only once. + * doc/extend.texi (x86 Built-in Functions): Update text, __float128 + built-in functions are available for x86-32 and x86-64 targets. + +2016-06-12 Uros Bizjak <ubizjak@gmail.com> + + PR target/71241 + * config/i386/i386.i386-builtin-types.def (CONST_STRING): + New primitive type. + (FLOAT128_FTYPE_CONST_STRING): New function type. + * config/i386/i386.c (enum ix86_builtins) [IX86_BUILTIN_NANQ]: New. + [IX86_BUILTIN_NANSQ]: Ditto. + (ix86_fold_builtin): Handle IX86_BUILTIN_NANQ and IX86_BUILTIN_NANSQ. + (ix86_init_builtin_types) Declare const_string_type_node. + Add __builtin_nanq and __builtin_nansq builtin functions. + (ix86_expand_builtin): Handle IX86_BUILTIN_NANQ and IX86_BUILTIN_NANSQ. + * doc/extend.texi (x86 Built-in Functions): Document + __builtin_nanq and __builtin_nansq. + +2016-06-11 Jiong Wang <jiong.wang@arm.com> + + PR target/71061 + * config/arm/arm-protos.h (arm_attr_length_pop_multi): New declaration. + * config/arm/arm.c (arm_attr_length_pop_multi): New function to return + length for pop patterns. + (arm_attr_length_push_multi): Update comments. + * config/arm/arm.md (*load_multiple_with_writeback): Set "length" + attribute. + (*pop_multiple_with_writeback_and_return): Likewise. + (*pop_multiple_with_return): Likewise. + +2016-06-11 Segher Boessenkool <segher@kernel.crashing.org> + + PR middle-end/71310 + * fold-const.c (optimize_bit_field_compare): Don't try to use + word_mode unconditionally for reading the bit field, look at + DECL_BIT_FIELD_REPRESENTATIVE instead. + +2016-06-11 Kugan Vivekanandarajah <kuganv@linaro.org> + + PR middle-end/71478 + * tree-ssa-reassoc.c (reassociate_bb): Remove (-1) from ops list for + vector integer type. + +2016-06-10 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/71494 + * tree-nested.c (convert_nonlocal_reference_stmt): For GIMPLE_GOTO + without LABEL_DECL, set *handled_ops_p to false instead of true. + +2016-06-10 Martin Sebor <msebor@redhat.com> + + PR c/71392 + * builtin-attrs.def (ATTR_NOTHROW_NONNULL_LEAF_LIST): New macro. + (ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF): Same. + * builtins.def (BUILT_IN_SADD_OVERFLOW, BUILT_IN_SADDL_OVERFLOW): Use + them. + (BUILT_IN_SADDLL_OVERFLOW, BUILT_IN_SSUB_OVERFLOW): Same. + (BUILT_IN_SSUBL_OVERFLOW, BUILT_IN_SSUBLL_OVERFLOW): Same. + (BUILT_IN_SMUL_OVERFLOW, BUILT_IN_SMULL_OVERFLOW): Same. + (BUILT_IN_SMULLL_OVERFLOW, BUILT_IN_UADD_OVERFLOW): Same. + (BUILT_IN_UADDL_OVERFLOW, BUILT_IN_UADDLL_OVERFLOW): Same. + (BUILT_IN_USUB_OVERFLOW, BUILT_IN_USUBL_OVERFLOW): Same. + (BUILT_IN_USUBLL_OVERFLOW, BUILT_IN_UMUL_OVERFLOW): Same. + (BUILT_IN_UMULL_OVERFLOW, BUILT_IN_UMULLL_OVERFLOW): Same. + +2016-06-10 Bernd Edlinger <bernd.edlinger@hotmail.de> + + * config/arm/arm.h (pool_vector_label, + return_used_this_function): Remove. + +2016-06-10 Jeff Law <law@redhat.com> + + PR tree-optimization/71335 + * tree-ssa-threadbackward.c (profitable_jump_thread_path): Filter out + zero length paths here. + (convert_and_register_jump_thread_path): Remove hacks related to + duplicated blocks in the jump thread path. + (fsm_find_control_statement_thread_paths): Avoid putting the same + block on the thread path twice, but ensure the thread path is + unchanged from the caller's point of view. + +2016-06-10 Jan Hubicka <hubicka@ucw.cz> + + * predict.c (predict_loops): Remove PRED_LOOP_BRANCH. + * predict.def (PRED_LOOP_BRANCH): Remove. + +2016-06-10 David Malcolm <dmalcolm@redhat.com> + + * Makefile.in (OBJS): Add ggc-tests.o. + (GTFILES): Add ggc-tests.c. + * ggc-tests.c: New file. + * selftest-run-tests.c (selftest::run_tests): Call + selftest::ggc_tests_c_tests. + * selftest.h (selftest::ggc_tests_c_tests): New prototype. + +2016-06-10 Alexander Monakov <amonakov@ispras.ru> + + * match.pd (-1 / B < A): Use :c to avoid pattern duplication. + +2016-06-10 Maxim Ostapenko <m.ostapenko@samsung.com> + + PR sanitizer/71480 + * varasm.c (place_block_symbol): Adjust alignment for asan protected + STRING_CSTs even if TREE_CONSTANT_POOL_ADDRESS_P. + +2016-06-10 Jan Hubicka <hubicka@ucw.cz> + + * profile.c: Include cfgloop.h. + (branch_prob): Compute estimated number of iterations. + * tree-ssa-loop-niter.c (estimate_numbers_of_iterations_loop): Do not + recompute estimate number of iterations from profile. + +2016-06-10 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR inline-asm/68843 + * reg-stack.c (check_asm_stack_operands): Explicit input arguments + must be grouped on top of stack. Don't force early clobber + on ordinary reg outputs. + +2016-06-10 Richard Biener <rguenther@suse.de> + + * targhooks.c (default_builtin_vectorization_cost): Adjust + vec_construct cost. + +2016-06-10 Richard Biener <rguenther@suse.de> + + * gimple-fold.c (gimple_fold_builtin_memory_op): Make sure + to fold the RHS to a constant if possible. + +2016-06-10 Thomas Schwinge <thomas@codesourcery.com> + + PR middle-end/71373 + * tree-nested.c (convert_nonlocal_omp_clauses) + (convert_local_omp_clauses): Handle OMP_CLAUSE_ASYNC, + OMP_CLAUSE_WAIT, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_AUTO, + OMP_CLAUSE__CACHE_, OMP_CLAUSE_TILE. + + * gimplify.c (gimplify_adjust_omp_clauses): Discard + OMP_CLAUSE_TILE. + * omp-low.c (scan_sharing_clauses): Don't expect OMP_CLAUSE_TILE. + + * omp-low.c (scan_sharing_clauses): Don't expect + OMP_CLAUSE__CACHE_. + +2016-06-10 Alan Hayward <alan.hayward@arm.com> + + PR tree-optimization/71407 + PR tree-optimization/71416 + * tree-vect-loop.c (vectorizable_live_operation): Use vectype for + BIT_FIELD_REF type. + +2016-06-10 Richard Biener <rguenther@suse.de> + + PR middle-end/71477 + * cfgloop.c (alloc_loop): Initialize nb_iterations_likely_upper_bound. + +2016-06-09 Eric Botcazou <ebotcazou@adacore.com> + + * df-problems.c (df_note_bb_compute): Guard use of DF_INSN_INFO_GET. + +2016-06-09 Vladimir Makarov <vmakarov@redhat.com> + Jiong Wang <jiong.wang@arm.com> + + PR rtl-optimization/70751 + * lra-constraints.c (process_alt_operands): Recognize Non-pseudo + spilled into memory. + +2016-06-09 Jonathan Yong <10walls@gmail.com> + + Revert: + 2015-09-21 Jonathan Yong <10walls@gmail.com> + + * config/i386/cygwin.h (STARTFILE_SPEC): Explicitly search + sysroot/usr/lib/32api for additional win32 libraries, + fixes failing Cygwin bootstrapping. + +2016-06-09 Marcin Baczyński <marbacz@gmail.com> + + * diagnostic.h (diagnostic_line_cutoff, diagnostic_flush_buffer): + Delete. + +2016-06-09 David Malcolm <dmalcolm@redhat.com> + + PR bootstrap/71471 + * pretty-print.c (pp_indent): Specify that %p is printed in a + host-dependent manner. + (test_pp_format): Remove the test for %p. + +2016-06-09 Maciej W. Rozycki <macro@imgtec.com> + + * config/mips/mips.c (mips_output_jump): Fix formatting. + +2016-06-09 Richard Biener <rguenther@suse.de> + + PR tree-optimization/71462 + * tree-ssa-loop-manip.c (find_uses_to_rename): Guard against + removed blocks. + +2016-06-09 Martin Liska <mliska@suse.cz> + + * predict.c (dump_prediction): Add new argument. + (enum predictor_reason): New enum. + (struct predictor_hash): New struct. + (predictor_hash::hash): New function. + (predictor_hash::equal): Likewise. + (not_removed_prediction_p): New function. + (prune_predictions_for_bb): Likewise. + (combine_predictions_for_bb): Prune predictions. + +2016-06-09 Martin Liska <mliska@suse.cz> + + * predict.c (filter_predictions): New function. + (remove_predictions_associated_with_edge): Use the filter + function. + (equal_edge_p): New function. + +2016-06-09 Stefan Bruens <stefan.bruens@rwth-aachen.de> + + * doc/invoke.texi (ARM Options): Use lexicographical ordering. + Correct usage of @samp vs @option, add @samp where appropriate. + Add -march={armv6k,armv6z,arm6zk}, remove -march=ep9312. + Add armv6s-m and document it, as it is no official ARM name. + +2016-06-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * ifcvt.c (struct noce_if_info): Add transform_name field. + (noce_try_move): Set if_info->transform_name to the function name. + (noce_try_ifelse_collapse): Likewise. + (noce_try_store_flag): Likewise. + (noce_try_inverse_constants): Likewise. + (noce_try_store_flag_constants): Likewise. + (noce_try_addcc): Likewise. + (noce_try_store_flag_mask): Likewise. + (noce_try_cmove): Likewise. + (noce_try_cmove_arith): Likewise. + (noce_try_minmax): Likewise. + (noce_try_abs): Likewise. + (noce_try_sign_mask): Likewise. + (noce_try_bitop): Likewise. + (noce_convert_multiple_sets): Likewise. + (noce_process_if_block): Print if_info->transform_name to + dump_file if transformation succeeded. + +2016-06-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * config/arm/cortex-a57.md (cortex_a57_alu): + Handle csel type. + +2016-06-08 Martin Sebor <msebor@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/70507 + PR c/68120 + * builtins.def (BUILT_IN_ADD_OVERFLOW_P, BUILT_IN_SUB_OVERFLOW_P, + BUILT_IN_MUL_OVERFLOW_P): New builtins. + * builtins.c: Include gimple-fold.h. + (fold_builtin_arith_overflow): Handle + BUILT_IN_{ADD,SUB,MUL}_OVERFLOW_P. + (fold_builtin_3): Likewise. + * doc/extend.texi (Integer Overflow Builtins): Document + __builtin_{add,sub,mul}_overflow_p. + +2016-06-08 Jose E. Marchesi <jose.marchesi@oracle.com> + + * config/sparc/driver-sparc.c (cpu_names): Fix the entry for the + SPARC-M7 and add an entry for SPARC-S7 cpus (Sonoma). + +2016-06-08 Alan Lawrence <alan.lawrence@arm.com> + + * config/aarch64/aarch64.c (aarch64_function_arg_alignment): + Rewrite, looking one level down for records and arrays. + 2016-06-08 David Malcolm <dmalcolm@redhat.com> * pretty-print.c: Include "selftest.h". @@ -250,8 +648,7 @@ 2016-06-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> - * simplify-rtx.c (simplify_cond_clz_ctz): Delete 'mode' local - variable. + * simplify-rtx.c (simplify_cond_clz_ctz): Delete 'mode' local variable. 2016-06-07 Jakub Jelinek <jakub@redhat.com> @@ -612,7 +1009,7 @@ only edges out of BB are EH edges. 2016-06-04 Martin Sebor <msebor@redhat.com> - Marcin Baczyński <marbacz@gmail.com> + Marcin Baczyński <marbacz@gmail.com> PR c/48116 * doc/invoke.texi (-Wreturn-type): Mention not warning on return with diff --git a/gcc/ChangeLog.meissner b/gcc/ChangeLog.meissner index 6433f1e51b5..005533fad72 100644 --- a/gcc/ChangeLog.meissner +++ b/gcc/ChangeLog.meissner @@ -1,3 +1,8 @@ +2016-06-13 Michael Meissner <meissner@linux.vnet.ibm.com> + + Merge up to 237393. + * REVISION: Update subversion id. + 2016-06-12 Michael Meissner <meissner@the-meissners.org> * config/rs6000/vsx.md (vsx_extract_<mode>): Combine both sets of diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 67def45676b..aeb82dff722 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20160608 +20160613 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index fdcc42aa309..776f6d7503b 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1270,6 +1270,7 @@ OBJS = \ gcse.o \ gcse-common.o \ ggc-common.o \ + ggc-tests.o \ gimple.o \ gimple-builder.o \ gimple-expr.o \ @@ -2398,6 +2399,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(srcdir)/emit-rtl.c $(srcdir)/except.h $(srcdir)/explow.c $(srcdir)/expr.c \ $(srcdir)/expr.h \ $(srcdir)/function.c $(srcdir)/except.c \ + $(srcdir)/ggc-tests.c \ $(srcdir)/gcse.c $(srcdir)/godump.c \ $(srcdir)/lists.c $(srcdir)/optabs-libfuncs.c \ $(srcdir)/profile.c $(srcdir)/mcf.c \ diff --git a/gcc/REVISION b/gcc/REVISION index 8955822ebd4..8555586cc1a 100644 --- a/gcc/REVISION +++ b/gcc/REVISION @@ -1 +1 @@ -stage-test branch, based on subversion id 237222 +stage-test branch, based on subversion id 237393. diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 20edf04ee22..930e86681ff 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,41 @@ +2016-06-13 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (gnat_to_gnu_subprog_type): Build only a minimal + PARM_DECL when the parameter type is dummy. + * gcc-interface/trans.c (Call_to_gnu): Translate formal types before + formal objects. + +2016-06-13 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Deal with + PLUS_EXPR in the expression of a renaming. + +2016-06-13 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/utils2.c (known_alignment) <CALL_EXPR>: Deal specially + with calls to malloc. + +2016-06-11 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/trans.c (build_binary_op_trapv): If no operand is a + constant, use the generic implementation of the middle-end; otherwise + turn the dynamic conditions into static conditions and simplify. + +2016-06-11 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/trans.c (Case_Statement_to_gnu): Deal with characters. + +2016-06-11 Pierre-Marie de Rodat <derodat@adacore.com> + + * gcc-interface/decl.c (gnat_to_gnu_entity): Do not clobber + gnat_entity_name with temporary names for XUP and XUT types. + +2016-06-10 Martin Sebor <msebor@redhat.com> + + PR c/71392 + * gcc/ada/gcc-interface/utils.c (handle_nonnull_attribute): Accept + the nonnull attribute in type-generic builtins. + 2016-06-06 Eric Botcazou <ebotcazou@adacore.com> * gcc-interface/decl.c (Gigi_Equivalent_Type): Make sure equivalent diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 45878a7c635..0ce2d47f195 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -1003,6 +1003,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) && !call_is_atomic_load (inner)) || TREE_CODE (inner) == ADDR_EXPR || TREE_CODE (inner) == NULL_EXPR + || TREE_CODE (inner) == PLUS_EXPR || TREE_CODE (inner) == CONSTRUCTOR || CONSTANT_CLASS_P (inner) /* We need to detect the case where a temporary is created to @@ -2335,10 +2336,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) gnat_name = Packed_Array_Impl_Type (gnat_entity); else gnat_name = gnat_entity; - if (gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL) - gnu_entity_name = create_concat_name (gnat_name, "XUP"); - create_type_decl (gnu_entity_name, gnu_fat_type, artificial_p, - debug_info_p, gnat_entity); + tree xup_name + = (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL) + ? get_entity_name (gnat_name) + : create_concat_name (gnat_name, "XUP"); + create_type_decl (xup_name, gnu_fat_type, artificial_p, debug_info_p, + gnat_entity); /* Create the type to be designated by thin pointers: a record type for the array and its template. We used to shift the fields to have the @@ -2348,11 +2351,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) Note that GDB can handle standard DWARF information for them, so we don't have to name them as a GNAT encoding, except if specifically asked to. */ - if (gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL) - gnu_entity_name = create_concat_name (gnat_name, "XUT"); - else - gnu_entity_name = get_entity_name (gnat_name); - tem = build_unc_object_type (gnu_template_type, tem, gnu_entity_name, + tree xut_name + = (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL) + ? get_entity_name (gnat_name) + : create_concat_name (gnat_name, "XUT"); + tem = build_unc_object_type (gnu_template_type, tem, xut_name, debug_info_p); SET_TYPE_UNCONSTRAINED_ARRAY (tem, gnu_type); @@ -5956,8 +5959,11 @@ gnat_to_gnu_subprog_type (Entity_Id gnat_subprog, bool definition, else { + /* Build a minimal PARM_DECL without DECL_ARG_TYPE so that + Call_to_gnu will stop if it encounters the PARM_DECL. */ gnu_param - = create_param_decl (gnu_param_name, gnu_param_type); + = build_decl (input_location, PARM_DECL, gnu_param_name, + gnu_param_type); associate_subprog_with_dummy_type (gnat_subprog, gnu_param_type); incomplete_profile_p = true; diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index fb17cb2c381..f110e928b93 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -2472,13 +2472,15 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) static tree Case_Statement_to_gnu (Node_Id gnat_node) { - tree gnu_result, gnu_expr, gnu_label; + tree gnu_result, gnu_expr, gnu_type, gnu_label; Node_Id gnat_when; location_t end_locus; bool may_fallthru = false; gnu_expr = gnat_to_gnu (Expression (gnat_node)); gnu_expr = convert (get_base_type (TREE_TYPE (gnu_expr)), gnu_expr); + gnu_expr = maybe_character_value (gnu_expr); + gnu_type = TREE_TYPE (gnu_expr); /* We build a SWITCH_EXPR that contains the code with interspersed CASE_LABEL_EXPRs for each label. */ @@ -2548,6 +2550,11 @@ Case_Statement_to_gnu (Node_Id gnat_node) gcc_assert (!gnu_low || TREE_CODE (gnu_low) == INTEGER_CST); gcc_assert (!gnu_high || TREE_CODE (gnu_high) == INTEGER_CST); + if (gnu_low && TREE_TYPE (gnu_low) != gnu_type) + gnu_low = convert (gnu_type, gnu_low); + if (gnu_high && TREE_TYPE (gnu_high) != gnu_type) + gnu_high = convert (gnu_type, gnu_high); + add_stmt_with_node (build_case_label (gnu_low, gnu_high, label), gnat_choice); choices_added_p = true; @@ -2579,8 +2586,8 @@ Case_Statement_to_gnu (Node_Id gnat_node) /* Now emit a definition of the label the cases branch to, if any. */ if (may_fallthru) add_stmt (build1 (LABEL_EXPR, void_type_node, gnu_label)); - gnu_result = build3 (SWITCH_EXPR, TREE_TYPE (gnu_expr), gnu_expr, - end_stmt_group (), NULL_TREE); + gnu_result + = build3 (SWITCH_EXPR, gnu_type, gnu_expr, end_stmt_group (), NULL_TREE); return gnu_result; } @@ -4334,9 +4341,9 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, gnat_actual = Next_Actual (gnat_actual)) { Entity_Id gnat_formal_type = Etype (gnat_formal); + tree gnu_formal_type = gnat_to_gnu_type (gnat_formal_type); tree gnu_formal = present_gnu_tree (gnat_formal) ? get_gnu_tree (gnat_formal) : NULL_TREE; - tree gnu_formal_type = gnat_to_gnu_type (gnat_formal_type); const bool is_true_formal_parm = gnu_formal && TREE_CODE (gnu_formal) == PARM_DECL; const bool is_by_ref_formal_parm @@ -8868,19 +8875,16 @@ build_binary_op_trapv (enum tree_code code, tree gnu_type, tree left, tree rhs = gnat_protect_expr (right); tree type_max = TYPE_MAX_VALUE (gnu_type); tree type_min = TYPE_MIN_VALUE (gnu_type); - tree zero = build_int_cst (gnu_type, 0); - tree gnu_expr, rhs_lt_zero, tmp1, tmp2; - tree check_pos, check_neg, check; + tree gnu_expr, check; + int sgn; /* Assert that the precision is a power of 2. */ gcc_assert ((precision & (precision - 1)) == 0); - /* Prefer a constant or known-positive rhs to simplify checks. */ - if (!TREE_CONSTANT (rhs) - && commutative_tree_code (code) - && (TREE_CONSTANT (lhs) - || (!tree_expr_nonnegative_p (rhs) - && tree_expr_nonnegative_p (lhs)))) + /* Prefer a constant on the RHS to simplify checks. */ + if (TREE_CODE (rhs) != INTEGER_CST + && TREE_CODE (lhs) == INTEGER_CST + && (code == PLUS_EXPR || code == MULT_EXPR)) { tree tmp = lhs; lhs = rhs; @@ -8891,151 +8895,149 @@ build_binary_op_trapv (enum tree_code code, tree gnu_type, tree left, /* If we can fold the expression to a constant, just return it. The caller will deal with overflow, no need to generate a check. */ - if (TREE_CONSTANT (gnu_expr)) + if (TREE_CODE (gnu_expr) == INTEGER_CST) return gnu_expr; - rhs_lt_zero = tree_expr_nonnegative_p (rhs) - ? boolean_false_node - : build_binary_op (LT_EXPR, boolean_type_node, rhs, zero); - - /* ??? Should use more efficient check for operand_equal_p (lhs, rhs, 0) */ - - /* Try a few strategies that may be cheaper than the general - code at the end of the function, if the rhs is not known. - The strategies are: - - Call library function for 64-bit multiplication (complex) - - Widen, if input arguments are sufficiently small - - Determine overflow using wrapped result for addition/subtraction. */ - - if (!TREE_CONSTANT (rhs)) + /* If no operand is a constant, we use the generic implementation. */ + if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (rhs) != INTEGER_CST) { - /* Even for add/subtract double size to get another base type. */ - const unsigned int needed_precision = precision * 2; - - if (code == MULT_EXPR && precision == 64) + /* Never inline a 64-bit mult for a 32-bit target, it's way too long. */ + if (code == MULT_EXPR && precision == 64 && BITS_PER_WORD < 64) { - tree int_64 = gnat_type_for_size (64, 0); - + tree int64 = gnat_type_for_size (64, 0); return convert (gnu_type, build_call_n_expr (mulv64_decl, 2, - convert (int_64, lhs), - convert (int_64, rhs))); + convert (int64, lhs), + convert (int64, rhs))); } - if (needed_precision <= BITS_PER_WORD - || (code == MULT_EXPR && needed_precision <= LONG_LONG_TYPE_SIZE)) - { - tree wide_type = gnat_type_for_size (needed_precision, 0); - tree wide_result = build_binary_op (code, wide_type, - convert (wide_type, lhs), - convert (wide_type, rhs)); - - check = build_binary_op - (TRUTH_ORIF_EXPR, boolean_type_node, - build_binary_op (LT_EXPR, boolean_type_node, wide_result, - convert (wide_type, type_min)), - build_binary_op (GT_EXPR, boolean_type_node, wide_result, - convert (wide_type, type_max))); - - return - emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node); - } + enum internal_fn icode; - if (code == PLUS_EXPR || code == MINUS_EXPR) + switch (code) { - tree unsigned_type = gnat_type_for_size (precision, 1); - tree wrapped_expr - = convert (gnu_type, - build_binary_op (code, unsigned_type, - convert (unsigned_type, lhs), - convert (unsigned_type, rhs))); - - /* Overflow when (rhs < 0) ^ (wrapped_expr < lhs)), for addition - or when (rhs < 0) ^ (wrapped_expr > lhs) for subtraction. */ - check - = build_binary_op (TRUTH_XOR_EXPR, boolean_type_node, rhs_lt_zero, - build_binary_op (code == PLUS_EXPR - ? LT_EXPR : GT_EXPR, - boolean_type_node, - wrapped_expr, lhs)); - - return - emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node); + case PLUS_EXPR: + icode = IFN_ADD_OVERFLOW; + break; + case MINUS_EXPR: + icode = IFN_SUB_OVERFLOW; + break; + case MULT_EXPR: + icode = IFN_MUL_OVERFLOW; + break; + default: + gcc_unreachable (); } + + tree gnu_ctype = build_complex_type (gnu_type); + tree call + = build_call_expr_internal_loc (UNKNOWN_LOCATION, icode, gnu_ctype, 2, + lhs, rhs); + tree tgt = save_expr (call); + gnu_expr = build1 (REALPART_EXPR, gnu_type, tgt); + check + = convert (boolean_type_node, build1 (IMAGPART_EXPR, gnu_type, tgt)); + return + emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node); } + /* If one operand is a constant, we expose the overflow condition to enable + a subsequent simplication or even elimination. */ switch (code) { case PLUS_EXPR: - /* When rhs >= 0, overflow when lhs > type_max - rhs. */ - check_pos = build_binary_op (GT_EXPR, boolean_type_node, lhs, - build_binary_op (MINUS_EXPR, gnu_type, - type_max, rhs)), - - /* When rhs < 0, overflow when lhs < type_min - rhs. */ - check_neg = build_binary_op (LT_EXPR, boolean_type_node, lhs, - build_binary_op (MINUS_EXPR, gnu_type, - type_min, rhs)); + sgn = tree_int_cst_sgn (rhs); + if (sgn > 0) + /* When rhs > 0, overflow when lhs > type_max - rhs. */ + check = build_binary_op (GT_EXPR, boolean_type_node, lhs, + build_binary_op (MINUS_EXPR, gnu_type, + type_max, rhs)); + else if (sgn < 0) + /* When rhs < 0, overflow when lhs < type_min - rhs. */ + check = build_binary_op (LT_EXPR, boolean_type_node, lhs, + build_binary_op (MINUS_EXPR, gnu_type, + type_min, rhs)); + else + return gnu_expr; break; case MINUS_EXPR: - /* When rhs >= 0, overflow when lhs < type_min + rhs. */ - check_pos = build_binary_op (LT_EXPR, boolean_type_node, lhs, - build_binary_op (PLUS_EXPR, gnu_type, - type_min, rhs)), - - /* When rhs < 0, overflow when lhs > type_max + rhs. */ - check_neg = build_binary_op (GT_EXPR, boolean_type_node, lhs, - build_binary_op (PLUS_EXPR, gnu_type, - type_max, rhs)); + if (TREE_CODE (lhs) == INTEGER_CST) + { + sgn = tree_int_cst_sgn (lhs); + if (sgn > 0) + /* When lhs > 0, overflow when rhs < lhs - type_max. */ + check = build_binary_op (LT_EXPR, boolean_type_node, rhs, + build_binary_op (MINUS_EXPR, gnu_type, + lhs, type_max)); + else if (sgn < 0) + /* When lhs < 0, overflow when rhs > lhs - type_min. */ + check = build_binary_op (GT_EXPR, boolean_type_node, rhs, + build_binary_op (MINUS_EXPR, gnu_type, + lhs, type_min)); + else + return gnu_expr; + } + else + { + sgn = tree_int_cst_sgn (rhs); + if (sgn > 0) + /* When rhs > 0, overflow when lhs < type_min + rhs. */ + check = build_binary_op (LT_EXPR, boolean_type_node, lhs, + build_binary_op (PLUS_EXPR, gnu_type, + type_min, rhs)); + else if (sgn < 0) + /* When rhs < 0, overflow when lhs > type_max + rhs. */ + check = build_binary_op (GT_EXPR, boolean_type_node, lhs, + build_binary_op (PLUS_EXPR, gnu_type, + type_max, rhs)); + else + return gnu_expr; + } break; case MULT_EXPR: - /* The check here is designed to be efficient if the rhs is constant, - but it will work for any rhs by using integer division. - Four different check expressions determine whether X * C overflows, - depending on C. - C == 0 => false - C > 0 => X > type_max / C || X < type_min / C - C == -1 => X == type_min - C < -1 => X > type_min / C || X < type_max / C */ - - tmp1 = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_max, rhs); - tmp2 = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_min, rhs); - - check_pos - = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node, - build_binary_op (NE_EXPR, boolean_type_node, zero, - rhs), - build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, - build_binary_op (GT_EXPR, - boolean_type_node, - lhs, tmp1), - build_binary_op (LT_EXPR, - boolean_type_node, - lhs, tmp2))); - - check_neg - = fold_build3 (COND_EXPR, boolean_type_node, - build_binary_op (EQ_EXPR, boolean_type_node, rhs, - build_int_cst (gnu_type, -1)), - build_binary_op (EQ_EXPR, boolean_type_node, lhs, - type_min), - build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, - build_binary_op (GT_EXPR, - boolean_type_node, - lhs, tmp2), - build_binary_op (LT_EXPR, - boolean_type_node, - lhs, tmp1))); + sgn = tree_int_cst_sgn (rhs); + if (sgn > 0) + { + if (integer_onep (rhs)) + return gnu_expr; + + tree lb = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_min, rhs); + tree ub = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_max, rhs); + + /* When rhs > 1, overflow outside [type_min/rhs; type_max/rhs]. */ + check + = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, + build_binary_op (LT_EXPR, boolean_type_node, + lhs, lb), + build_binary_op (GT_EXPR, boolean_type_node, + lhs, ub)); + } + else if (sgn < 0) + { + tree lb = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_max, rhs); + tree ub = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_min, rhs); + + if (integer_minus_onep (rhs)) + /* When rhs == -1, overflow if lhs == type_min. */ + check + = build_binary_op (EQ_EXPR, boolean_type_node, lhs, type_min); + else + /* When rhs < -1, overflow outside [type_max/rhs; type_min/rhs]. */ + check + = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, + build_binary_op (LT_EXPR, boolean_type_node, + lhs, lb), + build_binary_op (GT_EXPR, boolean_type_node, + lhs, ub)); + } + else + return gnu_expr; break; default: gcc_unreachable (); } - check = fold_build3 (COND_EXPR, boolean_type_node, rhs_lt_zero, check_neg, - check_pos); - return emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node); } diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 831b6e035aa..1f1e4d3b814 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -5833,10 +5833,14 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name), /* If no arguments are specified, all pointer arguments should be non-null. Verify a full prototype is given so that the arguments - will have the correct types when we actually check them later. */ + will have the correct types when we actually check them later. + Avoid diagnosing type-generic built-ins since those have no + prototype. */ if (!args) { - if (!prototype_p (type)) + if (!prototype_p (type) + && (!TYPE_ATTRIBUTES (type) + || !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)))) { error ("nonnull attribute without arguments on a non-prototype"); *no_add_attrs = true; diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index a0804e8e86d..aeb6cc3a3f7 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -171,6 +171,10 @@ known_alignment (tree exp) case CALL_EXPR: { + tree func = get_callee_fndecl (exp); + if (func && DECL_IS_MALLOC (func)) + return get_target_system_allocator_alignment () * BITS_PER_UNIT; + tree t = maybe_inline_call_in_expr (exp); if (t) return known_alignment (t); diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def index 089817a5c4d..99658883872 100644 --- a/gcc/builtin-attrs.def +++ b/gcc/builtin-attrs.def @@ -165,6 +165,7 @@ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL, ATTR_NONNULL, ATTR_NULL, \ /* Nothrow leaf functions whose pointer parameter(s) are all nonnull. */ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_LEAF, ATTR_NONNULL, ATTR_NULL, \ ATTR_NOTHROW_LEAF_LIST) +DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_LEAF_LIST, ATTR_LEAF, ATTR_NULL, ATTR_NOTHROW_NONNULL_LEAF) /* Nothrow functions whose first parameter is a nonnull pointer. */ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, \ ATTR_NOTHROW_LIST) @@ -183,6 +184,10 @@ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_5, ATTR_NONNULL, ATTR_LIST_5, \ /* Nothrow leaf functions which are type-generic. */ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_TYPEGENERIC_LEAF, ATTR_TYPEGENERIC, ATTR_NULL, \ ATTR_NOTHROW_LEAF_LIST) +/* Nothrow nonnull leaf functions that are type-generic. */ +DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF, + ATTR_TYPEGENERIC, ATTR_NULL, + ATTR_NOTHROW_NONNULL_LEAF) /* Nothrow const functions whose pointer parameter(s) are all nonnull. */ DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL, ATTR_CONST, ATTR_NULL, \ ATTR_NOTHROW_NONNULL) diff --git a/gcc/builtins.c b/gcc/builtins.c index d5191761680..5d234a5c827 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -64,6 +64,7 @@ along with GCC; see the file COPYING3. If not see #include "rtl-chkp.h" #include "internal-fn.h" #include "case-cfn-macros.h" +#include "gimple-fold.h" struct target_builtins default_target_builtins; @@ -7943,18 +7944,28 @@ fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1, /* Fold __builtin_{,s,u}{add,sub,mul}{,l,ll}_overflow, either into normal arithmetics if it can never overflow, or into internal functions that return both result of arithmetics and overflowed boolean flag in - a complex integer result, or some other check for overflow. */ + a complex integer result, or some other check for overflow. + Similarly fold __builtin_{add,sub,mul}_overflow_p to just the overflow + checking part of that. */ static tree fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode, tree arg0, tree arg1, tree arg2) { enum internal_fn ifn = IFN_LAST; - tree type = TREE_TYPE (TREE_TYPE (arg2)); - tree mem_arg2 = build_fold_indirect_ref_loc (loc, arg2); + /* The code of the expression corresponding to the type-generic + built-in, or ERROR_MARK for the type-specific ones. */ + enum tree_code opcode = ERROR_MARK; + bool ovf_only = false; + switch (fcode) { + case BUILT_IN_ADD_OVERFLOW_P: + ovf_only = true; + /* FALLTHRU */ case BUILT_IN_ADD_OVERFLOW: + opcode = PLUS_EXPR; + /* FALLTHRU */ case BUILT_IN_SADD_OVERFLOW: case BUILT_IN_SADDL_OVERFLOW: case BUILT_IN_SADDLL_OVERFLOW: @@ -7963,7 +7974,12 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode, case BUILT_IN_UADDLL_OVERFLOW: ifn = IFN_ADD_OVERFLOW; break; + case BUILT_IN_SUB_OVERFLOW_P: + ovf_only = true; + /* FALLTHRU */ case BUILT_IN_SUB_OVERFLOW: + opcode = MINUS_EXPR; + /* FALLTHRU */ case BUILT_IN_SSUB_OVERFLOW: case BUILT_IN_SSUBL_OVERFLOW: case BUILT_IN_SSUBLL_OVERFLOW: @@ -7972,7 +7988,12 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode, case BUILT_IN_USUBLL_OVERFLOW: ifn = IFN_SUB_OVERFLOW; break; + case BUILT_IN_MUL_OVERFLOW_P: + ovf_only = true; + /* FALLTHRU */ case BUILT_IN_MUL_OVERFLOW: + opcode = MULT_EXPR; + /* FALLTHRU */ case BUILT_IN_SMUL_OVERFLOW: case BUILT_IN_SMULL_OVERFLOW: case BUILT_IN_SMULLL_OVERFLOW: @@ -7984,6 +8005,25 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode, default: gcc_unreachable (); } + + /* For the "generic" overloads, the first two arguments can have different + types and the last argument determines the target type to use to check + for overflow. The arguments of the other overloads all have the same + type. */ + tree type = ovf_only ? TREE_TYPE (arg2) : TREE_TYPE (TREE_TYPE (arg2)); + + /* For the __builtin_{add,sub,mul}_overflow_p builtins, when the first two + arguments are constant, attempt to fold the built-in call into a constant + expression indicating whether or not it detected an overflow. */ + if (ovf_only + && TREE_CODE (arg0) == INTEGER_CST + && TREE_CODE (arg1) == INTEGER_CST) + /* Perform the computation in the target type and check for overflow. */ + return omit_one_operand_loc (loc, boolean_type_node, + arith_overflowed_p (opcode, type, arg0, arg1) + ? boolean_true_node : boolean_false_node, + arg2); + tree ctype = build_complex_type (type); tree call = build_call_expr_internal_loc (loc, ifn, ctype, 2, arg0, arg1); @@ -7991,6 +8031,11 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode, tree intres = build1_loc (loc, REALPART_EXPR, type, tgt); tree ovfres = build1_loc (loc, IMAGPART_EXPR, type, tgt); ovfres = fold_convert_loc (loc, boolean_type_node, ovfres); + + if (ovf_only) + return omit_one_operand_loc (loc, boolean_type_node, ovfres, arg2); + + tree mem_arg2 = build_fold_indirect_ref_loc (loc, arg2); tree store = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, mem_arg2, intres); return build2_loc (loc, COMPOUND_EXPR, boolean_type_node, store, ovfres); @@ -8340,6 +8385,9 @@ fold_builtin_3 (location_t loc, tree fndecl, case BUILT_IN_ADD_OVERFLOW: case BUILT_IN_SUB_OVERFLOW: case BUILT_IN_MUL_OVERFLOW: + case BUILT_IN_ADD_OVERFLOW_P: + case BUILT_IN_SUB_OVERFLOW_P: + case BUILT_IN_MUL_OVERFLOW_P: case BUILT_IN_SADD_OVERFLOW: case BUILT_IN_SADDL_OVERFLOW: case BUILT_IN_SADDLL_OVERFLOW: diff --git a/gcc/builtins.def b/gcc/builtins.def index 527503800ff..33a7626b70a 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -707,28 +707,31 @@ DEF_C94_BUILTIN (BUILT_IN_TOWLOWER, "towlower", BT_FN_WINT_WINT, ATTR_PUR DEF_C94_BUILTIN (BUILT_IN_TOWUPPER, "towupper", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) /* Category: integer overflow checking builtins. */ -DEF_GCC_BUILTIN (BUILT_IN_ADD_OVERFLOW, "add_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_TYPEGENERIC_LEAF) -DEF_GCC_BUILTIN (BUILT_IN_SUB_OVERFLOW, "sub_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_TYPEGENERIC_LEAF) -DEF_GCC_BUILTIN (BUILT_IN_MUL_OVERFLOW, "mul_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ADD_OVERFLOW, "add_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_SUB_OVERFLOW, "sub_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_MUL_OVERFLOW, "mul_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ADD_OVERFLOW_P, "add_overflow_p", BT_FN_BOOL_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_SUB_OVERFLOW_P, "sub_overflow_p", BT_FN_BOOL_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_MUL_OVERFLOW_P, "mul_overflow_p", BT_FN_BOOL_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) /* Clang compatibility. */ -DEF_GCC_BUILTIN (BUILT_IN_SADD_OVERFLOW, "sadd_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_SADDL_OVERFLOW, "saddl_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_SADDLL_OVERFLOW, "saddll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_SSUB_OVERFLOW, "ssub_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_SSUBL_OVERFLOW, "ssubl_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_SSUBLL_OVERFLOW, "ssubll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_SMUL_OVERFLOW, "smul_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_SMULL_OVERFLOW, "smull_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_SMULLL_OVERFLOW, "smulll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_UADD_OVERFLOW, "uadd_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_UADDL_OVERFLOW, "uaddl_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_UADDLL_OVERFLOW, "uaddll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_USUB_OVERFLOW, "usub_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_USUBL_OVERFLOW, "usubl_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_USUBLL_OVERFLOW, "usubll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_UMUL_OVERFLOW, "umul_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_UMULL_OVERFLOW, "umull_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_LEAF_LIST) -DEF_GCC_BUILTIN (BUILT_IN_UMULLL_OVERFLOW, "umulll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_SADD_OVERFLOW, "sadd_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_SADDL_OVERFLOW, "saddl_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_SADDLL_OVERFLOW, "saddll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_SSUB_OVERFLOW, "ssub_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_SSUBL_OVERFLOW, "ssubl_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_SSUBLL_OVERFLOW, "ssubll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_SMUL_OVERFLOW, "smul_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_SMULL_OVERFLOW, "smull_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_SMULLL_OVERFLOW, "smulll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_UADD_OVERFLOW, "uadd_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_UADDL_OVERFLOW, "uaddl_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_UADDLL_OVERFLOW, "uaddll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_USUB_OVERFLOW, "usub_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_USUBL_OVERFLOW, "usubl_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_USUBLL_OVERFLOW, "usubll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_UMUL_OVERFLOW, "umul_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_UMULL_OVERFLOW, "umull_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_UMULLL_OVERFLOW, "umulll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST) /* Category: miscellaneous builtins. */ DEF_LIB_BUILTIN (BUILT_IN_ABORT, "abort", BT_FN_VOID, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST) diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 1cd8aa7ad32..a53fc9cceb5 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,28 @@ +2016-06-10 Jakub Jelinek <jakub@redhat.com> + + PR c/68657 + * c.opt (Wpsabi): Add Warning flag. + +2016-06-10 Martin Sebor <msebor@redhat.com> + + PR c/71392 + * gcc/c-family/c-common.c (handle_nonnull_attribute): Accept + the nonnull attribute in type-generic builtins. + +2016-06-09 Martin Sebor <msebor@redhat.com> + + PR c/70883 + * c-common.c (builtin_function_validate_nargs): Make text of error + message consistent with others like it. + +2016-06-08 Martin Sebor <msebor@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/70507 + PR c/68120 + * c-common.c (check_builtin_function_arguments): Handle + BUILT_IN_{ADD,SUB,MUL}_OVERFLOW_P. + 2016-06-08 Richard Biener <rguenther@suse.de> * c-common.c (parse_optimize_options): Improve diagnostic messages. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 4e75e51c013..85f3a03146e 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -9040,10 +9040,14 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name), /* If no arguments are specified, all pointer arguments should be non-null. Verify a full prototype is given so that the arguments - will have the correct types when we actually check them later. */ + will have the correct types when we actually check them later. + Avoid diagnosing type-generic built-ins since those have no + prototype. */ if (!args) { - if (!prototype_p (type)) + if (!prototype_p (type) + && (!TYPE_ATTRIBUTES (type) + || !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)))) { error ("nonnull attribute without arguments on a non-prototype"); *no_add_attrs = true; @@ -9828,7 +9832,7 @@ builtin_function_validate_nargs (location_t loc, tree fndecl, int nargs, { if (nargs < required) { - error_at (loc, "not enough arguments to function %qE", fndecl); + error_at (loc, "too few arguments to function %qE", fndecl); return false; } else if (nargs > required) @@ -9989,6 +9993,23 @@ check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc, } return false; + case BUILT_IN_ADD_OVERFLOW_P: + case BUILT_IN_SUB_OVERFLOW_P: + case BUILT_IN_MUL_OVERFLOW_P: + if (builtin_function_validate_nargs (loc, fndecl, nargs, 3)) + { + unsigned i; + for (i = 0; i < 3; i++) + if (!INTEGRAL_TYPE_P (TREE_TYPE (args[i]))) + { + error_at (ARG_LOCATION (i), "argument %u in call to function " + "%qE does not have integral type", i + 1, fndecl); + return false; + } + return true; + } + return false; + default: return true; } diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 918df16ea99..761a83bcfb3 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -265,7 +265,7 @@ C++ ObjC++ Var(warn_abi_tag) Warning Warn if a subobject has an abi_tag attribute that the complete object type does not have. Wpsabi -C ObjC C++ ObjC++ LTO Var(warn_psabi) Init(1) Undocumented LangEnabledBy(C ObjC C++ ObjC++,Wabi) +C ObjC C++ ObjC++ LTO Var(warn_psabi) Init(1) Warning Undocumented LangEnabledBy(C ObjC C++ ObjC++,Wabi) Waddress C ObjC C++ ObjC++ Var(warn_address) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 9f0b91afb6a..08fc250f79a 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,27 @@ +2016-06-13 David Malcolm <dmalcolm@redhat.com> + + * c-parser.c (c_parser_initelt): Provide location of name for new + location_t param of set_init_label. + * c-tree.h (set_init_label): Add location_t param. + * c-typeck.c (set_init_index): Add "fieldname_loc" location_t + param and use it when issuing error messages about unrecognized + field names. Attempt to provide a fixit hint if appropriate, + otherwise update the error message to provide the type name. + +2016-06-10 Thomas Schwinge <thomas@codesourcery.com> + + PR c/71381 + * c-parser.c (c_parser_omp_variable_list) <OMP_CLAUSE__CACHE_>: + Loosen checking. + +2016-06-08 Martin Sebor <msebor@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/70507 + PR c/68120 + * c-typeck.c (convert_arguments): Don't promote last argument + of BUILT_IN_{ADD,SUB,MUL}_OVERFLOW_P. + 2016-06-08 Marek Polacek <polacek@redhat.com> PR c/71418 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 2fef1acebd1..ff32479685e 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -4397,6 +4397,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) /* Old-style structure member designator. */ set_init_label (c_parser_peek_token (parser)->location, c_parser_peek_token (parser)->value, + c_parser_peek_token (parser)->location, braced_init_obstack); /* Use the colon as the error location. */ pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic, @@ -4426,6 +4427,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) if (c_parser_next_token_is (parser, CPP_NAME)) { set_init_label (des_loc, c_parser_peek_token (parser)->value, + c_parser_peek_token (parser)->location, braced_init_obstack); c_parser_consume_token (parser); } @@ -10613,6 +10615,8 @@ c_parser_omp_variable_list (c_parser *parser, switch (kind) { case OMP_CLAUSE__CACHE_: + /* The OpenACC cache directive explicitly only allows "array + elements or subarrays". */ if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE) { c_parser_error (parser, "expected %<[%>"); @@ -10678,25 +10682,6 @@ c_parser_omp_variable_list (c_parser *parser, break; } - if (kind == OMP_CLAUSE__CACHE_) - { - if (TREE_CODE (low_bound) != INTEGER_CST - && !TREE_READONLY (low_bound)) - { - error_at (clause_loc, - "%qD is not a constant", low_bound); - t = error_mark_node; - } - - if (TREE_CODE (length) != INTEGER_CST - && !TREE_READONLY (length)) - { - error_at (clause_loc, - "%qD is not a constant", length); - t = error_mark_node; - } - } - t = tree_cons (low_bound, length, t); } break; diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index b4374e3e4bf..8f10a13f763 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -639,7 +639,7 @@ extern void finish_implicit_inits (location_t, struct obstack *); extern void push_init_level (location_t, int, struct obstack *); extern struct c_expr pop_init_level (location_t, int, struct obstack *); extern void set_init_index (location_t, tree, tree, struct obstack *); -extern void set_init_label (location_t, tree, struct obstack *); +extern void set_init_label (location_t, tree, location_t, struct obstack *); extern void process_init_element (location_t, struct c_expr, bool, struct obstack *); extern tree build_compound_literal (location_t, tree, tree, bool); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index cd8e9e57b3a..ea04d5eed76 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -3186,6 +3186,7 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, const bool type_generic = fundecl && lookup_attribute ("type generic", TYPE_ATTRIBUTES (TREE_TYPE (fundecl))); bool type_generic_remove_excess_precision = false; + bool type_generic_overflow_p = false; tree selector; /* Change pointer to function to the function itself for @@ -3215,8 +3216,15 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, type_generic_remove_excess_precision = true; break; + case BUILT_IN_ADD_OVERFLOW_P: + case BUILT_IN_SUB_OVERFLOW_P: + case BUILT_IN_MUL_OVERFLOW_P: + /* The last argument of these type-generic builtins + should not be promoted. */ + type_generic_overflow_p = true; + break; + default: - type_generic_remove_excess_precision = false; break; } } @@ -3466,9 +3474,12 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, parmval = convert (double_type_node, val); } } - else if (excess_precision && !type_generic) + else if ((excess_precision && !type_generic) + || (type_generic_overflow_p && parmnum == 2)) /* A "double" argument with excess precision being passed - without a prototype or in variable arguments. */ + without a prototype or in variable arguments. + The last argument of __builtin_*_overflow_p should not be + promoted. */ parmval = convert (valtype, val); else if ((invalid_func_diag = targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val))) @@ -8200,7 +8211,7 @@ set_init_index (location_t loc, tree first, tree last, /* Within a struct initializer, specify the next field to be initialized. */ void -set_init_label (location_t loc, tree fieldname, +set_init_label (location_t loc, tree fieldname, location_t fieldname_loc, struct obstack *braced_init_obstack) { tree field; @@ -8219,7 +8230,24 @@ set_init_label (location_t loc, tree fieldname, field = lookup_field (constructor_type, fieldname); if (field == 0) - error_at (loc, "unknown field %qE specified in initializer", fieldname); + { + tree guessed_id = lookup_field_fuzzy (constructor_type, fieldname); + if (guessed_id) + { + rich_location rich_loc (line_table, fieldname_loc); + source_range component_range = + get_range_from_loc (line_table, fieldname_loc); + rich_loc.add_fixit_replace (component_range, + IDENTIFIER_POINTER (guessed_id)); + error_at_rich_loc + (&rich_loc, + "%qT has no member named %qE; did you mean %qE?", + constructor_type, fieldname, guessed_id); + } + else + error_at (fieldname_loc, "%qT has no member named %qE", + constructor_type, fieldname); + } else do { diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index 27ccfb226c9..5650f0d92c5 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -331,6 +331,7 @@ alloc_loop (void) loop->exits->next = loop->exits->prev = loop->exits; loop->can_be_parallel = false; loop->nb_iterations_upper_bound = 0; + loop->nb_iterations_likely_upper_bound = 0; loop->nb_iterations_estimate = 0; return loop; } diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index b60e5c52df6..a0db3a4f632 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1961,22 +1961,23 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, static unsigned int aarch64_function_arg_alignment (machine_mode mode, const_tree type) { - unsigned int alignment; + if (!type) + return GET_MODE_ALIGNMENT (mode); + if (integer_zerop (TYPE_SIZE (type))) + return 0; - if (type) - { - if (!integer_zerop (TYPE_SIZE (type))) - { - if (TYPE_MODE (type) == mode) - alignment = TYPE_ALIGN (type); - else - alignment = GET_MODE_ALIGNMENT (mode); - } - else - alignment = 0; - } - else - alignment = GET_MODE_ALIGNMENT (mode); + gcc_assert (TYPE_MODE (type) == mode); + + if (!AGGREGATE_TYPE_P (type)) + return TYPE_ALIGN (TYPE_MAIN_VARIANT (type)); + + if (TREE_CODE (type) == ARRAY_TYPE) + return TYPE_ALIGN (TREE_TYPE (type)); + + unsigned int alignment = 0; + + for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) + alignment = std::max (alignment, DECL_ALIGN (field)); return alignment; } diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index aaaabb761cf..1ba2ebb630e 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -163,6 +163,7 @@ extern const char *arm_output_iwmmxt_shift_immediate (const char *, rtx *, bool) extern const char *arm_output_iwmmxt_tinsr (rtx *); extern unsigned int arm_sync_loop_insns (rtx , rtx *); extern int arm_attr_length_push_multi(rtx, rtx); +extern int arm_attr_length_pop_multi(rtx *, bool, bool); extern void arm_expand_compare_and_swap (rtx op[]); extern void arm_split_compare_and_swap (rtx op[]); extern void arm_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 47d2447ed34..3503c15420e 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -27793,7 +27793,7 @@ arm_preferred_rename_class (reg_class_t rclass) return NO_REGS; } -/* Compute the atrribute "length" of insn "*push_multi". +/* Compute the attribute "length" of insn "*push_multi". So this function MUST be kept in sync with that insn pattern. */ int arm_attr_length_push_multi(rtx parallel_op, rtx first_op) @@ -27810,6 +27810,11 @@ arm_attr_length_push_multi(rtx parallel_op, rtx first_op) /* Thumb2 mode. */ regno = REGNO (first_op); + /* For PUSH/STM under Thumb2 mode, we can use 16-bit encodings if the register + list is 8-bit. Normally this means all registers in the list must be + LO_REGS, that is (R0 -R7). If any HI_REGS used, then we must use 32-bit + encodings. There is one exception for PUSH that LR in HI_REGS can be used + with 16-bit encoding. */ hi_reg = (REGNO_REG_CLASS (regno) == HI_REGS) && (regno != LR_REGNUM); for (i = 1; i < num_saves && !hi_reg; i++) { @@ -27822,6 +27827,56 @@ arm_attr_length_push_multi(rtx parallel_op, rtx first_op) return 4; } +/* Compute the attribute "length" of insn. Currently, this function is used + for "*load_multiple_with_writeback", "*pop_multiple_with_return" and + "*pop_multiple_with_writeback_and_return". OPERANDS is the toplevel PARALLEL + rtx, RETURN_PC is true if OPERANDS contains return insn. WRITE_BACK_P is + true if OPERANDS contains insn which explicit updates base register. */ + +int +arm_attr_length_pop_multi (rtx *operands, bool return_pc, bool write_back_p) +{ + /* ARM mode. */ + if (TARGET_ARM) + return 4; + /* Thumb1 mode. */ + if (TARGET_THUMB1) + return 2; + + rtx parallel_op = operands[0]; + /* Initialize to elements number of PARALLEL. */ + unsigned indx = XVECLEN (parallel_op, 0) - 1; + /* Initialize the value to base register. */ + unsigned regno = REGNO (operands[1]); + /* Skip return and write back pattern. + We only need register pop pattern for later analysis. */ + unsigned first_indx = 0; + first_indx += return_pc ? 1 : 0; + first_indx += write_back_p ? 1 : 0; + + /* A pop operation can be done through LDM or POP. If the base register is SP + and if it's with write back, then a LDM will be alias of POP. */ + bool pop_p = (regno == SP_REGNUM && write_back_p); + bool ldm_p = !pop_p; + + /* Check base register for LDM. */ + if (ldm_p && REGNO_REG_CLASS (regno) == HI_REGS) + return 4; + + /* Check each register in the list. */ + for (; indx >= first_indx; indx--) + { + regno = REGNO (XEXP (XVECEXP (parallel_op, 0, indx), 0)); + /* For POP, PC in HI_REGS can be used with 16-bit encoding. See similar + comment in arm_attr_length_push_multi. */ + if (REGNO_REG_CLASS (regno) == HI_REGS + && (regno != PC_REGNUM || ldm_p)) + return 4; + } + + return 2; +} + /* Compute the number of instructions emitted by output_move_double. */ int arm_count_output_move_double_insns (rtx *operands) diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 065e7da4bfa..f0cdd669191 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -80,11 +80,6 @@ extern arm_cc arm_current_cc; extern int arm_target_label; extern int arm_ccfsm_state; extern GTY(()) rtx arm_target_insn; -/* The label of the current constant pool. */ -extern rtx pool_vector_label; -/* Set to 1 when a return insn is output, this means that the epilogue - is not needed. */ -extern int return_used_this_function; /* Callback to output language specific object attributes. */ extern void (*arm_lang_output_object_attributes_hook)(void); diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 04714a1335e..16498316bee 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -10562,7 +10562,11 @@ } " [(set_attr "type" "load4") - (set_attr "predicable" "yes")] + (set_attr "predicable" "yes") + (set (attr "length") + (symbol_ref "arm_attr_length_pop_multi (operands, + /*return_pc=*/false, + /*write_back_p=*/true)"))] ) ;; Pop with return (as used in epilogue RTL) @@ -10591,7 +10595,10 @@ } " [(set_attr "type" "load4") - (set_attr "predicable" "yes")] + (set_attr "predicable" "yes") + (set (attr "length") + (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true, + /*write_back_p=*/true)"))] ) (define_insn "*pop_multiple_with_return" @@ -10611,7 +10618,10 @@ } " [(set_attr "type" "load4") - (set_attr "predicable" "yes")] + (set_attr "predicable" "yes") + (set (attr "length") + (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true, + /*write_back_p=*/false)"))] ) ;; Load into PC and return diff --git a/gcc/config/arm/cortex-a57.md b/gcc/config/arm/cortex-a57.md index 37912db4643..c8cf80f4ba7 100644 --- a/gcc/config/arm/cortex-a57.md +++ b/gcc/config/arm/cortex-a57.md @@ -297,7 +297,7 @@ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ alu_sreg,alus_sreg,logic_reg,logics_reg,\ adc_imm,adcs_imm,adc_reg,adcs_reg,\ - adr,bfm,clz,rbit,rev,alu_dsp_reg,\ + adr,bfm,clz,csel,rbit,rev,alu_dsp_reg,\ rotate_imm,shift_imm,shift_reg,\ mov_imm,mov_reg,\ mvn_imm,mvn_reg,\ diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h index 182e4d62658..1d95cd70ad8 100644 --- a/gcc/config/i386/cygwin.h +++ b/gcc/config/i386/cygwin.h @@ -39,7 +39,6 @@ along with GCC; see the file COPYING3. If not see #undef STARTFILE_SPEC #define STARTFILE_SPEC "\ - -L%R/usr/lib/w32api \ %{!shared: %{!mdll: crt0%O%s \ %{pg:gcrt0%O%s}}}\ %{shared:crtbeginS.o%s;:crtbegin.o%s} \ diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def index c66f65108f8..7eb6fc96e66 100644 --- a/gcc/config/i386/i386-builtin-types.def +++ b/gcc/config/i386/i386-builtin-types.def @@ -73,6 +73,7 @@ DEF_PRIMITIVE_TYPE (FLOAT, float_type_node) DEF_PRIMITIVE_TYPE (DOUBLE, double_type_node) DEF_PRIMITIVE_TYPE (FLOAT80, float80_type_node) DEF_PRIMITIVE_TYPE (FLOAT128, float128_type_node) +DEF_PRIMITIVE_TYPE (CONST_STRING, const_string_type_node) # MMX vectors DEF_VECTOR_TYPE (V2SF, FLOAT) @@ -191,6 +192,7 @@ DEF_FUNCTION_TYPE (PVOID) DEF_FUNCTION_TYPE (FLOAT, FLOAT) DEF_FUNCTION_TYPE (FLOAT128, FLOAT128) +DEF_FUNCTION_TYPE (FLOAT128, CONST_STRING) DEF_FUNCTION_TYPE (INT, INT) DEF_FUNCTION_TYPE (INT, V16QI) DEF_FUNCTION_TYPE (INT, V2DF) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b807a9a0004..c5e5e1238a5 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -32718,6 +32718,8 @@ enum ix86_builtins /* TFmode support builtins. */ IX86_BUILTIN_INFQ, IX86_BUILTIN_HUGE_VALQ, + IX86_BUILTIN_NANQ, + IX86_BUILTIN_NANSQ, IX86_BUILTIN_FABSQ, IX86_BUILTIN_COPYSIGNQ, @@ -38105,11 +38107,28 @@ ix86_fold_builtin (tree fndecl, int n_args, { enum ix86_builtins fn_code = (enum ix86_builtins) DECL_FUNCTION_CODE (fndecl); - if (fn_code == IX86_BUILTIN_CPU_IS - || fn_code == IX86_BUILTIN_CPU_SUPPORTS) + switch (fn_code) { + case IX86_BUILTIN_CPU_IS: + case IX86_BUILTIN_CPU_SUPPORTS: gcc_assert (n_args == 1); - return fold_builtin_cpu (fndecl, args); + return fold_builtin_cpu (fndecl, args); + + case IX86_BUILTIN_NANQ: + case IX86_BUILTIN_NANSQ: + { + tree type = TREE_TYPE (TREE_TYPE (fndecl)); + const char *str = c_getstr (*args); + int quiet = fn_code == IX86_BUILTIN_NANQ; + REAL_VALUE_TYPE real; + + if (str && real_nan (&real, str, quiet, TYPE_MODE (type))) + return build_real (type, real); + return NULL_TREE; + } + + default: + break; } } @@ -38210,7 +38229,7 @@ ix86_init_builtins_va_builtins_abi (void) static void ix86_init_builtin_types (void) { - tree float128_type_node, float80_type_node; + tree float128_type_node, float80_type_node, const_string_type_node; /* The __float80 type. */ float80_type_node = long_double_type_node; @@ -38230,6 +38249,10 @@ ix86_init_builtin_types (void) layout_type (float128_type_node); lang_hooks.types.register_builtin_type (float128_type_node, "__float128"); + const_string_type_node + = build_pointer_type (build_qualified_type + (char_type_node, TYPE_QUAL_CONST)); + /* This macro is built by i386-builtin-types.awk. */ DEFINE_BUILTIN_PRIMITIVE_TYPES; } @@ -38237,7 +38260,7 @@ ix86_init_builtin_types (void) static void ix86_init_builtins (void) { - tree t; + tree ftype, decl; ix86_init_builtin_types (); @@ -38250,19 +38273,31 @@ ix86_init_builtins (void) def_builtin_const (0, "__builtin_huge_valq", FLOAT128_FTYPE_VOID, IX86_BUILTIN_HUGE_VALQ); + ftype = ix86_get_builtin_func_type (FLOAT128_FTYPE_CONST_STRING); + decl = add_builtin_function ("__builtin_nanq", ftype, IX86_BUILTIN_NANQ, + BUILT_IN_MD, "nanq", NULL_TREE); + TREE_READONLY (decl) = 1; + ix86_builtins[(int) IX86_BUILTIN_NANQ] = decl; + + decl = add_builtin_function ("__builtin_nansq", ftype, IX86_BUILTIN_NANSQ, + BUILT_IN_MD, "nansq", NULL_TREE); + TREE_READONLY (decl) = 1; + ix86_builtins[(int) IX86_BUILTIN_NANSQ] = decl; + /* We will expand them to normal call if SSE isn't available since they are used by libgcc. */ - t = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128); - t = add_builtin_function ("__builtin_fabsq", t, IX86_BUILTIN_FABSQ, - BUILT_IN_MD, "__fabstf2", NULL_TREE); - TREE_READONLY (t) = 1; - ix86_builtins[(int) IX86_BUILTIN_FABSQ] = t; - - t = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128_FLOAT128); - t = add_builtin_function ("__builtin_copysignq", t, IX86_BUILTIN_COPYSIGNQ, - BUILT_IN_MD, "__copysigntf3", NULL_TREE); - TREE_READONLY (t) = 1; - ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = t; + ftype = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128); + decl = add_builtin_function ("__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ, + BUILT_IN_MD, "__fabstf2", NULL_TREE); + TREE_READONLY (decl) = 1; + ix86_builtins[(int) IX86_BUILTIN_FABSQ] = decl; + + ftype = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128_FLOAT128); + decl = add_builtin_function ("__builtin_copysignq", ftype, + IX86_BUILTIN_COPYSIGNQ, BUILT_IN_MD, + "__copysigntf3", NULL_TREE); + TREE_READONLY (decl) = 1; + ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = decl; ix86_init_tm_builtins (); ix86_init_mmx_sse_builtins (); @@ -41463,6 +41498,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, return target; } + case IX86_BUILTIN_NANQ: + case IX86_BUILTIN_NANSQ: + return expand_call (exp, target, ignore); + case IX86_BUILTIN_RDPMC: case IX86_BUILTIN_RDTSC: case IX86_BUILTIN_RDTSCP: diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 416cdcd9129..86837525628 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -13458,15 +13458,12 @@ "! TARGET_POPCNT" { rtx scratch = gen_reg_rtx (QImode); - rtx cond; emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, NULL_RTX, operands[1])); - cond = gen_rtx_fmt_ee (ORDERED, QImode, - gen_rtx_REG (CCmode, FLAGS_REG), - const0_rtx); - emit_insn (gen_rtx_SET (scratch, cond)); + ix86_expand_setcc (scratch, ORDERED, + gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); if (TARGET_64BIT) emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); @@ -13486,14 +13483,11 @@ "! TARGET_POPCNT" { rtx scratch = gen_reg_rtx (QImode); - rtx cond; emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); - cond = gen_rtx_fmt_ee (ORDERED, QImode, - gen_rtx_REG (CCmode, FLAGS_REG), - const0_rtx); - emit_insn (gen_rtx_SET (scratch, cond)); + ix86_expand_setcc (scratch, ORDERED, + gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); DONE; @@ -16159,8 +16153,6 @@ rtx mask = GEN_INT (0x45); rtx val = GEN_INT (0x05); - rtx cond; - rtx scratch = gen_reg_rtx (HImode); rtx res = gen_reg_rtx (QImode); @@ -16168,10 +16160,8 @@ emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); emit_insn (gen_cmpqi_ext_3 (scratch, val)); - cond = gen_rtx_fmt_ee (EQ, QImode, - gen_rtx_REG (CCmode, FLAGS_REG), - const0_rtx); - emit_insn (gen_rtx_SET (res, cond)); + ix86_expand_setcc (res, EQ, + gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); emit_insn (gen_zero_extendqisi2 (operands[0], res)); DONE; }) @@ -16186,8 +16176,6 @@ rtx mask = GEN_INT (0x45); rtx val = GEN_INT (0x05); - rtx cond; - rtx scratch = gen_reg_rtx (HImode); rtx res = gen_reg_rtx (QImode); @@ -16204,10 +16192,8 @@ emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); emit_insn (gen_cmpqi_ext_3 (scratch, val)); - cond = gen_rtx_fmt_ee (EQ, QImode, - gen_rtx_REG (CCmode, FLAGS_REG), - const0_rtx); - emit_insn (gen_rtx_SET (res, cond)); + ix86_expand_setcc (res, EQ, + gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); emit_insn (gen_zero_extendqisi2 (operands[0], res)); DONE; }) diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 06acd30ec25..df7b1da42ff 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -13588,8 +13588,9 @@ mips_output_jump (rtx *operands, int target_opno, int size_opno, bool link_p) else s += sprintf (s, "%%*"); - s += sprintf (s, "%s%s%s%s%s\t%%%d%s", insn_name, and_link, reg, compact, short_delay, - target_opno, nop); + s += sprintf (s, "%s%s%s%s%s\t%%%d%s", + insn_name, and_link, reg, compact, short_delay, + target_opno, nop); if (!reg_p && TARGET_ABICALLS_PIC2) s += sprintf (s, "\n\t.option\tpic2"); diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h index 3ce74ab9144..9123d969be9 100644 --- a/gcc/config/rs6000/altivec.h +++ b/gcc/config/rs6000/altivec.h @@ -402,6 +402,11 @@ #define vec_vprtybq __builtin_vec_vprtybq #endif +#define vec_absd __builtin_vec_vadu +#define vec_absdb __builtin_vec_vadub +#define vec_absdh __builtin_vec_vaduh +#define vec_absdw __builtin_vec_vaduw + #define vec_slv __builtin_vec_vslv #define vec_srv __builtin_vec_vsrv #endif diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index d081bd1afbd..0cd67a4ec99 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -114,6 +114,7 @@ UNSPEC_STVLXL UNSPEC_STVRX UNSPEC_STVRXL + UNSPEC_VADU UNSPEC_VSLV UNSPEC_VSRV UNSPEC_VMULWHUB @@ -3464,6 +3465,24 @@ [(set_attr "length" "4") (set_attr "type" "vecsimple")]) +;; Vector absolute difference unsigned +(define_expand "vadu<mode>3" + [(set (match_operand:VI 0 "register_operand") + (unspec:VI [(match_operand:VI 1 "register_operand") + (match_operand:VI 2 "register_operand")] + UNSPEC_VADU))] + "TARGET_P9_VECTOR") + +;; Vector absolute difference unsigned +(define_insn "*p9_vadu<mode>3" + [(set (match_operand:VI 0 "register_operand" "=v") + (unspec:VI [(match_operand:VI 1 "register_operand" "v") + (match_operand:VI 2 "register_operand" "v")] + UNSPEC_VADU))] + "TARGET_P9_VECTOR" + "vabsdu<wd> %0,%1,%2" + [(set_attr "type" "vecsimple")]) + ;; Vector count trailing zeros (define_insn "*p9v_ctz<mode>2" [(set (match_operand:VI2 0 "register_operand" "=v") diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 606d7ae2840..80fe92a9d45 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -1757,6 +1757,17 @@ BU_P9V_AV_2 (VSRV, "vsrv", CONST, vsrv) BU_P9V_OVERLOAD_2 (VSLV, "vslv") BU_P9V_OVERLOAD_2 (VSRV, "vsrv") +/* 2 argument vector functions added in ISA 3.0 (power9). */ +BU_P9V_AV_2 (VADUB, "vadub", CONST, vaduv16qi3) +BU_P9V_AV_2 (VADUH, "vaduh", CONST, vaduv8hi3) +BU_P9V_AV_2 (VADUW, "vaduw", CONST, vaduv4si3) + +/* ISA 3.0 vector overloaded 2 argument functions. */ +BU_P9V_OVERLOAD_2 (VADU, "vadu") +BU_P9V_OVERLOAD_2 (VADUB, "vadub") +BU_P9V_OVERLOAD_2 (VADUH, "vaduh") +BU_P9V_OVERLOAD_2 (VADUW, "vaduw") + /* 2 argument extended divide functions added in ISA 2.06. */ BU_P7_MISC_2 (DIVWE, "divwe", CONST, dive_si) diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index d313e9b20fb..79a7e88a5ee 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -4240,6 +4240,28 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { { P9V_BUILTIN_VEC_VCTZD, P9V_BUILTIN_VCTZD, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + { P9V_BUILTIN_VEC_VADU, P9V_BUILTIN_VADUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P9V_BUILTIN_VEC_VADU, P9V_BUILTIN_VADUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P9V_BUILTIN_VEC_VADU, P9V_BUILTIN_VADUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + + { P9V_BUILTIN_VEC_VADUB, P9V_BUILTIN_VADUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + + { P9V_BUILTIN_VEC_VADUH, P9V_BUILTIN_VADUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + + { P9V_BUILTIN_VEC_VADUW, P9V_BUILTIN_VADUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD, diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 5f5510a6146..e1f01732074 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2694,6 +2694,7 @@ extern int frame_pointer_needed; | RS6000_BTM_VSX \ | RS6000_BTM_P8_VECTOR \ | RS6000_BTM_P9_VECTOR \ + | RS6000_BTM_MODULO \ | RS6000_BTM_CRYPTO \ | RS6000_BTM_FRE \ | RS6000_BTM_FRES \ diff --git a/gcc/config/s390/s390-builtin-types.def b/gcc/config/s390/s390-builtin-types.def index 6179b040e27..3d90d41dee3 100644 --- a/gcc/config/s390/s390-builtin-types.def +++ b/gcc/config/s390/s390-builtin-types.def @@ -19,29 +19,29 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ -#define DEF_FN_TYPE_1(FN_TYPE, FLAGS, T1) \ +#define DEF_FN_TYPE_0(FN_TYPE, FLAGS, T1) \ DEF_FN_TYPE (FN_TYPE, \ FLAGS, \ s390_builtin_types[T1]) -#define DEF_FN_TYPE_2(FN_TYPE, FLAGS, T1, T2) \ +#define DEF_FN_TYPE_1(FN_TYPE, FLAGS, T1, T2) \ DEF_FN_TYPE (FN_TYPE, \ FLAGS, \ s390_builtin_types[T1], \ s390_builtin_types[T2]) -#define DEF_FN_TYPE_3(FN_TYPE, FLAGS, T1, T2, T3) \ +#define DEF_FN_TYPE_2(FN_TYPE, FLAGS, T1, T2, T3) \ DEF_FN_TYPE (FN_TYPE, \ FLAGS, \ s390_builtin_types[T1], \ s390_builtin_types[T2], \ s390_builtin_types[T3]) -#define DEF_FN_TYPE_4(FN_TYPE, FLAGS, T1, T2, T3, T4) \ +#define DEF_FN_TYPE_3(FN_TYPE, FLAGS, T1, T2, T3, T4) \ DEF_FN_TYPE (FN_TYPE, \ FLAGS, \ s390_builtin_types[T1], \ s390_builtin_types[T2], \ s390_builtin_types[T3], \ s390_builtin_types[T4]) -#define DEF_FN_TYPE_5(FN_TYPE, FLAGS, T1, T2, T3, T4, T5) \ +#define DEF_FN_TYPE_4(FN_TYPE, FLAGS, T1, T2, T3, T4, T5) \ DEF_FN_TYPE (FN_TYPE, \ FLAGS, \ s390_builtin_types[T1], \ @@ -49,7 +49,7 @@ s390_builtin_types[T3], \ s390_builtin_types[T4], \ s390_builtin_types[T5]) -#define DEF_FN_TYPE_6(FN_TYPE, FLAGS, T1, T2, T3, T4, T5, T6) \ +#define DEF_FN_TYPE_5(FN_TYPE, FLAGS, T1, T2, T3, T4, T5, T6) \ DEF_FN_TYPE (FN_TYPE, \ FLAGS, \ s390_builtin_types[T1], \ @@ -126,210 +126,210 @@ DEF_OPAQUE_VECTOR_TYPE (BT_OUV4SI, B_VX, BT_UINT, 4) DEF_OPAQUE_VECTOR_TYPE (BT_BV4SI, B_VX, BT_BINT, 4) DEF_OPAQUE_VECTOR_TYPE (BT_BV2DI, B_VX, BT_BLONGLONG, 2) DEF_OPAQUE_VECTOR_TYPE (BT_BV8HI, B_VX, BT_BSHORT, 8) -DEF_FN_TYPE_1 (BT_FN_INT, B_HTM, BT_INT) -DEF_FN_TYPE_1 (BT_FN_UINT, 0, BT_UINT) -DEF_FN_TYPE_2 (BT_FN_INT_INT, B_VX, BT_INT, BT_INT) -DEF_FN_TYPE_2 (BT_FN_INT_VOIDPTR, B_HTM, BT_INT, BT_VOIDPTR) -DEF_FN_TYPE_2 (BT_FN_OV4SI_INT, B_VX, BT_OV4SI, BT_INT) -DEF_FN_TYPE_2 (BT_FN_OV4SI_INTCONSTPTR, B_VX, BT_OV4SI, BT_INTCONSTPTR) -DEF_FN_TYPE_2 (BT_FN_OV4SI_OV4SI, B_VX, BT_OV4SI, BT_OV4SI) -DEF_FN_TYPE_2 (BT_FN_UV16QI_UCHAR, B_VX, BT_UV16QI, BT_UCHAR) -DEF_FN_TYPE_2 (BT_FN_UV16QI_UCHARCONSTPTR, B_VX, BT_UV16QI, BT_UCHARCONSTPTR) -DEF_FN_TYPE_2 (BT_FN_UV16QI_USHORT, B_VX, BT_UV16QI, BT_USHORT) -DEF_FN_TYPE_2 (BT_FN_UV16QI_UV16QI, B_VX, BT_UV16QI, BT_UV16QI) -DEF_FN_TYPE_2 (BT_FN_UV2DI_ULONGLONG, B_VX, BT_UV2DI, BT_ULONGLONG) -DEF_FN_TYPE_2 (BT_FN_UV2DI_ULONGLONGCONSTPTR, B_VX, BT_UV2DI, BT_ULONGLONGCONSTPTR) -DEF_FN_TYPE_2 (BT_FN_UV2DI_USHORT, B_VX, BT_UV2DI, BT_USHORT) -DEF_FN_TYPE_2 (BT_FN_UV2DI_UV2DI, B_VX, BT_UV2DI, BT_UV2DI) -DEF_FN_TYPE_2 (BT_FN_UV2DI_UV4SI, B_VX, BT_UV2DI, BT_UV4SI) -DEF_FN_TYPE_2 (BT_FN_UV4SI_UINT, B_VX, BT_UV4SI, BT_UINT) -DEF_FN_TYPE_2 (BT_FN_UV4SI_UINTCONSTPTR, B_VX, BT_UV4SI, BT_UINTCONSTPTR) -DEF_FN_TYPE_2 (BT_FN_UV4SI_USHORT, B_VX, BT_UV4SI, BT_USHORT) -DEF_FN_TYPE_2 (BT_FN_UV4SI_UV4SI, B_VX, BT_UV4SI, BT_UV4SI) -DEF_FN_TYPE_2 (BT_FN_UV4SI_UV8HI, B_VX, BT_UV4SI, BT_UV8HI) -DEF_FN_TYPE_2 (BT_FN_UV8HI_USHORT, B_VX, BT_UV8HI, BT_USHORT) -DEF_FN_TYPE_2 (BT_FN_UV8HI_USHORTCONSTPTR, B_VX, BT_UV8HI, BT_USHORTCONSTPTR) -DEF_FN_TYPE_2 (BT_FN_UV8HI_UV16QI, B_VX, BT_UV8HI, BT_UV16QI) -DEF_FN_TYPE_2 (BT_FN_UV8HI_UV8HI, B_VX, BT_UV8HI, BT_UV8HI) -DEF_FN_TYPE_2 (BT_FN_V16QI_SCHAR, B_VX, BT_V16QI, BT_SCHAR) -DEF_FN_TYPE_2 (BT_FN_V16QI_UCHAR, B_VX, BT_V16QI, BT_UCHAR) -DEF_FN_TYPE_2 (BT_FN_V16QI_V16QI, B_VX, BT_V16QI, BT_V16QI) -DEF_FN_TYPE_2 (BT_FN_V2DF_DBL, B_VX, BT_V2DF, BT_DBL) -DEF_FN_TYPE_2 (BT_FN_V2DF_FLTCONSTPTR, B_VX, BT_V2DF, BT_FLTCONSTPTR) -DEF_FN_TYPE_2 (BT_FN_V2DF_V2DF, B_VX, BT_V2DF, BT_V2DF) -DEF_FN_TYPE_2 (BT_FN_V2DI_SHORT, B_VX, BT_V2DI, BT_SHORT) -DEF_FN_TYPE_2 (BT_FN_V2DI_V16QI, B_VX, BT_V2DI, BT_V16QI) -DEF_FN_TYPE_2 (BT_FN_V2DI_V2DI, B_VX, BT_V2DI, BT_V2DI) -DEF_FN_TYPE_2 (BT_FN_V2DI_V4SI, B_VX, BT_V2DI, BT_V4SI) -DEF_FN_TYPE_2 (BT_FN_V2DI_V8HI, B_VX, BT_V2DI, BT_V8HI) -DEF_FN_TYPE_2 (BT_FN_V4SI_SHORT, B_VX, BT_V4SI, BT_SHORT) -DEF_FN_TYPE_2 (BT_FN_V4SI_V4SI, B_VX, BT_V4SI, BT_V4SI) -DEF_FN_TYPE_2 (BT_FN_V4SI_V8HI, B_VX, BT_V4SI, BT_V8HI) -DEF_FN_TYPE_2 (BT_FN_V8HI_SHORT, B_VX, BT_V8HI, BT_SHORT) -DEF_FN_TYPE_2 (BT_FN_V8HI_V16QI, B_VX, BT_V8HI, BT_V16QI) -DEF_FN_TYPE_2 (BT_FN_V8HI_V8HI, B_VX, BT_V8HI, BT_V8HI) -DEF_FN_TYPE_2 (BT_FN_VOID_INT, B_HTM, BT_VOID, BT_INT) -DEF_FN_TYPE_2 (BT_FN_VOID_UINT, 0, BT_VOID, BT_UINT) -DEF_FN_TYPE_3 (BT_FN_DBL_V2DF_INT, B_VX, BT_DBL, BT_V2DF, BT_INT) -DEF_FN_TYPE_3 (BT_FN_INT_OV4SI_INT, B_VX, BT_INT, BT_OV4SI, BT_INT) -DEF_FN_TYPE_3 (BT_FN_INT_OV4SI_OV4SI, B_VX, BT_INT, BT_OV4SI, BT_OV4SI) -DEF_FN_TYPE_3 (BT_FN_INT_UV16QI_UV16QI, B_VX, BT_INT, BT_UV16QI, BT_UV16QI) -DEF_FN_TYPE_3 (BT_FN_INT_UV2DI_UV2DI, B_VX, BT_INT, BT_UV2DI, BT_UV2DI) -DEF_FN_TYPE_3 (BT_FN_INT_UV4SI_UV4SI, B_VX, BT_INT, BT_UV4SI, BT_UV4SI) -DEF_FN_TYPE_3 (BT_FN_INT_UV8HI_UV8HI, B_VX, BT_INT, BT_UV8HI, BT_UV8HI) -DEF_FN_TYPE_3 (BT_FN_INT_V16QI_V16QI, B_VX, BT_INT, BT_V16QI, BT_V16QI) -DEF_FN_TYPE_3 (BT_FN_INT_V2DF_V2DF, B_VX, BT_INT, BT_V2DF, BT_V2DF) -DEF_FN_TYPE_3 (BT_FN_INT_V2DI_V2DI, B_VX, BT_INT, BT_V2DI, BT_V2DI) -DEF_FN_TYPE_3 (BT_FN_INT_V4SI_V4SI, B_VX, BT_INT, BT_V4SI, BT_V4SI) -DEF_FN_TYPE_3 (BT_FN_INT_V8HI_V8HI, B_VX, BT_INT, BT_V8HI, BT_V8HI) -DEF_FN_TYPE_3 (BT_FN_INT_VOIDPTR_INT, B_HTM, BT_INT, BT_VOIDPTR, BT_INT) -DEF_FN_TYPE_3 (BT_FN_OV2DI_LONGLONG_LONGLONG, B_VX, BT_OV2DI, BT_LONGLONG, BT_LONGLONG) -DEF_FN_TYPE_3 (BT_FN_OV4SI_INTCONSTPTR_INT, B_VX, BT_OV4SI, BT_INTCONSTPTR, BT_INT) -DEF_FN_TYPE_3 (BT_FN_OV4SI_INTCONSTPTR_UINT, B_VX, BT_OV4SI, BT_INTCONSTPTR, BT_UINT) -DEF_FN_TYPE_3 (BT_FN_OV4SI_INT_INT, B_VX, BT_OV4SI, BT_INT, BT_INT) -DEF_FN_TYPE_3 (BT_FN_OV4SI_OV4SI_INTPTR, B_VX, BT_OV4SI, BT_OV4SI, BT_INTPTR) -DEF_FN_TYPE_3 (BT_FN_OV4SI_OV4SI_OV4SI, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI) -DEF_FN_TYPE_3 (BT_FN_OV4SI_OV4SI_UCHAR, B_VX, BT_OV4SI, BT_OV4SI, BT_UCHAR) -DEF_FN_TYPE_3 (BT_FN_OV4SI_OV4SI_ULONG, B_VX, BT_OV4SI, BT_OV4SI, BT_ULONG) -DEF_FN_TYPE_3 (BT_FN_UCHAR_UV16QI_INT, B_VX, BT_UCHAR, BT_UV16QI, BT_INT) -DEF_FN_TYPE_3 (BT_FN_UINT_UV4SI_INT, B_VX, BT_UINT, BT_UV4SI, BT_INT) -DEF_FN_TYPE_3 (BT_FN_UINT_VOIDCONSTPTR_INT, B_VX, BT_UINT, BT_VOIDCONSTPTR, BT_INT) -DEF_FN_TYPE_3 (BT_FN_ULONGLONG_UV2DI_INT, B_VX, BT_ULONGLONG, BT_UV2DI, BT_INT) -DEF_FN_TYPE_3 (BT_FN_USHORT_UV8HI_INT, B_VX, BT_USHORT, BT_UV8HI, BT_INT) -DEF_FN_TYPE_3 (BT_FN_UV16QI_UCHARCONSTPTR_USHORT, B_VX, BT_UV16QI, BT_UCHARCONSTPTR, BT_USHORT) -DEF_FN_TYPE_3 (BT_FN_UV16QI_UCHAR_INT, B_VX, BT_UV16QI, BT_UCHAR, BT_INT) -DEF_FN_TYPE_3 (BT_FN_UV16QI_UCHAR_UCHAR, B_VX, BT_UV16QI, BT_UCHAR, BT_UCHAR) -DEF_FN_TYPE_3 (BT_FN_UV16QI_UV16QI_INTPTR, B_VX, BT_UV16QI, BT_UV16QI, BT_INTPTR) -DEF_FN_TYPE_3 (BT_FN_UV16QI_UV16QI_UCHAR, B_VX, BT_UV16QI, BT_UV16QI, BT_UCHAR) -DEF_FN_TYPE_3 (BT_FN_UV16QI_UV16QI_UINT, B_VX, BT_UV16QI, BT_UV16QI, BT_UINT) -DEF_FN_TYPE_3 (BT_FN_UV16QI_UV16QI_UV16QI, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI) -DEF_FN_TYPE_3 (BT_FN_UV16QI_UV2DI_UV2DI, B_VX, BT_UV16QI, BT_UV2DI, BT_UV2DI) -DEF_FN_TYPE_3 (BT_FN_UV16QI_UV4SI_UV4SI, B_VX, BT_UV16QI, BT_UV4SI, BT_UV4SI) -DEF_FN_TYPE_3 (BT_FN_UV16QI_UV8HI_UV8HI, B_VX, BT_UV16QI, BT_UV8HI, BT_UV8HI) -DEF_FN_TYPE_3 (BT_FN_UV2DI_UCHAR_UCHAR, B_VX, BT_UV2DI, BT_UCHAR, BT_UCHAR) -DEF_FN_TYPE_3 (BT_FN_UV2DI_ULONGLONG_INT, B_VX, BT_UV2DI, BT_ULONGLONG, BT_INT) -DEF_FN_TYPE_3 (BT_FN_UV2DI_UV2DI_UCHAR, B_VX, BT_UV2DI, BT_UV2DI, BT_UCHAR) -DEF_FN_TYPE_3 (BT_FN_UV2DI_UV2DI_UINT, B_VX, BT_UV2DI, BT_UV2DI, BT_UINT) -DEF_FN_TYPE_3 (BT_FN_UV2DI_UV2DI_UV2DI, B_VX, BT_UV2DI, BT_UV2DI, BT_UV2DI) -DEF_FN_TYPE_3 (BT_FN_UV2DI_UV4SI_UV4SI, B_VX, BT_UV2DI, BT_UV4SI, BT_UV4SI) -DEF_FN_TYPE_3 (BT_FN_UV2DI_UV8HI_UV8HI, B_VX, BT_UV2DI, BT_UV8HI, BT_UV8HI) -DEF_FN_TYPE_3 (BT_FN_UV2DI_V2DF_INT, B_VX, BT_UV2DI, BT_V2DF, BT_INT) -DEF_FN_TYPE_3 (BT_FN_UV4SI_UCHAR_UCHAR, B_VX, BT_UV4SI, BT_UCHAR, BT_UCHAR) -DEF_FN_TYPE_3 (BT_FN_UV4SI_UINT_INT, B_VX, BT_UV4SI, BT_UINT, BT_INT) -DEF_FN_TYPE_3 (BT_FN_UV4SI_UV16QI_UV16QI, B_VX, BT_UV4SI, BT_UV16QI, BT_UV16QI) -DEF_FN_TYPE_3 (BT_FN_UV4SI_UV2DI_UV2DI, B_VX, BT_UV4SI, BT_UV2DI, BT_UV2DI) -DEF_FN_TYPE_3 (BT_FN_UV4SI_UV4SI_INTPTR, B_VX, BT_UV4SI, BT_UV4SI, BT_INTPTR) -DEF_FN_TYPE_3 (BT_FN_UV4SI_UV4SI_UCHAR, B_VX, BT_UV4SI, BT_UV4SI, BT_UCHAR) -DEF_FN_TYPE_3 (BT_FN_UV4SI_UV4SI_UINT, B_VX, BT_UV4SI, BT_UV4SI, BT_UINT) -DEF_FN_TYPE_3 (BT_FN_UV4SI_UV4SI_UV4SI, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI) -DEF_FN_TYPE_3 (BT_FN_UV4SI_UV8HI_UV8HI, B_VX, BT_UV4SI, BT_UV8HI, BT_UV8HI) -DEF_FN_TYPE_3 (BT_FN_UV8HI_UCHAR_UCHAR, B_VX, BT_UV8HI, BT_UCHAR, BT_UCHAR) -DEF_FN_TYPE_3 (BT_FN_UV8HI_USHORT_INT, B_VX, BT_UV8HI, BT_USHORT, BT_INT) -DEF_FN_TYPE_3 (BT_FN_UV8HI_UV16QI_UV16QI, B_VX, BT_UV8HI, BT_UV16QI, BT_UV16QI) -DEF_FN_TYPE_3 (BT_FN_UV8HI_UV4SI_UV4SI, B_VX, BT_UV8HI, BT_UV4SI, BT_UV4SI) -DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_INTPTR, B_VX, BT_UV8HI, BT_UV8HI, BT_INTPTR) -DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_UCHAR, B_VX, BT_UV8HI, BT_UV8HI, BT_UCHAR) -DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_UINT, B_VX, BT_UV8HI, BT_UV8HI, BT_UINT) -DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_UV8HI, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI) -DEF_FN_TYPE_3 (BT_FN_V16QI_BV16QI_V16QI, B_VX, BT_V16QI, BT_BV16QI, BT_V16QI) -DEF_FN_TYPE_3 (BT_FN_V16QI_UINT_VOIDCONSTPTR, B_VX, BT_V16QI, BT_UINT, BT_VOIDCONSTPTR) -DEF_FN_TYPE_3 (BT_FN_V16QI_UV16QI_UV16QI, B_VX, BT_V16QI, BT_UV16QI, BT_UV16QI) -DEF_FN_TYPE_3 (BT_FN_V16QI_V16QI_V16QI, B_VX, BT_V16QI, BT_V16QI, BT_V16QI) -DEF_FN_TYPE_3 (BT_FN_V16QI_V8HI_V8HI, B_VX, BT_V16QI, BT_V8HI, BT_V8HI) -DEF_FN_TYPE_3 (BT_FN_V2DF_DBL_INT, B_VX, BT_V2DF, BT_DBL, BT_INT) -DEF_FN_TYPE_3 (BT_FN_V2DF_UV2DI_INT, B_VX, BT_V2DF, BT_UV2DI, BT_INT) -DEF_FN_TYPE_3 (BT_FN_V2DF_UV4SI_INT, B_VX, BT_V2DF, BT_UV4SI, BT_INT) -DEF_FN_TYPE_3 (BT_FN_V2DF_V2DF_V2DF, B_VX, BT_V2DF, BT_V2DF, BT_V2DF) -DEF_FN_TYPE_3 (BT_FN_V2DF_V2DI_INT, B_VX, BT_V2DF, BT_V2DI, BT_INT) -DEF_FN_TYPE_3 (BT_FN_V2DI_BV2DI_V2DI, B_VX, BT_V2DI, BT_BV2DI, BT_V2DI) -DEF_FN_TYPE_3 (BT_FN_V2DI_UV2DI_UV2DI, B_VX, BT_V2DI, BT_UV2DI, BT_UV2DI) -DEF_FN_TYPE_3 (BT_FN_V2DI_V2DF_INT, B_VX, BT_V2DI, BT_V2DF, BT_INT) -DEF_FN_TYPE_3 (BT_FN_V2DI_V2DF_V2DF, B_VX, BT_V2DI, BT_V2DF, BT_V2DF) -DEF_FN_TYPE_3 (BT_FN_V2DI_V2DI_V2DI, B_VX, BT_V2DI, BT_V2DI, BT_V2DI) -DEF_FN_TYPE_3 (BT_FN_V2DI_V4SI_V4SI, B_VX, BT_V2DI, BT_V4SI, BT_V4SI) -DEF_FN_TYPE_3 (BT_FN_V4SI_BV4SI_V4SI, B_VX, BT_V4SI, BT_BV4SI, BT_V4SI) -DEF_FN_TYPE_3 (BT_FN_V4SI_INT_VOIDPTR, B_VX, BT_V4SI, BT_INT, BT_VOIDPTR) -DEF_FN_TYPE_3 (BT_FN_V4SI_UV4SI_UV4SI, B_VX, BT_V4SI, BT_UV4SI, BT_UV4SI) -DEF_FN_TYPE_3 (BT_FN_V4SI_V2DI_V2DI, B_VX, BT_V4SI, BT_V2DI, BT_V2DI) -DEF_FN_TYPE_3 (BT_FN_V4SI_V4SI_V4SI, B_VX, BT_V4SI, BT_V4SI, BT_V4SI) -DEF_FN_TYPE_3 (BT_FN_V4SI_V8HI_V8HI, B_VX, BT_V4SI, BT_V8HI, BT_V8HI) -DEF_FN_TYPE_3 (BT_FN_V8HI_BV8HI_V8HI, B_VX, BT_V8HI, BT_BV8HI, BT_V8HI) -DEF_FN_TYPE_3 (BT_FN_V8HI_UV8HI_UV8HI, B_VX, BT_V8HI, BT_UV8HI, BT_UV8HI) -DEF_FN_TYPE_3 (BT_FN_V8HI_V16QI_V16QI, B_VX, BT_V8HI, BT_V16QI, BT_V16QI) -DEF_FN_TYPE_3 (BT_FN_V8HI_V4SI_V4SI, B_VX, BT_V8HI, BT_V4SI, BT_V4SI) -DEF_FN_TYPE_3 (BT_FN_V8HI_V8HI_V8HI, B_VX, BT_V8HI, BT_V8HI, BT_V8HI) -DEF_FN_TYPE_3 (BT_FN_VOID_UINT64PTR_UINT64, B_HTM, BT_VOID, BT_UINT64PTR, BT_UINT64) -DEF_FN_TYPE_3 (BT_FN_VOID_V2DF_FLTPTR, B_VX, BT_VOID, BT_V2DF, BT_FLTPTR) -DEF_FN_TYPE_4 (BT_FN_INT_OV4SI_OV4SI_INTPTR, B_VX, BT_INT, BT_OV4SI, BT_OV4SI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_OV4SI_INT_OV4SI_INT, B_VX, BT_OV4SI, BT_INT, BT_OV4SI, BT_INT) -DEF_FN_TYPE_4 (BT_FN_OV4SI_OV4SI_OV4SI_INT, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_INT) -DEF_FN_TYPE_4 (BT_FN_OV4SI_OV4SI_OV4SI_INTPTR, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_OV4SI_OV4SI_OV4SI_OV4SI, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_OV4SI) -DEF_FN_TYPE_4 (BT_FN_OV4SI_OV4SI_OV4SI_UCHAR, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_UCHAR) -DEF_FN_TYPE_4 (BT_FN_OV4SI_OV4SI_OV4SI_ULONGLONG, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_ULONGLONG) -DEF_FN_TYPE_4 (BT_FN_UV16QI_UV16QI_UCHAR_INT, B_VX, BT_UV16QI, BT_UV16QI, BT_UCHAR, BT_INT) -DEF_FN_TYPE_4 (BT_FN_UV16QI_UV16QI_UV16QI_INT, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_INT) -DEF_FN_TYPE_4 (BT_FN_UV16QI_UV16QI_UV16QI_INTPTR, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_UV16QI_UV16QI_UV16QI_UV16QI, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_UV16QI) -DEF_FN_TYPE_4 (BT_FN_UV16QI_UV2DI_UV2DI_UV16QI, B_VX, BT_UV16QI, BT_UV2DI, BT_UV2DI, BT_UV16QI) -DEF_FN_TYPE_4 (BT_FN_UV16QI_UV8HI_UV8HI_INTPTR, B_VX, BT_UV16QI, BT_UV8HI, BT_UV8HI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_UV2DI_UV2DI_ULONGLONG_INT, B_VX, BT_UV2DI, BT_UV2DI, BT_ULONGLONG, BT_INT) -DEF_FN_TYPE_4 (BT_FN_UV2DI_UV2DI_UV2DI_INT, B_VX, BT_UV2DI, BT_UV2DI, BT_UV2DI, BT_INT) -DEF_FN_TYPE_4 (BT_FN_UV2DI_UV4SI_UV4SI_UV2DI, B_VX, BT_UV2DI, BT_UV4SI, BT_UV4SI, BT_UV2DI) -DEF_FN_TYPE_4 (BT_FN_UV4SI_UV2DI_UV2DI_INTPTR, B_VX, BT_UV4SI, BT_UV2DI, BT_UV2DI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_UV4SI_UV4SI_UINT_INT, B_VX, BT_UV4SI, BT_UV4SI, BT_UINT, BT_INT) -DEF_FN_TYPE_4 (BT_FN_UV4SI_UV4SI_UV4SI_INT, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_INT) -DEF_FN_TYPE_4 (BT_FN_UV4SI_UV4SI_UV4SI_INTPTR, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_UV4SI_UV4SI_UV4SI_UV4SI, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_UV4SI) -DEF_FN_TYPE_4 (BT_FN_UV4SI_UV8HI_UV8HI_UV4SI, B_VX, BT_UV4SI, BT_UV8HI, BT_UV8HI, BT_UV4SI) -DEF_FN_TYPE_4 (BT_FN_UV8HI_UV16QI_UV16QI_UV8HI, B_VX, BT_UV8HI, BT_UV16QI, BT_UV16QI, BT_UV8HI) -DEF_FN_TYPE_4 (BT_FN_UV8HI_UV4SI_UV4SI_INTPTR, B_VX, BT_UV8HI, BT_UV4SI, BT_UV4SI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_UV8HI_UV8HI_USHORT_INT, B_VX, BT_UV8HI, BT_UV8HI, BT_USHORT, BT_INT) -DEF_FN_TYPE_4 (BT_FN_UV8HI_UV8HI_UV8HI_INT, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INT) -DEF_FN_TYPE_4 (BT_FN_UV8HI_UV8HI_UV8HI_INTPTR, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_UV8HI_UV8HI_UV8HI_UV8HI, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_UV8HI) -DEF_FN_TYPE_4 (BT_FN_V16QI_UV16QI_UV16QI_INTPTR, B_VX, BT_V16QI, BT_UV16QI, BT_UV16QI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V16QI_V16QI_V16QI_INTPTR, B_VX, BT_V16QI, BT_V16QI, BT_V16QI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V16QI_V16QI_V16QI_V16QI, B_VX, BT_V16QI, BT_V16QI, BT_V16QI, BT_V16QI) -DEF_FN_TYPE_4 (BT_FN_V16QI_V8HI_V8HI_INTPTR, B_VX, BT_V16QI, BT_V8HI, BT_V8HI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V2DF_V2DF_DBL_INT, B_VX, BT_V2DF, BT_V2DF, BT_DBL, BT_INT) -DEF_FN_TYPE_4 (BT_FN_V2DF_V2DF_UCHAR_UCHAR, B_VX, BT_V2DF, BT_V2DF, BT_UCHAR, BT_UCHAR) -DEF_FN_TYPE_4 (BT_FN_V2DF_V2DF_V2DF_V2DF, B_VX, BT_V2DF, BT_V2DF, BT_V2DF, BT_V2DF) -DEF_FN_TYPE_4 (BT_FN_V2DI_UV2DI_UV2DI_INTPTR, B_VX, BT_V2DI, BT_UV2DI, BT_UV2DI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V2DI_V2DF_INT_INTPTR, B_VX, BT_V2DI, BT_V2DF, BT_INT, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V2DI_V2DF_V2DF_INTPTR, B_VX, BT_V2DI, BT_V2DF, BT_V2DF, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V2DI_V2DI_V2DI_INTPTR, B_VX, BT_V2DI, BT_V2DI, BT_V2DI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V2DI_V4SI_V4SI_V2DI, B_VX, BT_V2DI, BT_V4SI, BT_V4SI, BT_V2DI) -DEF_FN_TYPE_4 (BT_FN_V4SI_UV4SI_UV4SI_INTPTR, B_VX, BT_V4SI, BT_UV4SI, BT_UV4SI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V4SI_V2DI_V2DI_INTPTR, B_VX, BT_V4SI, BT_V2DI, BT_V2DI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V4SI_V4SI_V4SI_INTPTR, B_VX, BT_V4SI, BT_V4SI, BT_V4SI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V4SI_V4SI_V4SI_V4SI, B_VX, BT_V4SI, BT_V4SI, BT_V4SI, BT_V4SI) -DEF_FN_TYPE_4 (BT_FN_V4SI_V8HI_V8HI_V4SI, B_VX, BT_V4SI, BT_V8HI, BT_V8HI, BT_V4SI) -DEF_FN_TYPE_4 (BT_FN_V8HI_UV8HI_UV8HI_INTPTR, B_VX, BT_V8HI, BT_UV8HI, BT_UV8HI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V8HI_V16QI_V16QI_V8HI, B_VX, BT_V8HI, BT_V16QI, BT_V16QI, BT_V8HI) -DEF_FN_TYPE_4 (BT_FN_V8HI_V4SI_V4SI_INTPTR, B_VX, BT_V8HI, BT_V4SI, BT_V4SI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V8HI_V8HI_V8HI_INTPTR, B_VX, BT_V8HI, BT_V8HI, BT_V8HI, BT_INTPTR) -DEF_FN_TYPE_4 (BT_FN_V8HI_V8HI_V8HI_V8HI, B_VX, BT_V8HI, BT_V8HI, BT_V8HI, BT_V8HI) -DEF_FN_TYPE_4 (BT_FN_VOID_OV4SI_INT_VOIDPTR, B_VX, BT_VOID, BT_OV4SI, BT_INT, BT_VOIDPTR) -DEF_FN_TYPE_4 (BT_FN_VOID_OV4SI_VOIDPTR_UINT, B_VX, BT_VOID, BT_OV4SI, BT_VOIDPTR, BT_UINT) -DEF_FN_TYPE_4 (BT_FN_VOID_V16QI_UINT_VOIDPTR, B_VX, BT_VOID, BT_V16QI, BT_UINT, BT_VOIDPTR) -DEF_FN_TYPE_5 (BT_FN_OV4SI_OV4SI_OUV4SI_INTCONSTPTR_UCHAR, B_VX, BT_OV4SI, BT_OV4SI, BT_OUV4SI, BT_INTCONSTPTR, BT_UCHAR) -DEF_FN_TYPE_5 (BT_FN_OV4SI_OV4SI_OV4SI_OV4SI_INTPTR, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_INTPTR) -DEF_FN_TYPE_5 (BT_FN_UV16QI_UV16QI_UV16QI_INT_INTPTR, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_INT, BT_INTPTR) -DEF_FN_TYPE_5 (BT_FN_UV16QI_UV16QI_UV16QI_UV16QI_INT, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_INT) -DEF_FN_TYPE_5 (BT_FN_UV2DI_UV2DI_UV2DI_ULONGLONGCONSTPTR_UCHAR, B_VX, BT_UV2DI, BT_UV2DI, BT_UV2DI, BT_ULONGLONGCONSTPTR, BT_UCHAR) -DEF_FN_TYPE_5 (BT_FN_UV2DI_UV2DI_UV2DI_UV2DI_INT, B_VX, BT_UV2DI, BT_UV2DI, BT_UV2DI, BT_UV2DI, BT_INT) -DEF_FN_TYPE_5 (BT_FN_UV4SI_UV4SI_UV4SI_INT_INTPTR, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_INT, BT_INTPTR) -DEF_FN_TYPE_5 (BT_FN_UV4SI_UV4SI_UV4SI_UINTCONSTPTR_UCHAR, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_UINTCONSTPTR, BT_UCHAR) -DEF_FN_TYPE_5 (BT_FN_UV4SI_UV4SI_UV4SI_UV4SI_INT, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_INT) -DEF_FN_TYPE_5 (BT_FN_UV8HI_UV8HI_UV8HI_INT_INTPTR, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INT, BT_INTPTR) -DEF_FN_TYPE_5 (BT_FN_UV8HI_UV8HI_UV8HI_UV8HI_INT, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INT) -DEF_FN_TYPE_5 (BT_FN_VOID_UV2DI_UV2DI_ULONGLONGPTR_ULONGLONG, B_VX, BT_VOID, BT_UV2DI, BT_UV2DI, BT_ULONGLONGPTR, BT_ULONGLONG) -DEF_FN_TYPE_5 (BT_FN_VOID_UV4SI_UV4SI_UINTPTR_ULONGLONG, B_VX, BT_VOID, BT_UV4SI, BT_UV4SI, BT_UINTPTR, BT_ULONGLONG) -DEF_FN_TYPE_5 (BT_FN_VOID_V4SI_V4SI_INTPTR_ULONGLONG, B_VX, BT_VOID, BT_V4SI, BT_V4SI, BT_INTPTR, BT_ULONGLONG) -DEF_FN_TYPE_6 (BT_FN_UV16QI_UV16QI_UV16QI_UV16QI_INT_INTPTR, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_INT, BT_INTPTR) -DEF_FN_TYPE_6 (BT_FN_UV4SI_UV4SI_UV4SI_UV4SI_INT_INTPTR, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_INT, BT_INTPTR) -DEF_FN_TYPE_6 (BT_FN_UV8HI_UV8HI_UV8HI_UV8HI_INT_INTPTR, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INT, BT_INTPTR) +DEF_FN_TYPE_0 (BT_FN_INT, B_HTM, BT_INT) +DEF_FN_TYPE_0 (BT_FN_UINT, 0, BT_UINT) +DEF_FN_TYPE_1 (BT_FN_INT_INT, B_VX, BT_INT, BT_INT) +DEF_FN_TYPE_1 (BT_FN_INT_VOIDPTR, B_HTM, BT_INT, BT_VOIDPTR) +DEF_FN_TYPE_1 (BT_FN_OV4SI_INT, B_VX, BT_OV4SI, BT_INT) +DEF_FN_TYPE_1 (BT_FN_OV4SI_INTCONSTPTR, B_VX, BT_OV4SI, BT_INTCONSTPTR) +DEF_FN_TYPE_1 (BT_FN_OV4SI_OV4SI, B_VX, BT_OV4SI, BT_OV4SI) +DEF_FN_TYPE_1 (BT_FN_UV16QI_UCHAR, B_VX, BT_UV16QI, BT_UCHAR) +DEF_FN_TYPE_1 (BT_FN_UV16QI_UCHARCONSTPTR, B_VX, BT_UV16QI, BT_UCHARCONSTPTR) +DEF_FN_TYPE_1 (BT_FN_UV16QI_USHORT, B_VX, BT_UV16QI, BT_USHORT) +DEF_FN_TYPE_1 (BT_FN_UV16QI_UV16QI, B_VX, BT_UV16QI, BT_UV16QI) +DEF_FN_TYPE_1 (BT_FN_UV2DI_ULONGLONG, B_VX, BT_UV2DI, BT_ULONGLONG) +DEF_FN_TYPE_1 (BT_FN_UV2DI_ULONGLONGCONSTPTR, B_VX, BT_UV2DI, BT_ULONGLONGCONSTPTR) +DEF_FN_TYPE_1 (BT_FN_UV2DI_USHORT, B_VX, BT_UV2DI, BT_USHORT) +DEF_FN_TYPE_1 (BT_FN_UV2DI_UV2DI, B_VX, BT_UV2DI, BT_UV2DI) +DEF_FN_TYPE_1 (BT_FN_UV2DI_UV4SI, B_VX, BT_UV2DI, BT_UV4SI) +DEF_FN_TYPE_1 (BT_FN_UV4SI_UINT, B_VX, BT_UV4SI, BT_UINT) +DEF_FN_TYPE_1 (BT_FN_UV4SI_UINTCONSTPTR, B_VX, BT_UV4SI, BT_UINTCONSTPTR) +DEF_FN_TYPE_1 (BT_FN_UV4SI_USHORT, B_VX, BT_UV4SI, BT_USHORT) +DEF_FN_TYPE_1 (BT_FN_UV4SI_UV4SI, B_VX, BT_UV4SI, BT_UV4SI) +DEF_FN_TYPE_1 (BT_FN_UV4SI_UV8HI, B_VX, BT_UV4SI, BT_UV8HI) +DEF_FN_TYPE_1 (BT_FN_UV8HI_USHORT, B_VX, BT_UV8HI, BT_USHORT) +DEF_FN_TYPE_1 (BT_FN_UV8HI_USHORTCONSTPTR, B_VX, BT_UV8HI, BT_USHORTCONSTPTR) +DEF_FN_TYPE_1 (BT_FN_UV8HI_UV16QI, B_VX, BT_UV8HI, BT_UV16QI) +DEF_FN_TYPE_1 (BT_FN_UV8HI_UV8HI, B_VX, BT_UV8HI, BT_UV8HI) +DEF_FN_TYPE_1 (BT_FN_V16QI_SCHAR, B_VX, BT_V16QI, BT_SCHAR) +DEF_FN_TYPE_1 (BT_FN_V16QI_UCHAR, B_VX, BT_V16QI, BT_UCHAR) +DEF_FN_TYPE_1 (BT_FN_V16QI_V16QI, B_VX, BT_V16QI, BT_V16QI) +DEF_FN_TYPE_1 (BT_FN_V2DF_DBL, B_VX, BT_V2DF, BT_DBL) +DEF_FN_TYPE_1 (BT_FN_V2DF_FLTCONSTPTR, B_VX, BT_V2DF, BT_FLTCONSTPTR) +DEF_FN_TYPE_1 (BT_FN_V2DF_V2DF, B_VX, BT_V2DF, BT_V2DF) +DEF_FN_TYPE_1 (BT_FN_V2DI_SHORT, B_VX, BT_V2DI, BT_SHORT) +DEF_FN_TYPE_1 (BT_FN_V2DI_V16QI, B_VX, BT_V2DI, BT_V16QI) +DEF_FN_TYPE_1 (BT_FN_V2DI_V2DI, B_VX, BT_V2DI, BT_V2DI) +DEF_FN_TYPE_1 (BT_FN_V2DI_V4SI, B_VX, BT_V2DI, BT_V4SI) +DEF_FN_TYPE_1 (BT_FN_V2DI_V8HI, B_VX, BT_V2DI, BT_V8HI) +DEF_FN_TYPE_1 (BT_FN_V4SI_SHORT, B_VX, BT_V4SI, BT_SHORT) +DEF_FN_TYPE_1 (BT_FN_V4SI_V4SI, B_VX, BT_V4SI, BT_V4SI) +DEF_FN_TYPE_1 (BT_FN_V4SI_V8HI, B_VX, BT_V4SI, BT_V8HI) +DEF_FN_TYPE_1 (BT_FN_V8HI_SHORT, B_VX, BT_V8HI, BT_SHORT) +DEF_FN_TYPE_1 (BT_FN_V8HI_V16QI, B_VX, BT_V8HI, BT_V16QI) +DEF_FN_TYPE_1 (BT_FN_V8HI_V8HI, B_VX, BT_V8HI, BT_V8HI) +DEF_FN_TYPE_1 (BT_FN_VOID_INT, B_HTM, BT_VOID, BT_INT) +DEF_FN_TYPE_1 (BT_FN_VOID_UINT, 0, BT_VOID, BT_UINT) +DEF_FN_TYPE_2 (BT_FN_DBL_V2DF_INT, B_VX, BT_DBL, BT_V2DF, BT_INT) +DEF_FN_TYPE_2 (BT_FN_INT_OV4SI_INT, B_VX, BT_INT, BT_OV4SI, BT_INT) +DEF_FN_TYPE_2 (BT_FN_INT_OV4SI_OV4SI, B_VX, BT_INT, BT_OV4SI, BT_OV4SI) +DEF_FN_TYPE_2 (BT_FN_INT_UV16QI_UV16QI, B_VX, BT_INT, BT_UV16QI, BT_UV16QI) +DEF_FN_TYPE_2 (BT_FN_INT_UV2DI_UV2DI, B_VX, BT_INT, BT_UV2DI, BT_UV2DI) +DEF_FN_TYPE_2 (BT_FN_INT_UV4SI_UV4SI, B_VX, BT_INT, BT_UV4SI, BT_UV4SI) +DEF_FN_TYPE_2 (BT_FN_INT_UV8HI_UV8HI, B_VX, BT_INT, BT_UV8HI, BT_UV8HI) +DEF_FN_TYPE_2 (BT_FN_INT_V16QI_V16QI, B_VX, BT_INT, BT_V16QI, BT_V16QI) +DEF_FN_TYPE_2 (BT_FN_INT_V2DF_V2DF, B_VX, BT_INT, BT_V2DF, BT_V2DF) +DEF_FN_TYPE_2 (BT_FN_INT_V2DI_V2DI, B_VX, BT_INT, BT_V2DI, BT_V2DI) +DEF_FN_TYPE_2 (BT_FN_INT_V4SI_V4SI, B_VX, BT_INT, BT_V4SI, BT_V4SI) +DEF_FN_TYPE_2 (BT_FN_INT_V8HI_V8HI, B_VX, BT_INT, BT_V8HI, BT_V8HI) +DEF_FN_TYPE_2 (BT_FN_INT_VOIDPTR_INT, B_HTM, BT_INT, BT_VOIDPTR, BT_INT) +DEF_FN_TYPE_2 (BT_FN_OV2DI_LONGLONG_LONGLONG, B_VX, BT_OV2DI, BT_LONGLONG, BT_LONGLONG) +DEF_FN_TYPE_2 (BT_FN_OV4SI_INTCONSTPTR_INT, B_VX, BT_OV4SI, BT_INTCONSTPTR, BT_INT) +DEF_FN_TYPE_2 (BT_FN_OV4SI_INTCONSTPTR_UINT, B_VX, BT_OV4SI, BT_INTCONSTPTR, BT_UINT) +DEF_FN_TYPE_2 (BT_FN_OV4SI_INT_INT, B_VX, BT_OV4SI, BT_INT, BT_INT) +DEF_FN_TYPE_2 (BT_FN_OV4SI_OV4SI_INTPTR, B_VX, BT_OV4SI, BT_OV4SI, BT_INTPTR) +DEF_FN_TYPE_2 (BT_FN_OV4SI_OV4SI_OV4SI, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI) +DEF_FN_TYPE_2 (BT_FN_OV4SI_OV4SI_UCHAR, B_VX, BT_OV4SI, BT_OV4SI, BT_UCHAR) +DEF_FN_TYPE_2 (BT_FN_OV4SI_OV4SI_ULONG, B_VX, BT_OV4SI, BT_OV4SI, BT_ULONG) +DEF_FN_TYPE_2 (BT_FN_UCHAR_UV16QI_INT, B_VX, BT_UCHAR, BT_UV16QI, BT_INT) +DEF_FN_TYPE_2 (BT_FN_UINT_UV4SI_INT, B_VX, BT_UINT, BT_UV4SI, BT_INT) +DEF_FN_TYPE_2 (BT_FN_UINT_VOIDCONSTPTR_INT, B_VX, BT_UINT, BT_VOIDCONSTPTR, BT_INT) +DEF_FN_TYPE_2 (BT_FN_ULONGLONG_UV2DI_INT, B_VX, BT_ULONGLONG, BT_UV2DI, BT_INT) +DEF_FN_TYPE_2 (BT_FN_USHORT_UV8HI_INT, B_VX, BT_USHORT, BT_UV8HI, BT_INT) +DEF_FN_TYPE_2 (BT_FN_UV16QI_UCHARCONSTPTR_USHORT, B_VX, BT_UV16QI, BT_UCHARCONSTPTR, BT_USHORT) +DEF_FN_TYPE_2 (BT_FN_UV16QI_UCHAR_INT, B_VX, BT_UV16QI, BT_UCHAR, BT_INT) +DEF_FN_TYPE_2 (BT_FN_UV16QI_UCHAR_UCHAR, B_VX, BT_UV16QI, BT_UCHAR, BT_UCHAR) +DEF_FN_TYPE_2 (BT_FN_UV16QI_UV16QI_INTPTR, B_VX, BT_UV16QI, BT_UV16QI, BT_INTPTR) +DEF_FN_TYPE_2 (BT_FN_UV16QI_UV16QI_UCHAR, B_VX, BT_UV16QI, BT_UV16QI, BT_UCHAR) +DEF_FN_TYPE_2 (BT_FN_UV16QI_UV16QI_UINT, B_VX, BT_UV16QI, BT_UV16QI, BT_UINT) +DEF_FN_TYPE_2 (BT_FN_UV16QI_UV16QI_UV16QI, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI) +DEF_FN_TYPE_2 (BT_FN_UV16QI_UV2DI_UV2DI, B_VX, BT_UV16QI, BT_UV2DI, BT_UV2DI) +DEF_FN_TYPE_2 (BT_FN_UV16QI_UV4SI_UV4SI, B_VX, BT_UV16QI, BT_UV4SI, BT_UV4SI) +DEF_FN_TYPE_2 (BT_FN_UV16QI_UV8HI_UV8HI, B_VX, BT_UV16QI, BT_UV8HI, BT_UV8HI) +DEF_FN_TYPE_2 (BT_FN_UV2DI_UCHAR_UCHAR, B_VX, BT_UV2DI, BT_UCHAR, BT_UCHAR) +DEF_FN_TYPE_2 (BT_FN_UV2DI_ULONGLONG_INT, B_VX, BT_UV2DI, BT_ULONGLONG, BT_INT) +DEF_FN_TYPE_2 (BT_FN_UV2DI_UV2DI_UCHAR, B_VX, BT_UV2DI, BT_UV2DI, BT_UCHAR) +DEF_FN_TYPE_2 (BT_FN_UV2DI_UV2DI_UINT, B_VX, BT_UV2DI, BT_UV2DI, BT_UINT) +DEF_FN_TYPE_2 (BT_FN_UV2DI_UV2DI_UV2DI, B_VX, BT_UV2DI, BT_UV2DI, BT_UV2DI) +DEF_FN_TYPE_2 (BT_FN_UV2DI_UV4SI_UV4SI, B_VX, BT_UV2DI, BT_UV4SI, BT_UV4SI) +DEF_FN_TYPE_2 (BT_FN_UV2DI_UV8HI_UV8HI, B_VX, BT_UV2DI, BT_UV8HI, BT_UV8HI) +DEF_FN_TYPE_2 (BT_FN_UV2DI_V2DF_INT, B_VX, BT_UV2DI, BT_V2DF, BT_INT) +DEF_FN_TYPE_2 (BT_FN_UV4SI_UCHAR_UCHAR, B_VX, BT_UV4SI, BT_UCHAR, BT_UCHAR) +DEF_FN_TYPE_2 (BT_FN_UV4SI_UINT_INT, B_VX, BT_UV4SI, BT_UINT, BT_INT) +DEF_FN_TYPE_2 (BT_FN_UV4SI_UV16QI_UV16QI, B_VX, BT_UV4SI, BT_UV16QI, BT_UV16QI) +DEF_FN_TYPE_2 (BT_FN_UV4SI_UV2DI_UV2DI, B_VX, BT_UV4SI, BT_UV2DI, BT_UV2DI) +DEF_FN_TYPE_2 (BT_FN_UV4SI_UV4SI_INTPTR, B_VX, BT_UV4SI, BT_UV4SI, BT_INTPTR) +DEF_FN_TYPE_2 (BT_FN_UV4SI_UV4SI_UCHAR, B_VX, BT_UV4SI, BT_UV4SI, BT_UCHAR) +DEF_FN_TYPE_2 (BT_FN_UV4SI_UV4SI_UINT, B_VX, BT_UV4SI, BT_UV4SI, BT_UINT) +DEF_FN_TYPE_2 (BT_FN_UV4SI_UV4SI_UV4SI, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI) +DEF_FN_TYPE_2 (BT_FN_UV4SI_UV8HI_UV8HI, B_VX, BT_UV4SI, BT_UV8HI, BT_UV8HI) +DEF_FN_TYPE_2 (BT_FN_UV8HI_UCHAR_UCHAR, B_VX, BT_UV8HI, BT_UCHAR, BT_UCHAR) +DEF_FN_TYPE_2 (BT_FN_UV8HI_USHORT_INT, B_VX, BT_UV8HI, BT_USHORT, BT_INT) +DEF_FN_TYPE_2 (BT_FN_UV8HI_UV16QI_UV16QI, B_VX, BT_UV8HI, BT_UV16QI, BT_UV16QI) +DEF_FN_TYPE_2 (BT_FN_UV8HI_UV4SI_UV4SI, B_VX, BT_UV8HI, BT_UV4SI, BT_UV4SI) +DEF_FN_TYPE_2 (BT_FN_UV8HI_UV8HI_INTPTR, B_VX, BT_UV8HI, BT_UV8HI, BT_INTPTR) +DEF_FN_TYPE_2 (BT_FN_UV8HI_UV8HI_UCHAR, B_VX, BT_UV8HI, BT_UV8HI, BT_UCHAR) +DEF_FN_TYPE_2 (BT_FN_UV8HI_UV8HI_UINT, B_VX, BT_UV8HI, BT_UV8HI, BT_UINT) +DEF_FN_TYPE_2 (BT_FN_UV8HI_UV8HI_UV8HI, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI) +DEF_FN_TYPE_2 (BT_FN_V16QI_BV16QI_V16QI, B_VX, BT_V16QI, BT_BV16QI, BT_V16QI) +DEF_FN_TYPE_2 (BT_FN_V16QI_UINT_VOIDCONSTPTR, B_VX, BT_V16QI, BT_UINT, BT_VOIDCONSTPTR) +DEF_FN_TYPE_2 (BT_FN_V16QI_UV16QI_UV16QI, B_VX, BT_V16QI, BT_UV16QI, BT_UV16QI) +DEF_FN_TYPE_2 (BT_FN_V16QI_V16QI_V16QI, B_VX, BT_V16QI, BT_V16QI, BT_V16QI) +DEF_FN_TYPE_2 (BT_FN_V16QI_V8HI_V8HI, B_VX, BT_V16QI, BT_V8HI, BT_V8HI) +DEF_FN_TYPE_2 (BT_FN_V2DF_DBL_INT, B_VX, BT_V2DF, BT_DBL, BT_INT) +DEF_FN_TYPE_2 (BT_FN_V2DF_UV2DI_INT, B_VX, BT_V2DF, BT_UV2DI, BT_INT) +DEF_FN_TYPE_2 (BT_FN_V2DF_UV4SI_INT, B_VX, BT_V2DF, BT_UV4SI, BT_INT) +DEF_FN_TYPE_2 (BT_FN_V2DF_V2DF_V2DF, B_VX, BT_V2DF, BT_V2DF, BT_V2DF) +DEF_FN_TYPE_2 (BT_FN_V2DF_V2DI_INT, B_VX, BT_V2DF, BT_V2DI, BT_INT) +DEF_FN_TYPE_2 (BT_FN_V2DI_BV2DI_V2DI, B_VX, BT_V2DI, BT_BV2DI, BT_V2DI) +DEF_FN_TYPE_2 (BT_FN_V2DI_UV2DI_UV2DI, B_VX, BT_V2DI, BT_UV2DI, BT_UV2DI) +DEF_FN_TYPE_2 (BT_FN_V2DI_V2DF_INT, B_VX, BT_V2DI, BT_V2DF, BT_INT) +DEF_FN_TYPE_2 (BT_FN_V2DI_V2DF_V2DF, B_VX, BT_V2DI, BT_V2DF, BT_V2DF) +DEF_FN_TYPE_2 (BT_FN_V2DI_V2DI_V2DI, B_VX, BT_V2DI, BT_V2DI, BT_V2DI) +DEF_FN_TYPE_2 (BT_FN_V2DI_V4SI_V4SI, B_VX, BT_V2DI, BT_V4SI, BT_V4SI) +DEF_FN_TYPE_2 (BT_FN_V4SI_BV4SI_V4SI, B_VX, BT_V4SI, BT_BV4SI, BT_V4SI) +DEF_FN_TYPE_2 (BT_FN_V4SI_INT_VOIDPTR, B_VX, BT_V4SI, BT_INT, BT_VOIDPTR) +DEF_FN_TYPE_2 (BT_FN_V4SI_UV4SI_UV4SI, B_VX, BT_V4SI, BT_UV4SI, BT_UV4SI) +DEF_FN_TYPE_2 (BT_FN_V4SI_V2DI_V2DI, B_VX, BT_V4SI, BT_V2DI, BT_V2DI) +DEF_FN_TYPE_2 (BT_FN_V4SI_V4SI_V4SI, B_VX, BT_V4SI, BT_V4SI, BT_V4SI) +DEF_FN_TYPE_2 (BT_FN_V4SI_V8HI_V8HI, B_VX, BT_V4SI, BT_V8HI, BT_V8HI) +DEF_FN_TYPE_2 (BT_FN_V8HI_BV8HI_V8HI, B_VX, BT_V8HI, BT_BV8HI, BT_V8HI) +DEF_FN_TYPE_2 (BT_FN_V8HI_UV8HI_UV8HI, B_VX, BT_V8HI, BT_UV8HI, BT_UV8HI) +DEF_FN_TYPE_2 (BT_FN_V8HI_V16QI_V16QI, B_VX, BT_V8HI, BT_V16QI, BT_V16QI) +DEF_FN_TYPE_2 (BT_FN_V8HI_V4SI_V4SI, B_VX, BT_V8HI, BT_V4SI, BT_V4SI) +DEF_FN_TYPE_2 (BT_FN_V8HI_V8HI_V8HI, B_VX, BT_V8HI, BT_V8HI, BT_V8HI) +DEF_FN_TYPE_2 (BT_FN_VOID_UINT64PTR_UINT64, B_HTM, BT_VOID, BT_UINT64PTR, BT_UINT64) +DEF_FN_TYPE_2 (BT_FN_VOID_V2DF_FLTPTR, B_VX, BT_VOID, BT_V2DF, BT_FLTPTR) +DEF_FN_TYPE_3 (BT_FN_INT_OV4SI_OV4SI_INTPTR, B_VX, BT_INT, BT_OV4SI, BT_OV4SI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_OV4SI_INT_OV4SI_INT, B_VX, BT_OV4SI, BT_INT, BT_OV4SI, BT_INT) +DEF_FN_TYPE_3 (BT_FN_OV4SI_OV4SI_OV4SI_INT, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_INT) +DEF_FN_TYPE_3 (BT_FN_OV4SI_OV4SI_OV4SI_INTPTR, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_OV4SI_OV4SI_OV4SI_OV4SI, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_OV4SI) +DEF_FN_TYPE_3 (BT_FN_OV4SI_OV4SI_OV4SI_UCHAR, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_UCHAR) +DEF_FN_TYPE_3 (BT_FN_OV4SI_OV4SI_OV4SI_ULONGLONG, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_ULONGLONG) +DEF_FN_TYPE_3 (BT_FN_UV16QI_UV16QI_UCHAR_INT, B_VX, BT_UV16QI, BT_UV16QI, BT_UCHAR, BT_INT) +DEF_FN_TYPE_3 (BT_FN_UV16QI_UV16QI_UV16QI_INT, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_INT) +DEF_FN_TYPE_3 (BT_FN_UV16QI_UV16QI_UV16QI_INTPTR, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_UV16QI_UV16QI_UV16QI_UV16QI, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_UV16QI) +DEF_FN_TYPE_3 (BT_FN_UV16QI_UV2DI_UV2DI_UV16QI, B_VX, BT_UV16QI, BT_UV2DI, BT_UV2DI, BT_UV16QI) +DEF_FN_TYPE_3 (BT_FN_UV16QI_UV8HI_UV8HI_INTPTR, B_VX, BT_UV16QI, BT_UV8HI, BT_UV8HI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_UV2DI_UV2DI_ULONGLONG_INT, B_VX, BT_UV2DI, BT_UV2DI, BT_ULONGLONG, BT_INT) +DEF_FN_TYPE_3 (BT_FN_UV2DI_UV2DI_UV2DI_INT, B_VX, BT_UV2DI, BT_UV2DI, BT_UV2DI, BT_INT) +DEF_FN_TYPE_3 (BT_FN_UV2DI_UV4SI_UV4SI_UV2DI, B_VX, BT_UV2DI, BT_UV4SI, BT_UV4SI, BT_UV2DI) +DEF_FN_TYPE_3 (BT_FN_UV4SI_UV2DI_UV2DI_INTPTR, B_VX, BT_UV4SI, BT_UV2DI, BT_UV2DI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_UV4SI_UV4SI_UINT_INT, B_VX, BT_UV4SI, BT_UV4SI, BT_UINT, BT_INT) +DEF_FN_TYPE_3 (BT_FN_UV4SI_UV4SI_UV4SI_INT, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_INT) +DEF_FN_TYPE_3 (BT_FN_UV4SI_UV4SI_UV4SI_INTPTR, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_UV4SI_UV4SI_UV4SI_UV4SI, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_UV4SI) +DEF_FN_TYPE_3 (BT_FN_UV4SI_UV8HI_UV8HI_UV4SI, B_VX, BT_UV4SI, BT_UV8HI, BT_UV8HI, BT_UV4SI) +DEF_FN_TYPE_3 (BT_FN_UV8HI_UV16QI_UV16QI_UV8HI, B_VX, BT_UV8HI, BT_UV16QI, BT_UV16QI, BT_UV8HI) +DEF_FN_TYPE_3 (BT_FN_UV8HI_UV4SI_UV4SI_INTPTR, B_VX, BT_UV8HI, BT_UV4SI, BT_UV4SI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_USHORT_INT, B_VX, BT_UV8HI, BT_UV8HI, BT_USHORT, BT_INT) +DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_UV8HI_INT, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INT) +DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_UV8HI_INTPTR, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_UV8HI_UV8HI_UV8HI_UV8HI, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_UV8HI) +DEF_FN_TYPE_3 (BT_FN_V16QI_UV16QI_UV16QI_INTPTR, B_VX, BT_V16QI, BT_UV16QI, BT_UV16QI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V16QI_V16QI_V16QI_INTPTR, B_VX, BT_V16QI, BT_V16QI, BT_V16QI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V16QI_V16QI_V16QI_V16QI, B_VX, BT_V16QI, BT_V16QI, BT_V16QI, BT_V16QI) +DEF_FN_TYPE_3 (BT_FN_V16QI_V8HI_V8HI_INTPTR, B_VX, BT_V16QI, BT_V8HI, BT_V8HI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V2DF_V2DF_DBL_INT, B_VX, BT_V2DF, BT_V2DF, BT_DBL, BT_INT) +DEF_FN_TYPE_3 (BT_FN_V2DF_V2DF_UCHAR_UCHAR, B_VX, BT_V2DF, BT_V2DF, BT_UCHAR, BT_UCHAR) +DEF_FN_TYPE_3 (BT_FN_V2DF_V2DF_V2DF_V2DF, B_VX, BT_V2DF, BT_V2DF, BT_V2DF, BT_V2DF) +DEF_FN_TYPE_3 (BT_FN_V2DI_UV2DI_UV2DI_INTPTR, B_VX, BT_V2DI, BT_UV2DI, BT_UV2DI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V2DI_V2DF_INT_INTPTR, B_VX, BT_V2DI, BT_V2DF, BT_INT, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V2DI_V2DF_V2DF_INTPTR, B_VX, BT_V2DI, BT_V2DF, BT_V2DF, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V2DI_V2DI_V2DI_INTPTR, B_VX, BT_V2DI, BT_V2DI, BT_V2DI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V2DI_V4SI_V4SI_V2DI, B_VX, BT_V2DI, BT_V4SI, BT_V4SI, BT_V2DI) +DEF_FN_TYPE_3 (BT_FN_V4SI_UV4SI_UV4SI_INTPTR, B_VX, BT_V4SI, BT_UV4SI, BT_UV4SI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V4SI_V2DI_V2DI_INTPTR, B_VX, BT_V4SI, BT_V2DI, BT_V2DI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V4SI_V4SI_V4SI_INTPTR, B_VX, BT_V4SI, BT_V4SI, BT_V4SI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V4SI_V4SI_V4SI_V4SI, B_VX, BT_V4SI, BT_V4SI, BT_V4SI, BT_V4SI) +DEF_FN_TYPE_3 (BT_FN_V4SI_V8HI_V8HI_V4SI, B_VX, BT_V4SI, BT_V8HI, BT_V8HI, BT_V4SI) +DEF_FN_TYPE_3 (BT_FN_V8HI_UV8HI_UV8HI_INTPTR, B_VX, BT_V8HI, BT_UV8HI, BT_UV8HI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V8HI_V16QI_V16QI_V8HI, B_VX, BT_V8HI, BT_V16QI, BT_V16QI, BT_V8HI) +DEF_FN_TYPE_3 (BT_FN_V8HI_V4SI_V4SI_INTPTR, B_VX, BT_V8HI, BT_V4SI, BT_V4SI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V8HI_V8HI_V8HI_INTPTR, B_VX, BT_V8HI, BT_V8HI, BT_V8HI, BT_INTPTR) +DEF_FN_TYPE_3 (BT_FN_V8HI_V8HI_V8HI_V8HI, B_VX, BT_V8HI, BT_V8HI, BT_V8HI, BT_V8HI) +DEF_FN_TYPE_3 (BT_FN_VOID_OV4SI_INT_VOIDPTR, B_VX, BT_VOID, BT_OV4SI, BT_INT, BT_VOIDPTR) +DEF_FN_TYPE_3 (BT_FN_VOID_OV4SI_VOIDPTR_UINT, B_VX, BT_VOID, BT_OV4SI, BT_VOIDPTR, BT_UINT) +DEF_FN_TYPE_3 (BT_FN_VOID_V16QI_UINT_VOIDPTR, B_VX, BT_VOID, BT_V16QI, BT_UINT, BT_VOIDPTR) +DEF_FN_TYPE_4 (BT_FN_OV4SI_OV4SI_OUV4SI_INTCONSTPTR_UCHAR, B_VX, BT_OV4SI, BT_OV4SI, BT_OUV4SI, BT_INTCONSTPTR, BT_UCHAR) +DEF_FN_TYPE_4 (BT_FN_OV4SI_OV4SI_OV4SI_OV4SI_INTPTR, B_VX, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_OV4SI, BT_INTPTR) +DEF_FN_TYPE_4 (BT_FN_UV16QI_UV16QI_UV16QI_INT_INTPTR, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_INT, BT_INTPTR) +DEF_FN_TYPE_4 (BT_FN_UV16QI_UV16QI_UV16QI_UV16QI_INT, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_INT) +DEF_FN_TYPE_4 (BT_FN_UV2DI_UV2DI_UV2DI_ULONGLONGCONSTPTR_UCHAR, B_VX, BT_UV2DI, BT_UV2DI, BT_UV2DI, BT_ULONGLONGCONSTPTR, BT_UCHAR) +DEF_FN_TYPE_4 (BT_FN_UV2DI_UV2DI_UV2DI_UV2DI_INT, B_VX, BT_UV2DI, BT_UV2DI, BT_UV2DI, BT_UV2DI, BT_INT) +DEF_FN_TYPE_4 (BT_FN_UV4SI_UV4SI_UV4SI_INT_INTPTR, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_INT, BT_INTPTR) +DEF_FN_TYPE_4 (BT_FN_UV4SI_UV4SI_UV4SI_UINTCONSTPTR_UCHAR, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_UINTCONSTPTR, BT_UCHAR) +DEF_FN_TYPE_4 (BT_FN_UV4SI_UV4SI_UV4SI_UV4SI_INT, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_INT) +DEF_FN_TYPE_4 (BT_FN_UV8HI_UV8HI_UV8HI_INT_INTPTR, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INT, BT_INTPTR) +DEF_FN_TYPE_4 (BT_FN_UV8HI_UV8HI_UV8HI_UV8HI_INT, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INT) +DEF_FN_TYPE_4 (BT_FN_VOID_UV2DI_UV2DI_ULONGLONGPTR_ULONGLONG, B_VX, BT_VOID, BT_UV2DI, BT_UV2DI, BT_ULONGLONGPTR, BT_ULONGLONG) +DEF_FN_TYPE_4 (BT_FN_VOID_UV4SI_UV4SI_UINTPTR_ULONGLONG, B_VX, BT_VOID, BT_UV4SI, BT_UV4SI, BT_UINTPTR, BT_ULONGLONG) +DEF_FN_TYPE_4 (BT_FN_VOID_V4SI_V4SI_INTPTR_ULONGLONG, B_VX, BT_VOID, BT_V4SI, BT_V4SI, BT_INTPTR, BT_ULONGLONG) +DEF_FN_TYPE_5 (BT_FN_UV16QI_UV16QI_UV16QI_UV16QI_INT_INTPTR, B_VX, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_UV16QI, BT_INT, BT_INTPTR) +DEF_FN_TYPE_5 (BT_FN_UV4SI_UV4SI_UV4SI_UV4SI_INT_INTPTR, B_VX, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_UV4SI, BT_INT, BT_INTPTR) +DEF_FN_TYPE_5 (BT_FN_UV8HI_UV8HI_UV8HI_UV8HI_INT_INTPTR, B_VX, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_UV8HI, BT_INT, BT_INTPTR) DEF_OV_TYPE (BT_OV_BV16QI_BV16QI, BT_BV16QI, BT_BV16QI) DEF_OV_TYPE (BT_OV_BV16QI_BV16QI_BV16QI, BT_BV16QI, BT_BV16QI, BT_BV16QI) DEF_OV_TYPE (BT_OV_BV16QI_BV16QI_BV16QI_BV16QI, BT_BV16QI, BT_BV16QI, BT_BV16QI, BT_BV16QI) diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 48b8222bf87..ee0187c67f7 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -791,7 +791,7 @@ s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED) { -#define MAX_ARGS 5 +#define MAX_ARGS 6 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); unsigned int fcode = DECL_FUNCTION_CODE (fndecl); diff --git a/gcc/config/s390/vecintrin.h b/gcc/config/s390/vecintrin.h index ab82e7aed06..2bd35d67064 100644 --- a/gcc/config/s390/vecintrin.h +++ b/gcc/config/s390/vecintrin.h @@ -1,4 +1,4 @@ -/* GNU compiler hardware transactional execution intrinsics +/* GNU compiler vector extension intrinsics Copyright (C) 2015-2016 Free Software Foundation, Inc. Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com) diff --git a/gcc/config/sparc/driver-sparc.c b/gcc/config/sparc/driver-sparc.c index b81763e4c4f..ea174bf3dc5 100644 --- a/gcc/config/sparc/driver-sparc.c +++ b/gcc/config/sparc/driver-sparc.c @@ -57,7 +57,6 @@ static const struct cpu_names { { "UltraSPARC-T2+", "niagara2" }, { "SPARC-T3", "niagara3" }, { "SPARC-T4", "niagara4" }, - { "SPARC-M7", "niagara7" }, #else { "SuperSparc", "supersparc" }, { "HyperSparc", "hypersparc" }, @@ -74,9 +73,10 @@ static const struct cpu_names { { "UltraSparc T2", "niagara2" }, { "UltraSparc T3", "niagara3" }, { "UltraSparc T4", "niagara4" }, - { "UltraSparc M7", "niagara7" }, { "LEON", "leon3" }, #endif + { "SPARC-M7", "niagara7" }, + { "SPARC-S7", "niagara7" }, { NULL, NULL } }; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 86dddd210d7..2b17452d812 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,55 @@ +2016-06-13 Paolo Carlini <paolo.carlini@oracle.com> + + * decl.c (grokdeclarator): Fix typo in pedwarn text. + +2016-06-10 Thomas Schwinge <thomas@codesourcery.com> + + PR c/71381 + * parser.c (cp_parser_omp_var_list_no_open) <OMP_CLAUSE__CACHE_>: + Loosen checking. + +2016-06-09 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/71465 + Revert: + 2016-06-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/70202 + * parser.c (cp_parser_class_head): When xref_basetypes fails and + emits an error do not zero the type. + +2016-06-08 Paolo Carlini <paolo.carlini@oracle.com> + + * decl.c (maybe_deduce_size_from_array_init): Use + DECL_SOURCE_LOCATION in error_at. + (layout_var_decl): Likewise. + (check_array_initializer): Likewise. + (check_initializer): Likewise. + (duplicate_decls, check_elaborated_type_specifier): Tidy. + +2016-06-08 Martin Sebor <msebor@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/70507 + PR c/68120 + * constexpr.c: Include gimple-fold.h. + (cxx_eval_internal_function): New function. + (cxx_eval_call_expression): Call it. + (potential_constant_expression_1): Handle integer arithmetic + overflow built-ins. + * tree.c (builtin_valid_in_constant_expr_p): Handle + BUILT_IN_{ADD,SUB,MUL}_OVERFLOW_P. + +2016-06-08 Paolo Carlini <paolo.carlini@oracle.com> + + * pt.c (tsubst, case TYPENAME_TYPE): Don't delay checking the + return value of tsubst_aggr_type for error_mark_node. + +2016-06-08 Jakub Jelinek <jakub@redhat.com> + + PR c++/71442 + * pt.c (tsubst_copy): Only set TREE_USED on DECLs. + 2016-06-06 Jakub Jelinek <jakub@redhat.com> Patrick Palka <ppalka@gcc.gnu.org> diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 482f8afaeb6..ba40435ef67 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "tree-inline.h" #include "ubsan.h" +#include "gimple-fold.h" static bool verify_constant (tree, bool, bool *, bool *); #define VERIFY_CONSTANT(X) \ @@ -1255,6 +1256,69 @@ cx_error_context (void) return r; } +/* Evaluate a call T to a GCC internal function when possible and return + the evaluated result or, under the control of CTX, give an error, set + NON_CONSTANT_P, and return the unevaluated call T otherwise. */ + +static tree +cxx_eval_internal_function (const constexpr_ctx *ctx, tree t, + bool lval, + bool *non_constant_p, bool *overflow_p) +{ + enum tree_code opcode = ERROR_MARK; + + switch (CALL_EXPR_IFN (t)) + { + case IFN_UBSAN_NULL: + case IFN_UBSAN_BOUNDS: + case IFN_UBSAN_VPTR: + return void_node; + + case IFN_ADD_OVERFLOW: + opcode = PLUS_EXPR; + break; + case IFN_SUB_OVERFLOW: + opcode = MINUS_EXPR; + break; + case IFN_MUL_OVERFLOW: + opcode = MULT_EXPR; + break; + + default: + if (!ctx->quiet) + error_at (EXPR_LOC_OR_LOC (t, input_location), + "call to internal function %qE", t); + *non_constant_p = true; + return t; + } + + /* Evaluate constant arguments using OPCODE and return a complex + number containing the result and the overflow bit. */ + tree arg0 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0), lval, + non_constant_p, overflow_p); + tree arg1 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 1), lval, + non_constant_p, overflow_p); + + if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) + { + location_t loc = EXPR_LOC_OR_LOC (t, input_location); + tree type = TREE_TYPE (TREE_TYPE (t)); + tree result = fold_binary_loc (loc, opcode, type, + fold_convert_loc (loc, type, arg0), + fold_convert_loc (loc, type, arg1)); + tree ovf + = build_int_cst (type, arith_overflowed_p (opcode, type, arg0, arg1)); + /* Reset TREE_OVERFLOW to avoid warnings for the overflow. */ + if (TREE_OVERFLOW (result)) + TREE_OVERFLOW (result) = 0; + + return build_complex (TREE_TYPE (t), result, ovf); + } + + *non_constant_p = true; + return t; +} + /* Subroutine of cxx_eval_constant_expression. Evaluate the call expression tree T in the context of OLD_CALL expression evaluation. */ @@ -1270,18 +1334,8 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, bool depth_ok; if (fun == NULL_TREE) - switch (CALL_EXPR_IFN (t)) - { - case IFN_UBSAN_NULL: - case IFN_UBSAN_BOUNDS: - case IFN_UBSAN_VPTR: - return void_node; - default: - if (!ctx->quiet) - error_at (loc, "call to internal function"); - *non_constant_p = true; - return t; - } + return cxx_eval_internal_function (ctx, t, lval, + non_constant_p, overflow_p); if (TREE_CODE (fun) != FUNCTION_DECL) { @@ -4588,6 +4642,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, if (fun == NULL_TREE) { + /* Reset to allow the function to continue past the end + of the block below. Otherwise return early. */ + bool bail = true; + if (TREE_CODE (t) == CALL_EXPR && CALL_EXPR_FN (t) == NULL_TREE) switch (CALL_EXPR_IFN (t)) @@ -4598,16 +4656,27 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, case IFN_UBSAN_BOUNDS: case IFN_UBSAN_VPTR: return true; + + case IFN_ADD_OVERFLOW: + case IFN_SUB_OVERFLOW: + case IFN_MUL_OVERFLOW: + bail = false; + default: break; } - /* fold_call_expr can't do anything with IFN calls. */ - if (flags & tf_error) - error_at (EXPR_LOC_OR_LOC (t, input_location), - "call to internal function"); - return false; + + if (bail) + { + /* fold_call_expr can't do anything with IFN calls. */ + if (flags & tf_error) + error_at (EXPR_LOC_OR_LOC (t, input_location), + "call to internal function %qE", t); + return false; + } } - if (is_overloaded_fn (fun)) + + if (fun && is_overloaded_fn (fun)) { if (TREE_CODE (fun) == FUNCTION_DECL) { @@ -4652,7 +4721,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, i = num_artificial_parms_for (fun); fun = DECL_ORIGIN (fun); } - else + else if (fun) { if (RECUR (fun, rval)) /* Might end up being a constant function pointer. */; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3328e7158aa..415689f535f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1393,7 +1393,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) { if (DECL_INITIAL (olddecl)) inform (DECL_SOURCE_LOCATION (olddecl), - "previous definition of %q+D was here", olddecl); + "previous definition of %qD was here", olddecl); else inform (DECL_SOURCE_LOCATION (olddecl), "previous declaration of %qD was here", olddecl); @@ -5266,13 +5266,16 @@ maybe_deduce_size_from_array_init (tree decl, tree init) do_default); if (failure == 1) { - error ("initializer fails to determine size of %qD", decl); + error_at (EXPR_LOC_OR_LOC (initializer, + DECL_SOURCE_LOCATION (decl)), + "initializer fails to determine size of %qD", decl); } else if (failure == 2) { if (do_default) { - error ("array size missing in %qD", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "array size missing in %qD", decl); } /* If a `static' var's size isn't known, make it extern as well as static, so it does not get allocated. If it's not @@ -5283,7 +5286,8 @@ maybe_deduce_size_from_array_init (tree decl, tree init) } else if (failure == 3) { - error ("zero-size array %qD", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "zero-size array %qD", decl); } } @@ -5322,7 +5326,8 @@ layout_var_decl (tree decl) /* An automatic variable with an incomplete type: that is an error. Don't talk about array types here, since we took care of that message in grokdeclarator. */ - error ("storage size of %qD isn%'t known", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "storage size of %qD isn%'t known", decl); TREE_TYPE (decl) = error_mark_node; } #if 0 @@ -5345,7 +5350,8 @@ layout_var_decl (tree decl) constant_expression_warning (DECL_SIZE (decl)); else { - error ("storage size of %qD isn%'t constant", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "storage size of %qD isn%'t constant", decl); TREE_TYPE (decl) = error_mark_node; } } @@ -5954,7 +5960,8 @@ check_array_initializer (tree decl, tree type, tree init) if (!COMPLETE_TYPE_P (complete_type (element_type))) { if (decl) - error ("elements of array %q#D have incomplete type", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "elements of array %q#D have incomplete type", decl); else error ("elements of array %q#T have incomplete type", type); return true; @@ -6018,7 +6025,8 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) } else if (!COMPLETE_TYPE_P (type)) { - error ("%q#D has incomplete type", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "%q#D has incomplete type", decl); TREE_TYPE (decl) = error_mark_node; return NULL_TREE; } @@ -6038,8 +6046,9 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) } else if (init_len != 1 && TREE_CODE (type) != COMPLEX_TYPE) { - error ("scalar object %qD requires one element in initializer", - decl); + error_at (EXPR_LOC_OR_LOC (init, DECL_SOURCE_LOCATION (decl)), + "scalar object %qD requires one element in " + "initializer", decl); TREE_TYPE (decl) = error_mark_node; return NULL_TREE; } @@ -6081,9 +6090,10 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) { /* Don't reshape if the class has constructors. */ if (cxx_dialect == cxx98) - error ("in C++98 %qD must be initialized by constructor, " - "not by %<{...}%>", - decl); + error_at (EXPR_LOC_OR_LOC (init, DECL_SOURCE_LOCATION (decl)), + "in C++98 %qD must be initialized by " + "constructor, not by %<{...}%>", + decl); } else if (VECTOR_TYPE_P (type) && TYPE_VECTOR_OPAQUE (type)) { @@ -6175,8 +6185,11 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) && DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST && PAREN_STRING_LITERAL_P (DECL_INITIAL (decl))) - warning (0, "array %qD initialized by parenthesized string literal %qE", - decl, DECL_INITIAL (decl)); + warning_at (EXPR_LOC_OR_LOC (DECL_INITIAL (decl), + DECL_SOURCE_LOCATION (decl)), + 0, "array %qD initialized by parenthesized " + "string literal %qE", + decl, DECL_INITIAL (decl)); init = NULL; } } @@ -11352,7 +11365,7 @@ grokdeclarator (const cp_declarator *declarator, { if (storage_class == sc_static) pedwarn (input_location, OPT_Wpedantic, - "%<static%> specified invalid for function %qs " + "%<static%> specifier invalid for function %qs " "declared out of global scope", name); else pedwarn (input_location, OPT_Wpedantic, @@ -12528,14 +12541,14 @@ check_elaborated_type_specifier (enum tag_types tag_code, && tag_code != typename_type) { error ("%qT referred to as %qs", type, tag_name (tag_code)); - inform (input_location, "%q+T has a previous declaration here", type); + inform (location_of (type), "%qT has a previous declaration here", type); return error_mark_node; } else if (TREE_CODE (type) != ENUMERAL_TYPE && tag_code == enum_type) { error ("%qT referred to as enum", type); - inform (input_location, "%q+T has a previous declaration here", type); + inform (location_of (type), "%qT has a previous declaration here", type); return error_mark_node; } else if (!allow_template_p diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 2fccc5acf01..632b25fac95 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22050,8 +22050,9 @@ cp_parser_class_head (cp_parser* parser, /* If we're really defining a class, process the base classes. If they're invalid, fail. */ - if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) - xref_basetypes (type, bases); + if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE) + && !xref_basetypes (type, bases)) + type = NULL_TREE; done: /* Leave the scope given by the nested-name-specifier. We will @@ -29983,6 +29984,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, switch (kind) { case OMP_CLAUSE__CACHE_: + /* The OpenACC cache directive explicitly only allows "array + elements or subarrays". */ if (cp_lexer_peek_token (parser->lexer)->type != CPP_OPEN_SQUARE) { error_at (token->location, "expected %<[%>"); @@ -30034,25 +30037,6 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, RT_CLOSE_SQUARE)) goto skip_comma; - if (kind == OMP_CLAUSE__CACHE_) - { - if (TREE_CODE (low_bound) != INTEGER_CST - && !TREE_READONLY (low_bound)) - { - error_at (token->location, - "%qD is not a constant", low_bound); - decl = error_mark_node; - } - - if (TREE_CODE (length) != INTEGER_CST - && !TREE_READONLY (length)) - { - error_at (token->location, - "%qD is not a constant", length); - decl = error_mark_node; - } - } - decl = tree_cons (low_bound, length, decl); } break; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 64fef68c9e3..3a3d9b8f439 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13430,10 +13430,12 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain, in_decl, /*entering_scope=*/1); + if (ctx == error_mark_node) + return error_mark_node; + tree f = tsubst_copy (TYPENAME_TYPE_FULLNAME (t), args, complain, in_decl); - - if (ctx == error_mark_node || f == error_mark_node) + if (f == error_mark_node) return error_mark_node; if (!MAYBE_CLASS_TYPE_P (ctx)) @@ -14160,7 +14162,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) len = TREE_VEC_LENGTH (expanded); /* Set TREE_USED for the benefit of -Wunused. */ for (int i = 0; i < len; i++) - TREE_USED (TREE_VEC_ELT (expanded, i)) = true; + if (DECL_P (TREE_VEC_ELT (expanded, i))) + TREE_USED (TREE_VEC_ELT (expanded, i)) = true; } if (expanded == error_mark_node) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 04702ee1c00..abda6e4f729 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -352,6 +352,12 @@ builtin_valid_in_constant_expr_p (const_tree decl) case BUILT_IN_FUNCTION: case BUILT_IN_LINE: + /* The following built-ins are valid in constant expressions + when their arguments are. */ + case BUILT_IN_ADD_OVERFLOW_P: + case BUILT_IN_SUB_OVERFLOW_P: + case BUILT_IN_MUL_OVERFLOW_P: + /* These have constant results even if their operands are non-constant. */ case BUILT_IN_CONSTANT_P: diff --git a/gcc/df-problems.c b/gcc/df-problems.c index 132c1276e89..290281ccd4f 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -3498,13 +3498,13 @@ df_note_bb_compute (unsigned int bb_index, FOR_BB_INSNS_REVERSE (bb, insn) { + if (!INSN_P (insn)) + continue; + df_insn_info *insn_info = DF_INSN_INFO_GET (insn); df_mw_hardreg *mw; int debug_insn; - if (!INSN_P (insn)) - continue; - debug_insn = DEBUG_INSN_P (insn); bitmap_clear (do_not_gen); diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index 48ae50d6879..58d77df61c5 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -231,12 +231,6 @@ diagnostic_inhibit_notes (diagnostic_context * context) /* Same as output_prefixing_rule. Works on 'diagnostic_context *'. */ #define diagnostic_prefixing_rule(DC) ((DC)->printer->wrapping.rule) -/* Maximum characters per line in automatic line wrapping mode. - Zero means don't wrap lines. */ -#define diagnostic_line_cutoff(DC) ((DC)->printer->wrapping.line_cutoff) - -#define diagnostic_flush_buffer(DC) pp_flush ((DC)->printer) - /* True if the last module or file in which a diagnostic was reported is different from the current one. */ #define diagnostic_last_module_changed(DC, MAP) \ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 7208f33e76c..06d52b8ce0d 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -9869,6 +9869,47 @@ functions above, except they perform multiplication, instead of addition. @end deftypefn +The following built-in functions allow checking if simple arithmetic operation +would overflow. + +@deftypefn {Built-in Function} bool __builtin_add_overflow_p (@var{type1} a, @var{type2} b, @var{type3} c) +@deftypefnx {Built-in Function} bool __builtin_sub_overflow_p (@var{type1} a, @var{type2} b, @var{type3} c) +@deftypefnx {Built-in Function} bool __builtin_mul_overflow_p (@var{type1} a, @var{type2} b, @var{type3} c) + +These built-in functions are similar to @code{__builtin_add_overflow}, +@code{__builtin_sub_overflow}, or @code{__builtin_mul_overflow}, except that +they don't store the result of the arithmetic operation anywhere and the +last argument is not a pointer, but some integral expression. + +The built-in functions promote the first two operands into infinite precision signed type +and perform addition on those promoted operands. The result is then +cast to the type of the third argument. If the cast result is equal to the infinite +precision result, the built-in functions return false, otherwise they return true. +The value of the third argument is ignored, just the side-effects in the third argument +are evaluated, and no integral argument promotions are performed on the last argument. + +For example, the following macro can be used to portably check, at +compile-time, whether or not adding two constant integers will overflow, +and perform the addition only when it is known to be safe and not to trigger +a @option{-Woverflow} warning. + +@smallexample +#define INT_ADD_OVERFLOW_P(a, b) \ + __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0) + +enum @{ + A = INT_MAX, B = 3, + C = INT_ADD_OVERFLOW_P (A, B) ? 0 : A + B, + D = __builtin_add_overflow_p (1, SCHAR_MAX, (signed char) 0) +@}; +@end smallexample + +The compiler will attempt to use hardware instructions to implement +these built-in functions where possible, like conditional jump on overflow +after addition, conditional jump on carry etc. + +@end deftypefn + @node x86 specific memory model extensions for transactional memory @section x86-Specific Memory Model Extensions for Transactional Memory @@ -17452,6 +17493,31 @@ result returned from the @code{vec_srv} function is a (0x07 & shift_distance[i]))}, with this resulting value coerced to the @code{unsigned char} type. +The following built-in functions are available for the PowerPC family +of processors, starting with ISA 3.0 or later (@option{-mcpu=power9}) +or with @option{-mpower9-vector}: +@smallexample +__vector unsigned char +vec_absd (__vector unsigned char arg1, __vector unsigned char arg2); +__vector unsigned short +vec_absd (__vector unsigned short arg1, __vector unsigned short arg2); +__vector unsigned int +vec_absd (__vector unsigned int arg1, __vector unsigned int arg2); + +__vector unsigned char +vec_absdb (__vector unsigned char arg1, __vector unsigned char arg2); +__vector unsigned short +vec_absdh (__vector unsigned short arg1, __vector unsigned short arg2); +__vector unsigned int +vec_absdw (__vector unsigned int arg1, __vector unsigned int arg2); +@end smallexample + +The @code{vec_absd}, @code{vec_absdb}, @code{vec_absdh}, and +@code{vec_absdw} built-in functions each computes the absolute +differences of the pairs of vector elements supplied in its two vector +arguments, placing the absolute differences into the corresponding +elements of the vector result. + If the cryptographic instructions are enabled (@option{-mcrypto} or @option{-mcpu=power8}), the following builtins are enabled. @@ -18404,28 +18470,19 @@ integers, these use @code{V4SI}. Finally, some instructions operate on an entire vector register, interpreting it as a 128-bit integer, these use mode @code{TI}. -In 64-bit mode, the x86-64 family of processors uses additional built-in +The x86-32 and x86-64 family of processors use additional built-in functions for efficient use of @code{TF} (@code{__float128}) 128-bit floating point and @code{TC} 128-bit complex floating-point values. -The following floating-point built-in functions are available in 64-bit -mode. All of them implement the function that is part of the name. +The following floating-point built-in functions are always available. All +of them implement the function that is part of the name. @smallexample __float128 __builtin_fabsq (__float128) __float128 __builtin_copysignq (__float128, __float128) @end smallexample -The following built-in function is always available. - -@table @code -@item void __builtin_ia32_pause (void) -Generates the @code{pause} machine instruction with a compiler memory -barrier. -@end table - -The following floating-point built-in functions are made available in the -64-bit mode. +The following built-in functions are always available. @table @code @item __float128 __builtin_infq (void) @@ -18435,6 +18492,22 @@ Similar to @code{__builtin_inf}, except the return type is @code{__float128}. @item __float128 __builtin_huge_valq (void) Similar to @code{__builtin_huge_val}, except the return type is @code{__float128}. @findex __builtin_huge_valq + +@item __float128 __builtin_nanq (void) +Similar to @code{__builtin_nan}, except the return type is @code{__float128}. +@findex __builtin_nanq + +@item __float128 __builtin_nansq (void) +Similar to @code{__builtin_nans}, except the return type is @code{__float128}. +@findex __builtin_nansq +@end table + +The following built-in function is always available. + +@table @code +@item void __builtin_ia32_pause (void) +Generates the @code{pause} machine instruction with a compiler memory +barrier. @end table The following built-in functions are always available and can be used to diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 15bb42a5a7b..ec9719c04c1 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -14070,16 +14070,23 @@ name to determine what kind of instructions it can emit when generating assembly code. This option can be used in conjunction with or instead of the @option{-mcpu=} option. Permissible names are: @samp{armv2}, @samp{armv2a}, @samp{armv3}, @samp{armv3m}, @samp{armv4}, @samp{armv4t}, -@samp{armv5}, @samp{armv5t}, @samp{armv5e}, @samp{armv5te}, -@samp{armv6}, @samp{armv6j}, -@samp{armv6t2}, @samp{armv6z}, @samp{armv6kz}, @samp{armv6-m}, -@samp{armv7}, @samp{armv7-a}, @samp{armv7-r}, @samp{armv7-m}, @samp{armv7e-m}, +@samp{armv5}, @samp{armv5e}, @samp{armv5t}, @samp{armv5te}, +@samp{armv6}, @samp{armv6-m}, @samp{armv6j}, @samp{armv6k}, +@samp{armv6kz}, @samp{armv6s-m}, +@samp{armv6t2}, @samp{armv6z}, @samp{armv6zk}, +@samp{armv7}, @samp{armv7-a}, @samp{armv7-m}, @samp{armv7-r}, @samp{armv7e-m}, @samp{armv7ve}, @samp{armv8-a}, @samp{armv8-a+crc}, @samp{armv8.1-a}, -@samp{armv8.1-a+crc}, @samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312}. +@samp{armv8.1-a+crc}, @samp{iwmmxt}, @samp{iwmmxt2}. -Architecture revisions older than @option{armv4t} are deprecated. +Architecture revisions older than @samp{armv4t} are deprecated. -@option{-march=armv7ve} is the armv7-a architecture with virtualization +@option{-march=armv6s-m} is the @samp{armv6-m} architecture with support for +the (now mandatory) SVC instruction. + +@option{-march=armv6zk} is an alias for @samp{armv6kz}, existing for backwards +compatibility. + +@option{-march=armv7ve} is the @samp{armv7-a} architecture with virtualization extensions. @option{-march=armv8-a+crc} enables code generation for the ARMv8-A diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0b7ea82c034..26c1435ed0c 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -128,8 +128,6 @@ static tree range_successor (tree); static tree fold_range_test (location_t, enum tree_code, tree, tree, tree); static tree fold_cond_expr_with_comparison (location_t, tree, tree, tree, tree); static tree unextend (tree, int, int, tree); -static tree optimize_minmax_comparison (location_t, enum tree_code, - tree, tree, tree); static tree extract_muldiv (tree, tree, enum tree_code, tree, bool *); static tree extract_muldiv_1 (tree, tree, enum tree_code, tree, bool *); static tree fold_binary_op_with_conditional_arg (location_t, @@ -3904,13 +3902,24 @@ optimize_bit_field_compare (location_t loc, enum tree_code code, return 0; } + /* Don't use a larger mode for reading the bit field than we will + use in other places accessing the bit field. */ + machine_mode largest_mode = word_mode; + if (TREE_CODE (lhs) == COMPONENT_REF) + { + tree field = TREE_OPERAND (lhs, 1); + tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field); + if (repr) + largest_mode = DECL_MODE (repr); + } + /* See if we can find a mode to refer to this field. We should be able to, but fail if we can't. */ nmode = get_best_mode (lbitsize, lbitpos, 0, 0, const_p ? TYPE_ALIGN (TREE_TYPE (linner)) : MIN (TYPE_ALIGN (TREE_TYPE (linner)), TYPE_ALIGN (TREE_TYPE (rinner))), - word_mode, false); + largest_mode, false); if (nmode == VOIDmode) return 0; @@ -5968,110 +5977,6 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type, const_binop (BIT_IOR_EXPR, l_const, r_const)); } -/* Optimize T, which is a comparison of a MIN_EXPR or MAX_EXPR with a - constant. */ - -static tree -optimize_minmax_comparison (location_t loc, enum tree_code code, tree type, - tree op0, tree op1) -{ - tree arg0 = op0; - enum tree_code op_code; - tree comp_const; - tree minmax_const; - int consts_equal, consts_lt; - tree inner; - - STRIP_SIGN_NOPS (arg0); - - op_code = TREE_CODE (arg0); - minmax_const = TREE_OPERAND (arg0, 1); - comp_const = fold_convert_loc (loc, TREE_TYPE (arg0), op1); - consts_equal = tree_int_cst_equal (minmax_const, comp_const); - consts_lt = tree_int_cst_lt (minmax_const, comp_const); - inner = TREE_OPERAND (arg0, 0); - - /* If something does not permit us to optimize, return the original tree. */ - if ((op_code != MIN_EXPR && op_code != MAX_EXPR) - || TREE_CODE (comp_const) != INTEGER_CST - || TREE_OVERFLOW (comp_const) - || TREE_CODE (minmax_const) != INTEGER_CST - || TREE_OVERFLOW (minmax_const)) - return NULL_TREE; - - /* Now handle all the various comparison codes. We only handle EQ_EXPR - and GT_EXPR, doing the rest with recursive calls using logical - simplifications. */ - switch (code) - { - case NE_EXPR: case LT_EXPR: case LE_EXPR: - { - tree tem - = optimize_minmax_comparison (loc, - invert_tree_comparison (code, false), - type, op0, op1); - if (tem) - return invert_truthvalue_loc (loc, tem); - return NULL_TREE; - } - - case GE_EXPR: - return - fold_build2_loc (loc, TRUTH_ORIF_EXPR, type, - optimize_minmax_comparison - (loc, EQ_EXPR, type, arg0, comp_const), - optimize_minmax_comparison - (loc, GT_EXPR, type, arg0, comp_const)); - - case EQ_EXPR: - if (op_code == MAX_EXPR && consts_equal) - /* MAX (X, 0) == 0 -> X <= 0 */ - return fold_build2_loc (loc, LE_EXPR, type, inner, comp_const); - - else if (op_code == MAX_EXPR && consts_lt) - /* MAX (X, 0) == 5 -> X == 5 */ - return fold_build2_loc (loc, EQ_EXPR, type, inner, comp_const); - - else if (op_code == MAX_EXPR) - /* MAX (X, 0) == -1 -> false */ - return omit_one_operand_loc (loc, type, integer_zero_node, inner); - - else if (consts_equal) - /* MIN (X, 0) == 0 -> X >= 0 */ - return fold_build2_loc (loc, GE_EXPR, type, inner, comp_const); - - else if (consts_lt) - /* MIN (X, 0) == 5 -> false */ - return omit_one_operand_loc (loc, type, integer_zero_node, inner); - - else - /* MIN (X, 0) == -1 -> X == -1 */ - return fold_build2_loc (loc, EQ_EXPR, type, inner, comp_const); - - case GT_EXPR: - if (op_code == MAX_EXPR && (consts_equal || consts_lt)) - /* MAX (X, 0) > 0 -> X > 0 - MAX (X, 0) > 5 -> X > 5 */ - return fold_build2_loc (loc, GT_EXPR, type, inner, comp_const); - - else if (op_code == MAX_EXPR) - /* MAX (X, 0) > -1 -> true */ - return omit_one_operand_loc (loc, type, integer_one_node, inner); - - else if (op_code == MIN_EXPR && (consts_equal || consts_lt)) - /* MIN (X, 0) > 0 -> false - MIN (X, 0) > 5 -> false */ - return omit_one_operand_loc (loc, type, integer_zero_node, inner); - - else - /* MIN (X, 0) > -1 -> X > -1 */ - return fold_build2_loc (loc, GT_EXPR, type, inner, comp_const); - - default: - return NULL_TREE; - } -} - /* T is an integer expression that is being multiplied, divided, or taken a modulus (CODE says which and what kind of divide or modulus) by a constant C. See if we can eliminate that operation by folding it with @@ -7964,6 +7869,8 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) case VIEW_CONVERT_EXPR: if (TREE_CODE (op0) == MEM_REF) { + if (TYPE_ALIGN (TREE_TYPE (op0)) != TYPE_ALIGN (type)) + type = build_aligned_type (type, TYPE_ALIGN (TREE_TYPE (op0))); tem = fold_build2_loc (loc, MEM_REF, type, TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1)); REF_REVERSE_STORAGE_ORDER (tem) = REF_REVERSE_STORAGE_ORDER (op0); @@ -8708,18 +8615,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type, if (tem) return tem; - /* If this is comparing a constant with a MIN_EXPR or a MAX_EXPR of a - constant, we can simplify it. */ - if (TREE_CODE (arg1) == INTEGER_CST - && (TREE_CODE (arg0) == MIN_EXPR - || TREE_CODE (arg0) == MAX_EXPR) - && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) - { - tem = optimize_minmax_comparison (loc, code, type, op0, op1); - if (tem) - return tem; - } - /* If we are comparing an expression that just has comparisons of two integer values, arithmetic expressions of those comparisons, and constants, we can simplify it. There are only three cases diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b2354e7c203..998255a9bff 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,19 @@ +2016-06-13 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/70673 + * frontend-passes.c (realloc_string_callback): Add a call to + gfc_dep_compare_expr. + +2016-06-11 Dominique d'Humieres <dominiq@lps.ens.fr> + + PR fortran/60751 + * io.c (gfc_resolve_dt): Replace GFC_STD_GNU with GFC_STD_LEGACY. + +2016-06-10 Thomas Schwinge <thomas@codesourcery.com> + + PR c/71381 + * openmp.c (gfc_match_oacc_cache): Add comment. + 2016-06-05 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR fortran/71404 diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 37c42bb5e34..f02a52ace8b 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -45,7 +45,7 @@ static void realloc_strings (gfc_namespace *); static gfc_expr *create_var (gfc_expr *, const char *vname=NULL); static int inline_matmul_assign (gfc_code **, int *, void *); static gfc_code * create_do_loop (gfc_expr *, gfc_expr *, gfc_expr *, - locus *, gfc_namespace *, + locus *, gfc_namespace *, char *vname=NULL); /* How deep we are inside an argument list. */ @@ -108,7 +108,7 @@ static int var_num = 1; enum matrix_case { none=0, A2B2, A2B1, A1B2, A2B2T }; -/* Keep track of the number of expressions we have inserted so far +/* Keep track of the number of expressions we have inserted so far using create_var. */ int n_vars; @@ -142,7 +142,7 @@ gfc_run_passes (gfc_namespace *ns) /* Callback for each gfc_code node invoked from check_realloc_strings. For an allocatable LHS string which also appears as a variable on - the RHS, replace + the RHS, replace a = a(x:y) @@ -175,6 +175,13 @@ realloc_string_callback (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED, if (!gfc_check_dependency (expr1, expr2, true)) return 0; + /* gfc_check_dependency doesn't always pick up identical expressions. + However, eliminating the above sends the compiler into an infinite + loop on valid expressions. Without this check, the gimplifier emits + an ICE for a = a, where a is deferred character length. */ + if (!gfc_dep_compare_expr (expr1, expr2)) + return 0; + current_code = c; inserted_block = NULL; changed_statement = NULL; @@ -422,7 +429,7 @@ cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, return 0; /* We don't do character functions with unknown charlens. */ - if ((*e)->ts.type == BT_CHARACTER + if ((*e)->ts.type == BT_CHARACTER && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT)) return 0; @@ -446,7 +453,7 @@ cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, if ((*e)->rank > 0 && (*e)->shape == NULL && !flag_realloc_lhs) return 0; - + /* Skip the test for pure functions if -faggressive-function-elimination is specified. */ if ((*e)->value.function.esym) @@ -528,7 +535,7 @@ constant_string_length (gfc_expr *e) { res = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind, &e->where); - + mpz_add_ui (res->value.integer, value, 1); mpz_clear (value); return res; @@ -568,7 +575,7 @@ insert_block () /* If the statement has a label, make sure it is transferred to the newly created block. */ - if ((*current_code)->here) + if ((*current_code)->here) { inserted_block->here = (*current_code)->here; (*current_code)->here = NULL; @@ -640,12 +647,12 @@ create_var (gfc_expr * e, const char *vname) for (i=0; i<e->rank; i++) { gfc_expr *p, *q; - + p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind, &(e->where)); mpz_set_si (p->value.integer, 1); symbol->as->lower[i] = p; - + q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind, &(e->where)); mpz_set (q->value.integer, e->shape[i]); @@ -812,7 +819,7 @@ cfe_code (gfc_code **c, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) *walk_subtrees = 0; return 0; } - + return 0; } @@ -1077,8 +1084,8 @@ optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op) } } else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0 - && ! (e->value.function.esym - && (e->value.function.esym->attr.elemental + && ! (e->value.function.esym + && (e->value.function.esym->attr.elemental || e->value.function.esym->attr.allocatable || e->value.function.esym->ts.type != c->expr1->ts.type || e->value.function.esym->ts.kind != c->expr1->ts.kind)) @@ -1104,7 +1111,7 @@ optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op) new_expr = gfc_copy_expr (c->expr1); c->expr2 = e; *rhs = new_expr; - + return true; } @@ -1337,7 +1344,7 @@ optimize_power (gfc_expr *e) "_internal_iand", e->where, 2, op2, gfc_get_int_expr (e->ts.kind, &e->where, 1)); - + ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT, "_internal_ishft", e->where, 2, iand, gfc_get_int_expr (e->ts.kind, @@ -1672,7 +1679,7 @@ optimize_comparison (gfc_expr *e, gfc_intrinsic_op op) case INTRINSIC_EQ: result = eq == 0; break; - + case INTRINSIC_GE: result = eq >= 0; break; @@ -1692,7 +1699,7 @@ optimize_comparison (gfc_expr *e, gfc_intrinsic_op op) case INTRINSIC_LT: result = eq < 0; break; - + default: gfc_internal_error ("illegal OP in optimize_comparison"); break; @@ -1876,12 +1883,12 @@ doloop_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED, FOR_EACH_VEC_ELT (doloop_list, i, cl) { gfc_symbol *do_sym; - + if (cl == NULL) break; do_sym = cl->ext.iterator->var->symtree->n.sym; - + if (a->expr && a->expr->symtree && a->expr->symtree->n.sym == do_sym) { @@ -1953,7 +1960,7 @@ do_function (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, break; do_sym = dl->ext.iterator->var->symtree->n.sym; - + if (a->expr && a->expr->symtree && a->expr->symtree->n.sym == do_sym) { @@ -2184,7 +2191,7 @@ runtime_error_ne (gfc_expr *e1, gfc_expr *e2, const char *msg) /* Handle matrix reallocation. Caller is responsible to insert into the code tree. - For the two-dimensional case, build + For the two-dimensional case, build if (allocated(c)) then if (size(c,1) /= size(a,1) .or. size(c,2) /= size(b,2)) then @@ -2277,7 +2284,7 @@ matmul_lhs_realloc (gfc_expr *c, gfc_expr *a, gfc_expr *b, /* We need two identical allocate statements in two branches of the IF statement. */ - + allocate1 = XCNEW (gfc_code); allocate1->op = EXEC_ALLOCATE; allocate1->ext.alloc.list = gfc_get_alloc (); @@ -2300,7 +2307,7 @@ matmul_lhs_realloc (gfc_expr *c, gfc_expr *a, gfc_expr *b, deallocate->ext.alloc.list->expr = gfc_copy_expr (c); deallocate->next = allocate1; deallocate->loc = c->where; - + if_size_2 = XCNEW (gfc_code); if_size_2->op = EXEC_IF; if_size_2->expr1 = cond; @@ -2580,7 +2587,7 @@ scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index) /* Loop over the indices. For each index, create the expression index * stride + lbound(e, dim). */ - + i_index = 0; for (i=0; i < ar->dimen; i++) { @@ -2590,9 +2597,9 @@ scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index) { gfc_expr *lbound, *nindex; gfc_expr *loopvar; - - loopvar = gfc_copy_expr (index[i_index]); - + + loopvar = gfc_copy_expr (index[i_index]); + if (ar->stride[i]) { gfc_expr *tmp; @@ -2610,7 +2617,7 @@ scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index) } else nindex = loopvar; - + /* Calculate the lower bound of the expression. */ if (ar->start[i]) { @@ -2677,12 +2684,12 @@ scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index) i + 1); gfc_free_expr (lbound_e); } - + ar->dimen_type[i] = DIMEN_ELEMENT; gfc_free_expr (ar->start[i]); ar->start[i] = get_operand (INTRINSIC_PLUS, nindex, lbound); - + gfc_free_expr (ar->end[i]); ar->end[i] = NULL; gfc_free_expr (ar->stride[i]); @@ -2781,7 +2788,7 @@ check_conjg_transpose_variable (gfc_expr *e, bool *conjg, bool *transpose) end do end do END BLOCK - + */ static int @@ -3213,7 +3220,7 @@ inline_matmul_assign (gfc_code **c, int *walk_subtrees, matrix_a->where, 1, ascalar); if (conjg_b) - bscalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg", + bscalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg", matrix_b->where, 1, bscalar); /* First loop comes after the zero assignment. */ @@ -3586,7 +3593,7 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn, /* This goto serves as a shortcut to avoid code duplication or a larger if or switch statement. */ goto check_omp_clauses; - + case EXEC_OMP_WORKSHARE: case EXEC_OMP_PARALLEL_WORKSHARE: diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index d538d845033..7c648e93cad 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -3007,7 +3007,7 @@ gfc_resolve_dt (gfc_dt *dt, locus *loc) } if (dt->extra_comma - && !gfc_notify_std (GFC_STD_GNU, "Comma before i/o item list at %L", + && !gfc_notify_std (GFC_STD_LEGACY, "Comma before i/o item list at %L", &dt->extra_comma->where)) return false; diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 2689d302c77..2c9279401a2 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -1688,6 +1688,10 @@ match gfc_match_oacc_cache (void) { gfc_omp_clauses *c = gfc_get_omp_clauses (); + /* The OpenACC cache directive explicitly only allows "array elements or + subarrays", which we're currently not checking here. Either check this + after the call of gfc_match_omp_variable_list, or add something like a + only_sections variant next to its allow_sections parameter. */ match m = gfc_match_omp_variable_list (" (", &c->lists[OMP_LIST_CACHE], true, NULL, NULL, true); diff --git a/gcc/ggc-tests.c b/gcc/ggc-tests.c new file mode 100644 index 00000000000..7f972314981 --- /dev/null +++ b/gcc/ggc-tests.c @@ -0,0 +1,525 @@ +/* Unit tests for GCC's garbage collector (and gengtype etc). + Copyright (C) 2015-2016 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tree-core.h" +#include "tree.h" +#include "ggc-internal.h" /* (for ggc_force_collect). */ +#include "selftest.h" + +#if CHECKING_P + +/* The various GTY markers must be outside of a namespace to be seen by + gengtype, so we don't put this file within the selftest namespace. */ + +/* A helper function for writing ggc tests. */ + +static void +forcibly_ggc_collect () +{ + ggc_force_collect = true; + ggc_collect (); + ggc_force_collect = false; +} + + + +/* Verify that a simple struct works, and that it can + own references to non-roots, and have them be marked. */ + +struct GTY(()) test_struct +{ + struct test_struct *other; +}; + +static GTY(()) test_struct *root_test_struct; + +static void +test_basic_struct () +{ + root_test_struct = ggc_cleared_alloc <test_struct> (); + root_test_struct->other = ggc_cleared_alloc <test_struct> (); + + forcibly_ggc_collect (); + + ASSERT_TRUE (ggc_marked_p (root_test_struct)); + ASSERT_TRUE (ggc_marked_p (root_test_struct->other)); +} + + + +/* Selftest for GTY((length)). */ + +/* A test struct using GTY((length)). */ + +struct GTY(()) test_of_length +{ + int num_elem; + struct test_of_length * GTY ((length ("%h.num_elem"))) elem[1]; +}; + +static GTY(()) test_of_length *root_test_of_length; + +static void +test_length () +{ + const int count = 5; + size_t sz = sizeof (test_of_length) + (count- 1) * sizeof (test_of_length *); + root_test_of_length = (test_of_length *)ggc_internal_cleared_alloc (sz); + root_test_of_length->num_elem = count; + for (int i = 0; i < count; i++) + root_test_of_length->elem[i] = ggc_cleared_alloc <test_of_length> (); + + forcibly_ggc_collect (); + + ASSERT_TRUE (ggc_marked_p (root_test_of_length)); + for (int i = 0; i < count; i++) + ASSERT_TRUE (ggc_marked_p (root_test_of_length->elem[i])); +} + + + +/* Selftest for unions, GTY((tag)), and GTY((desc)). */ + +/* A struct with a reference that's an a different offset to test_struct, + to ensure that we're using the correct types. */ + +struct GTY(()) test_other +{ + char dummy[256]; + test_struct *m_ptr; +}; + +enum which_field +{ + WHICH_FIELD_USE_TEST_STRUCT, + WHICH_FIELD_USE_TEST_OTHER +}; + +/* An example function for use by a GTY((desc)) marker. */ + +static enum which_field +calc_desc (int kind) +{ + switch (kind) + { + case 0: return WHICH_FIELD_USE_TEST_STRUCT; + case 1: return WHICH_FIELD_USE_TEST_OTHER; + default: + gcc_unreachable (); + } +} + +/* A struct containing an example of a union, showing the "tag" and + "desc" markers. */ + +struct GTY(()) test_of_union +{ + int m_kind; + union u { + test_struct * GTY ((tag ("WHICH_FIELD_USE_TEST_STRUCT") )) u_test_struct; + test_other * GTY ((tag ("WHICH_FIELD_USE_TEST_OTHER") )) u_test_other; + } GTY ((desc ("calc_desc (%0.m_kind)"))) m_u; +}; + +/* Example roots. */ + +static GTY(()) test_of_union *root_test_of_union_1; +static GTY(()) test_of_union *root_test_of_union_2; + +/* Verify that the above work correctly. */ + +static void +test_union () +{ + root_test_of_union_1 = ggc_cleared_alloc <test_of_union> (); + root_test_of_union_1->m_kind = 0; + test_struct *ts = ggc_cleared_alloc <test_struct> (); + root_test_of_union_1->m_u.u_test_struct = ts; + + root_test_of_union_2 = ggc_cleared_alloc <test_of_union> (); + root_test_of_union_2->m_kind = 1; + test_other *other = ggc_cleared_alloc <test_other> (); + root_test_of_union_2->m_u.u_test_other = other; + test_struct *referenced_by_other = ggc_cleared_alloc <test_struct> (); + other->m_ptr = referenced_by_other; + + forcibly_ggc_collect (); + + ASSERT_TRUE (ggc_marked_p (root_test_of_union_1)); + ASSERT_TRUE (ggc_marked_p (ts)); + + ASSERT_TRUE (ggc_marked_p (root_test_of_union_2)); + ASSERT_TRUE (ggc_marked_p (other)); + ASSERT_TRUE (ggc_marked_p (referenced_by_other)); +} + + + +/* Verify that destructors get run when instances are collected. */ + +struct GTY(()) test_struct_with_dtor +{ + /* This struct has a destructor; it *ought* to be called + by the ggc machinery when instances are collected. */ + ~test_struct_with_dtor () { dtor_call_count++; } + + static int dtor_call_count; +}; + +int test_struct_with_dtor::dtor_call_count; + +static void +test_finalization () +{ +#if GCC_VERSION >= 4003 + ASSERT_FALSE (need_finalization_p <test_struct> ()); + ASSERT_TRUE (need_finalization_p <test_struct_with_dtor> ()); +#endif + + /* Create some garbage. */ + const int count = 10; + for (int i = 0; i < count; i++) + ggc_cleared_alloc <test_struct_with_dtor> (); + + test_struct_with_dtor::dtor_call_count = 0; + + forcibly_ggc_collect (); + + /* Verify that the destructor was run for each instance. */ + ASSERT_EQ (count, test_struct_with_dtor::dtor_call_count); +} + + + +/* Verify that a global can be marked as "deletable". */ + +static GTY((deletable)) test_struct *test_of_deletable; + +static void +test_deletable_global () +{ + test_of_deletable = ggc_cleared_alloc <test_struct> (); + ASSERT_TRUE (test_of_deletable != NULL); + + forcibly_ggc_collect (); + + ASSERT_EQ (NULL, test_of_deletable); +} + + + +/* Verify that gengtype etc can cope with inheritance. */ + +class GTY((desc("%h.m_kind"), tag("0"))) example_base +{ + public: + example_base () + : m_kind (0), + m_a (ggc_cleared_alloc <test_struct> ()) + {} + + void * + operator new (size_t sz) + { + return ggc_internal_cleared_alloc (sz); + } + + protected: + example_base (int kind) + : m_kind (kind), + m_a (ggc_cleared_alloc <test_struct> ()) + {} + + public: + int m_kind; + test_struct *m_a; +}; + +class GTY((tag("1"))) some_subclass : public example_base +{ + public: + some_subclass () + : example_base (1), + m_b (ggc_cleared_alloc <test_struct> ()) + {} + + test_struct *m_b; +}; + +class GTY((tag("2"))) some_other_subclass : public example_base +{ + public: + some_other_subclass () + : example_base (2), + m_c (ggc_cleared_alloc <test_struct> ()) + {} + + test_struct *m_c; +}; + +/* Various test roots, both expressed as a ptr to the actual class, and + as a ptr to the base class. */ +static GTY(()) example_base *test_example_base; +static GTY(()) some_subclass *test_some_subclass; +static GTY(()) some_other_subclass *test_some_other_subclass; +static GTY(()) example_base *test_some_subclass_as_base_ptr; +static GTY(()) example_base *test_some_other_subclass_as_base_ptr; + +static void +test_inheritance () +{ + test_example_base = new example_base (); + test_some_subclass = new some_subclass (); + test_some_other_subclass = new some_other_subclass (); + test_some_subclass_as_base_ptr = new some_subclass (); + test_some_other_subclass_as_base_ptr = new some_other_subclass (); + + forcibly_ggc_collect (); + + /* Verify that the roots and everything referenced by them got marked + (both for fields in the base class and those in subclasses). */ + ASSERT_TRUE (ggc_marked_p (test_example_base)); + ASSERT_TRUE (ggc_marked_p (test_example_base->m_a)); + + ASSERT_TRUE (ggc_marked_p (test_some_subclass)); + ASSERT_TRUE (ggc_marked_p (test_some_subclass->m_a)); + ASSERT_TRUE (ggc_marked_p (test_some_subclass->m_b)); + + ASSERT_TRUE (ggc_marked_p (test_some_other_subclass)); + ASSERT_TRUE (ggc_marked_p (test_some_other_subclass->m_a)); + ASSERT_TRUE (ggc_marked_p (test_some_other_subclass->m_c)); + + ASSERT_TRUE (ggc_marked_p (test_some_subclass_as_base_ptr)); + ASSERT_TRUE (ggc_marked_p (test_some_subclass_as_base_ptr->m_a)); + ASSERT_TRUE (ggc_marked_p (((some_subclass *) + test_some_subclass_as_base_ptr)->m_b)); + + ASSERT_TRUE (ggc_marked_p (test_some_other_subclass_as_base_ptr)); + ASSERT_TRUE (ggc_marked_p (test_some_other_subclass_as_base_ptr->m_a)); + ASSERT_TRUE (ggc_marked_p (((some_other_subclass *) + test_some_other_subclass_as_base_ptr)->m_c)); +} + + + +/* Test of chain_next/chain_prev + + Construct a very long linked list, so that without + the chain_next/chain_prev optimization we'd have + a stack overflow when gt_ggc_mx_test_node recurses. */ + +struct GTY(( chain_next ("%h.m_next"), + chain_prev ("%h.m_prev") )) test_node +{ + test_node *m_prev; + test_node *m_next; + int m_idx; +}; + +static GTY(()) test_node *root_test_node; + +static void +test_chain_next () +{ + /* Ideally we would construct a long list so that the number of + stack frames would be deep enough to crash if gengtype has created + something that recurses. + + However, as the list is lengthened to increase the chance of + overflowing the stack, the test will require more time and memory + to run. On a Fedora 20 x86_64 box with 128GB of RAM, count=2000000 + without the chain_next optimization reliably overflowed the stack, + but the test took 0.5s to run. + + For now this test runs with a low value for "count", which defeats + the main purpose of the test - though it at least gives us coverage + for walking a GTY((chain_next)) list. + + We could potentially increase this value once we have a better sense + of the time and space requirements of the test on different hosts, + or perhaps find a way to reduce the stack size when running this + testcase. */ + const int count = 10; + + /* Build the linked list. */ + root_test_node = ggc_cleared_alloc <test_node> (); + test_node *tail_node = root_test_node; + for (int i = 0; i < count; i++) + { + test_node *new_node = ggc_cleared_alloc <test_node> (); + tail_node->m_next = new_node; + new_node->m_prev = tail_node; + new_node->m_idx = i; + tail_node = new_node; + } + + forcibly_ggc_collect (); + + /* If we got here, we survived. */ + + /* Verify that all nodes in the list were marked. */ + ASSERT_TRUE (ggc_marked_p (root_test_node)); + test_node *iter_node = root_test_node->m_next; + for (int i = 0; i < count; i++) + { + ASSERT_TRUE (ggc_marked_p (iter_node)); + ASSERT_EQ (i, iter_node->m_idx); + iter_node = iter_node->m_next; + } +} + + + +/* Test for GTY((user)). */ + +struct GTY((user)) user_struct +{ + char dummy[16]; + test_struct *m_ptr; +}; + +static GTY(()) user_struct *root_user_struct_ptr; + +/* A global for verifying that the user-provided gt_ggc_mx gets + called. */ +static int num_calls_to_user_gt_ggc_mx; + +/* User-provided implementation of gt_ggc_mx. */ + +static void +gt_ggc_mx (user_struct *p) +{ + num_calls_to_user_gt_ggc_mx++; + gt_ggc_mx_test_struct (p->m_ptr); +} + +/* User-provided implementation of gt_pch_nx. */ + +static void +gt_pch_nx (user_struct *p) +{ + gt_pch_nx_test_struct (p->m_ptr); +} + +/* User-provided implementation of gt_pch_nx. */ + +static void +gt_pch_nx (user_struct *p, gt_pointer_operator op, void *cookie) +{ + op (&(p->m_ptr), cookie); +} + +/* Verify that GTY((user)) works. */ + +static void +test_user_struct () +{ + root_user_struct_ptr = ggc_cleared_alloc <user_struct> (); + test_struct *referenced = ggc_cleared_alloc <test_struct> (); + root_user_struct_ptr->m_ptr = referenced; + + num_calls_to_user_gt_ggc_mx = 0; + + forcibly_ggc_collect (); + + ASSERT_TRUE (ggc_marked_p (root_user_struct_ptr)); + ASSERT_TRUE (ggc_marked_p (referenced)); + ASSERT_TRUE (num_calls_to_user_gt_ggc_mx > 0); +} + + + +/* Smoketest to ensure that the tree type is marked. */ + +static GTY(()) tree dummy_unittesting_tree; + +static void +test_tree_marking () +{ + dummy_unittesting_tree = build_int_cst (integer_type_node, 1066); + + forcibly_ggc_collect (); + + ASSERT_TRUE (ggc_marked_p (dummy_unittesting_tree)); +} + + + +/* Ideas for other tests: + - pch-handling */ + +namespace selftest { + +/* Run all of the selftests within this file. */ + +void +ggc_tests_c_tests () +{ + test_basic_struct (); + test_length (); + test_union (); + test_finalization (); + test_deletable_global (); + test_inheritance (); + test_chain_next (); + test_user_struct (); + test_tree_marking (); +} + +} // namespace selftest + +#include "gt-ggc-tests.h" + +#else /* #if CHECKING_P */ + +/* The #if CHECKING_P code above has various GTY-marked roots. + gengtype has no knowledge of the preprocessor, and so detects + these roots and writes them out to gt-ggc-tests.h. + In a !CHECKING_P build we can ignore gt-ggc-tests.h, but the + root tables are referenced in the various generated gtype-*.c + files like this: + + ...snip... + extern const struct ggc_root_tab gt_ggc_r_gt_ggc_tests_h[]; + ...snip... + + EXPORTED_CONST struct ggc_root_tab * const gt_ggc_rtab[] = { + ...snip... + gt_ggc_r_gt_ggc_tests_h, + ...snip... + }; + + Hence to avoid a link failure, we provide dummy implementations + of these root tables in an unchecked build. + + Note that these conditional roots imply that PCH files are + incompatible between checked and unchecked builds. */ + +EXPORTED_CONST struct ggc_root_tab gt_ggc_r_gt_ggc_tests_h[] = { + LAST_GGC_ROOT_TAB +}; + +EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_gt_ggc_tests_h[] = { + LAST_GGC_ROOT_TAB +}; + +#endif /* #else clause of #if CHECKING_P */ diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 600aa72f217..885367e9114 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -1020,14 +1020,20 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi, gimple *new_stmt; if (is_gimple_reg_type (TREE_TYPE (srcvar))) { - new_stmt = gimple_build_assign (NULL_TREE, srcvar); - if (gimple_in_ssa_p (cfun)) - srcvar = make_ssa_name (TREE_TYPE (srcvar), new_stmt); - else - srcvar = create_tmp_reg (TREE_TYPE (srcvar)); - gimple_assign_set_lhs (new_stmt, srcvar); - gimple_set_vuse (new_stmt, gimple_vuse (stmt)); - gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); + tree tem = fold_const_aggregate_ref (srcvar); + if (tem) + srcvar = tem; + if (! is_gimple_min_invariant (srcvar)) + { + new_stmt = gimple_build_assign (NULL_TREE, srcvar); + if (gimple_in_ssa_p (cfun)) + srcvar = make_ssa_name (TREE_TYPE (srcvar), new_stmt); + else + srcvar = create_tmp_reg (TREE_TYPE (srcvar)); + gimple_assign_set_lhs (new_stmt, srcvar); + gimple_set_vuse (new_stmt, gimple_vuse (stmt)); + gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); + } } new_stmt = gimple_build_assign (destvar, srcvar); gimple_set_vuse (new_stmt, gimple_vuse (stmt)); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index f12c6a11456..ae8b4fcce3c 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1559,6 +1559,73 @@ gimplify_statement_list (tree *expr_p, gimple_seq *pre_p) return GS_ALL_DONE; } +/* Callback for walk_gimple_seq. */ + +static tree +warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, + struct walk_stmt_info *wi) +{ + gimple *stmt = gsi_stmt (*gsi_p); + + *handled_ops_p = true; + switch (gimple_code (stmt)) + { + case GIMPLE_TRY: + /* A compiler-generated cleanup or a user-written try block. + If it's empty, don't dive into it--that would result in + worse location info. */ + if (gimple_try_eval (stmt) == NULL) + { + wi->info = stmt; + return integer_zero_node; + } + /* Fall through. */ + case GIMPLE_BIND: + case GIMPLE_CATCH: + case GIMPLE_EH_FILTER: + case GIMPLE_TRANSACTION: + /* Walk the sub-statements. */ + *handled_ops_p = false; + break; + default: + /* Save the first "real" statement (not a decl/lexical scope/...). */ + wi->info = stmt; + return integer_zero_node; + } + return NULL_TREE; +} + +/* Possibly warn about unreachable statements between switch's controlling + expression and the first case. SEQ is the body of a switch expression. */ + +static void +maybe_warn_switch_unreachable (gimple_seq seq) +{ + if (!warn_switch_unreachable + /* This warning doesn't play well with Fortran when optimizations + are on. */ + || lang_GNU_Fortran () + || seq == NULL) + return; + + struct walk_stmt_info wi; + memset (&wi, 0, sizeof (wi)); + walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi); + gimple *stmt = (gimple *) wi.info; + + if (stmt && gimple_code (stmt) != GIMPLE_LABEL) + { + if (gimple_code (stmt) == GIMPLE_GOTO + && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL + && DECL_ARTIFICIAL (gimple_goto_dest (stmt))) + /* Don't warn for compiler-generated gotos. These occur + in Duff's devices, for example. */; + else + warning_at (gimple_location (stmt), OPT_Wswitch_unreachable, + "statement will never be executed"); + } +} + /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can branch to. */ @@ -1596,39 +1663,8 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p) gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq); - /* Possibly warn about unreachable statements between switch's - controlling expression and the first case. */ - if (warn_switch_unreachable - /* This warning doesn't play well with Fortran when optimizations - are on. */ - && !lang_GNU_Fortran () - && switch_body_seq != NULL) - { - gimple_seq seq = switch_body_seq; - /* Look into the innermost lexical scope. */ - while (gimple_code (seq) == GIMPLE_BIND) - seq = gimple_bind_body (as_a <gbind *> (seq)); - gimple *stmt = gimple_seq_first_stmt (seq); - if (gimple_code (stmt) == GIMPLE_TRY) - { - /* A compiler-generated cleanup or a user-written try block. - Try to get the first statement in its try-block, for better - location. */ - if ((seq = gimple_try_eval (stmt))) - stmt = gimple_seq_first_stmt (seq); - } - if (gimple_code (stmt) != GIMPLE_LABEL) - { - if (gimple_code (stmt) == GIMPLE_GOTO - && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL - && DECL_ARTIFICIAL (gimple_goto_dest (stmt))) - /* Don't warn for compiler-generated gotos. These occur - in Duff's devices, for example. */; - else - warning_at (gimple_location (stmt), OPT_Wswitch_unreachable, - "statement will never be executed"); - } - } + maybe_warn_switch_unreachable (switch_body_seq); + labels = gimplify_ctxp->case_labels; gimplify_ctxp->case_labels = saved_labels; @@ -8280,7 +8316,13 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_AUTO: case OMP_CLAUSE_SEQ: + break; + case OMP_CLAUSE_TILE: + /* We're not yet making use of the information provided by OpenACC + tile clauses. Discard these here, to simplify later middle end + processing. */ + remove = true; break; default: diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 8e0fd0fb63e..b812a02e28e 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -a87af72757d9a2e4479062a459a41d4540398005 +054ff1ece3dd5888a445efeaf3ae197b16d4186f The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index da7b4e0e788..5f7e4c9c0e3 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -11463,7 +11463,7 @@ Selector_expression::lower_method_expression(Gogo* gogo) if (method != NULL && !is_pointer && !method->is_value_method()) { - error_at(location, "method requires pointer (use %<(*%s).%s)%>", + error_at(location, "method requires pointer (use %<(*%s).%s%>)", nt->message_name().c_str(), Gogo::message_name(name).c_str()); return Expression::make_error(location); diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 05fac71409d..4a277db7dcc 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -813,6 +813,10 @@ struct noce_if_info /* Estimated cost of the particular branch instruction. */ unsigned int branch_cost; + + /* The name of the noce transform that succeeded in if-converting + this structure. Used for debugging. */ + const char *transform_name; }; static rtx noce_emit_store_flag (struct noce_if_info *, rtx, int, int); @@ -1116,6 +1120,7 @@ noce_try_move (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); } + if_info->transform_name = "noce_try_move"; return TRUE; } return FALSE; @@ -1148,6 +1153,8 @@ noce_try_ifelse_collapse (struct noce_if_info * if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + + if_info->transform_name = "noce_try_ifelse_collapse"; return TRUE; } @@ -1195,6 +1202,7 @@ noce_try_store_flag (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_store_flag"; return TRUE; } else @@ -1273,6 +1281,7 @@ noce_try_inverse_constants (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_inverse_constants"; return true; } @@ -1493,6 +1502,8 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_store_flag_constants"; + return TRUE; } @@ -1545,6 +1556,8 @@ noce_try_addcc (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_addcc"; + return TRUE; } end_sequence (); @@ -1585,6 +1598,7 @@ noce_try_addcc (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_addcc"; return TRUE; } end_sequence (); @@ -1649,6 +1663,8 @@ noce_try_store_flag_mask (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_store_flag_mask"; + return TRUE; } @@ -1799,6 +1815,8 @@ noce_try_cmove (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_cmove"; + return TRUE; } /* If both a and b are constants try a last-ditch transformation: @@ -1852,6 +1870,7 @@ noce_try_cmove (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_cmove"; return TRUE; } else @@ -2305,6 +2324,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) emit_insn_before_setloc (ifcvt_seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_cmove_arith"; return TRUE; end_seq_and_fail: @@ -2561,6 +2581,7 @@ noce_try_minmax (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->cond = cond; if_info->cond_earliest = earliest; + if_info->transform_name = "noce_try_minmax"; return TRUE; } @@ -2727,6 +2748,7 @@ noce_try_abs (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->cond = cond; if_info->cond_earliest = earliest; + if_info->transform_name = "noce_try_abs"; return TRUE; } @@ -2808,6 +2830,8 @@ noce_try_sign_mask (struct noce_if_info *if_info) return FALSE; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_sign_mask"; + return TRUE; } @@ -2913,6 +2937,7 @@ noce_try_bitop (struct noce_if_info *if_info) emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); } + if_info->transform_name = "noce_try_bitop"; return TRUE; } @@ -3276,6 +3301,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) } num_updated_if_blocks++; + if_info->transform_name = "noce_convert_multiple_sets"; return TRUE; } @@ -3372,7 +3398,12 @@ noce_process_if_block (struct noce_if_info *if_info) && bb_ok_for_noce_convert_multiple_sets (then_bb, if_info)) { if (noce_convert_multiple_sets (if_info)) - return TRUE; + { + if (dump_file && if_info->transform_name) + fprintf (dump_file, "if-conversion succeeded through %s\n", + if_info->transform_name); + return TRUE; + } } if (! bb_valid_for_noce_process_p (then_bb, cond, &if_info->then_cost, @@ -3571,6 +3602,9 @@ noce_process_if_block (struct noce_if_info *if_info) return FALSE; success: + if (dump_file && if_info->transform_name) + fprintf (dump_file, "if-conversion succeeded through %s\n", + if_info->transform_name); /* If we used a temporary, fix it up now. */ if (orig_x != x) diff --git a/gcc/input.c b/gcc/input.c index 0b340a8ed9d..e872cf039f7 100644 --- a/gcc/input.c +++ b/gcc/input.c @@ -1210,7 +1210,7 @@ test_unknown_location () static void test_builtins () { - assert_loceq ("<built-in>", 0, 0, BUILTINS_LOCATION); + assert_loceq (_("<built-in>"), 0, 0, BUILTINS_LOCATION); ASSERT_PRED1 (is_location_from_builtin_token, BUILTINS_LOCATION); } diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index e4e6c8c47eb..bf08dce2e0a 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -2474,14 +2474,27 @@ process_alt_operands (int only_alternative) /* We are trying to spill pseudo into memory. It is usually more costly than moving to a hard register although it might takes the same number of - reloads. */ - if (no_regs_p && REG_P (op) && hard_regno[nop] >= 0) + reloads. + + Non-pseudo spill may happen also. Suppose a target allows both + register and memory in the operand constraint alternatives, + then it's typical that an eliminable register has a substition + of "base + offset" which can either be reloaded by a simple + "new_reg <= base + offset" which will match the register + constraint, or a similar reg addition followed by further spill + to and reload from memory which will match the memory + constraint, but this memory spill will be much more costly + usually. + + Code below increases the reject for both pseudo and non-pseudo + spill. */ + if (no_regs_p && !(REG_P (op) && hard_regno[nop] < 0)) { if (lra_dump_file != NULL) fprintf (lra_dump_file, - " %d Spill pseudo into memory: reject+=3\n", - nop); + " %d Spill %spseudo into memory: reject+=3\n", + nop, REG_P (op) ? "" : "Non-"); reject += 3; if (VECTOR_MODE_P (mode)) { diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 06458d46033..9323a255151 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2016-06-10 Martin Sebor <msebor@redhat.com> + + PR c/71392 + * gcc/lto/lto-lang.c (handle_nonnull_attribute): Accept the nonnull + attribute in type-generic builtins. + 2016-05-16 Jan Hubicka <hubicka@ucw.cz> * lto-partition.c (add_symbol_to_partition_1): Likewise. diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index b5efe3aab7e..301cf2124a6 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -352,10 +352,15 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name), /* If no arguments are specified, all pointer arguments should be non-null. Verify a full prototype is given so that the arguments - will have the correct types when we actually check them later. */ + will have the correct types when we actually check them later. + Avoid diagnosing type-generic built-ins since those have no + prototype. */ if (!args) { - gcc_assert (prototype_p (type)); + gcc_assert (prototype_p (type) + || !TYPE_ATTRIBUTES (type) + || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))); + return NULL_TREE; } diff --git a/gcc/match.pd b/gcc/match.pd index fe711159df9..980b73b9a19 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1312,6 +1312,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (minmax (bit_not:s@2 @0) (bit_not:s@3 @1)) (bit_not (maxmin @0 @1)))) +/* MIN (X, Y) == X -> X <= Y */ +(for minmax (min min max max) + cmp (eq ne eq ne ) + out (le gt ge lt ) + (simplify + (cmp:c (minmax:c @0 @1) @0) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))) + (out @0 @1)))) +/* MIN (X, 5) == 0 -> X == 0 + MIN (X, 5) == 7 -> false */ +(for cmp (eq ne) + (simplify + (cmp (min @0 INTEGER_CST@1) INTEGER_CST@2) + (if (wi::lt_p (@1, @2, TYPE_SIGN (TREE_TYPE (@0)))) + { constant_boolean_node (cmp == NE_EXPR, type); } + (if (wi::gt_p (@1, @2, TYPE_SIGN (TREE_TYPE (@0)))) + (cmp @0 @2))))) +(for cmp (eq ne) + (simplify + (cmp (max @0 INTEGER_CST@1) INTEGER_CST@2) + (if (wi::gt_p (@1, @2, TYPE_SIGN (TREE_TYPE (@0)))) + { constant_boolean_node (cmp == NE_EXPR, type); } + (if (wi::lt_p (@1, @2, TYPE_SIGN (TREE_TYPE (@0)))) + (cmp @0 @2))))) +/* MIN (X, C1) < C2 -> X < C2 || C1 < C2 */ +(for minmax (min min max max min min max max ) + cmp (lt le gt ge gt ge lt le ) + comb (bit_ior bit_ior bit_ior bit_ior bit_and bit_and bit_and bit_and) + (simplify + (cmp (minmax @0 INTEGER_CST@1) INTEGER_CST@2) + (comb (cmp @0 @2) (cmp @1 @2)))) + /* Simplifications of shift and rotates. */ (for rotate (lrotate rrotate) @@ -2626,22 +2658,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && types_match (TREE_TYPE (@0), TREE_TYPE (@1))) (out (imagpart @2) { build_zero_cst (TREE_TYPE (@0)); })))) -/* For unsigned operands, A > -1 / B checks whether A * B would overflow. +/* For unsigned operands, -1 / B < A checks whether A * B would overflow. Simplify it to __builtin_mul_overflow (A, B, <unused>). */ -/* -1 / B < A */ (for cmp (lt ge) out (ne eq) (simplify - (cmp (trunc_div:s integer_all_onesp @1) @0) - (if (TYPE_UNSIGNED (TREE_TYPE (@0)) && !VECTOR_TYPE_P (TREE_TYPE (@0))) - (with { tree t = TREE_TYPE (@0), cpx = build_complex_type (t); } - (out (imagpart (IFN_MUL_OVERFLOW:cpx @0 @1)) { build_zero_cst (t); }))))) - -/* A > -1 / B */ -(for cmp (gt le) - out (ne eq) - (simplify - (cmp @0 (trunc_div:s integer_all_onesp @1)) + (cmp:c (trunc_div:s integer_all_onesp @1) @0) (if (TYPE_UNSIGNED (TREE_TYPE (@0)) && !VECTOR_TYPE_P (TREE_TYPE (@0))) (with { tree t = TREE_TYPE (@0), cpx = build_complex_type (t); } (out (imagpart (IFN_MUL_OVERFLOW:cpx @0 @1)) { build_zero_cst (t); }))))) diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 77bdb1810e6..22e59094e82 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -2187,7 +2187,6 @@ scan_sharing_clauses (tree clauses, omp_context *ctx, case OMP_CLAUSE_GANG: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: - case OMP_CLAUSE_TILE: case OMP_CLAUSE_INDEPENDENT: case OMP_CLAUSE_AUTO: case OMP_CLAUSE_SEQ: @@ -2200,10 +2199,8 @@ scan_sharing_clauses (tree clauses, omp_context *ctx, install_var_local (decl, ctx); break; + case OMP_CLAUSE_TILE: case OMP_CLAUSE__CACHE_: - sorry ("Clause not supported yet"); - break; - default: gcc_unreachable (); } @@ -2360,17 +2357,14 @@ scan_sharing_clauses (tree clauses, omp_context *ctx, case OMP_CLAUSE_GANG: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: - case OMP_CLAUSE_TILE: case OMP_CLAUSE_INDEPENDENT: case OMP_CLAUSE_AUTO: case OMP_CLAUSE_SEQ: case OMP_CLAUSE__GRIDDIM_: break; + case OMP_CLAUSE_TILE: case OMP_CLAUSE__CACHE_: - sorry ("Clause not supported yet"); - break; - default: gcc_unreachable (); } diff --git a/gcc/predict.c b/gcc/predict.c index 837c2f3274f..7d55ff7c71c 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -55,13 +55,29 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-loop.h" #include "tree-scalar-evolution.h" +/* Enum with reasons why a predictor is ignored. */ + +enum predictor_reason +{ + REASON_NONE, + REASON_IGNORED, + REASON_SINGLE_EDGE_DUPLICATE, + REASON_EDGE_PAIR_DUPLICATE +}; + +/* String messages for the aforementioned enum. */ + +static const char *reason_messages[] = {"", " (ignored)", + " (single edge duplicate)", " (edge pair duplicate)"}; + /* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE, 1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */ static sreal real_almost_one, real_br_prob_base, real_inv_br_prob_base, real_one_half, real_bb_freq_max; static void combine_predictions_for_insn (rtx_insn *, basic_block); -static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int); +static void dump_prediction (FILE *, enum br_predictor, int, basic_block, + enum predictor_reason, edge); static void predict_paths_leading_to (basic_block, enum br_predictor, enum prediction); static void predict_paths_leading_to_edge (edge, enum br_predictor, enum prediction); static bool can_predict_insn_p (const rtx_insn *); @@ -609,16 +625,16 @@ gimple_predict_edge (edge e, enum br_predictor predictor, int probability) } } -/* Remove all predictions on given basic block that are attached - to edge E. */ +/* Filter edge predictions PREDS by a function FILTER. DATA are passed + to the filter function. */ + void -remove_predictions_associated_with_edge (edge e) +filter_predictions (edge_prediction **preds, + bool (*filter) (edge_prediction *, void *), void *data) { if (!bb_predictions) return; - edge_prediction **preds = bb_predictions->get (e->src); - if (preds) { struct edge_prediction **prediction = preds; @@ -626,18 +642,39 @@ remove_predictions_associated_with_edge (edge e) while (*prediction) { - if ((*prediction)->ep_edge == e) + if ((*filter) (*prediction, data)) + prediction = &((*prediction)->ep_next); + else { next = (*prediction)->ep_next; free (*prediction); *prediction = next; } - else - prediction = &((*prediction)->ep_next); } } } +/* Filter function predicate that returns true for a edge predicate P + if its edge is equal to DATA. */ + +bool +equal_edge_p (edge_prediction *p, void *data) +{ + return p->ep_edge == (edge)data; +} + +/* Remove all predictions on given basic block that are attached + to edge E. */ +void +remove_predictions_associated_with_edge (edge e) +{ + if (!bb_predictions) + return; + + edge_prediction **preds = bb_predictions->get (e->src); + filter_predictions (preds, equal_edge_p, e); +} + /* Clears the list of predictions stored for BB. */ static void @@ -702,21 +739,31 @@ invert_br_probabilities (rtx insn) static void dump_prediction (FILE *file, enum br_predictor predictor, int probability, - basic_block bb, int used) + basic_block bb, enum predictor_reason reason = REASON_NONE, + edge ep_edge = NULL) { - edge e; + edge e = ep_edge; edge_iterator ei; if (!file) return; - FOR_EACH_EDGE (e, ei, bb->succs) - if (! (e->flags & EDGE_FALLTHRU)) - break; + if (e == NULL) + FOR_EACH_EDGE (e, ei, bb->succs) + if (! (e->flags & EDGE_FALLTHRU)) + break; + + char edge_info_str[128]; + if (ep_edge) + sprintf (edge_info_str, " of edge %d->%d", ep_edge->src->index, + ep_edge->dest->index); + else + edge_info_str[0] = '\0'; - fprintf (file, " %s heuristics%s: %.1f%%", + fprintf (file, " %s heuristics%s%s: %.1f%%", predictor_info[predictor].name, - used ? "" : " (ignored)", probability * 100.0 / REG_BR_PROB_BASE); + edge_info_str, reason_messages[reason], + probability * 100.0 / REG_BR_PROB_BASE); if (bb->count) { @@ -813,18 +860,18 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb) if (!found) dump_prediction (dump_file, PRED_NO_PREDICTION, - combined_probability, bb, true); + combined_probability, bb); else { dump_prediction (dump_file, PRED_DS_THEORY, combined_probability, - bb, !first_match); + bb, !first_match ? REASON_NONE : REASON_IGNORED); dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability, - bb, first_match); + bb, first_match ? REASON_NONE : REASON_IGNORED); } if (first_match) combined_probability = best_probability; - dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true); + dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb); while (*pnote) { @@ -835,7 +882,8 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb) int probability = INTVAL (XEXP (XEXP (*pnote, 0), 1)); dump_prediction (dump_file, predictor, probability, bb, - !first_match || best_predictor == predictor); + (!first_match || best_predictor == predictor) + ? REASON_NONE : REASON_IGNORED); *pnote = XEXP (*pnote, 1); } else @@ -866,6 +914,121 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb) single_succ_edge (bb)->probability = REG_BR_PROB_BASE; } +/* Edge prediction hash traits. */ + +struct predictor_hash: pointer_hash <edge_prediction> +{ + + static inline hashval_t hash (const edge_prediction *); + static inline bool equal (const edge_prediction *, const edge_prediction *); +}; + +/* Calculate hash value of an edge prediction P based on predictor and + normalized probability. */ + +inline hashval_t +predictor_hash::hash (const edge_prediction *p) +{ + inchash::hash hstate; + hstate.add_int (p->ep_predictor); + + int prob = p->ep_probability; + if (prob > REG_BR_PROB_BASE / 2) + prob = REG_BR_PROB_BASE - prob; + + hstate.add_int (prob); + + return hstate.end (); +} + +/* Return true whether edge predictions P1 and P2 use the same predictor and + have equal (or opposed probability). */ + +inline bool +predictor_hash::equal (const edge_prediction *p1, const edge_prediction *p2) +{ + return (p1->ep_predictor == p2->ep_predictor + && (p1->ep_probability == p2->ep_probability + || p1->ep_probability == REG_BR_PROB_BASE - p2->ep_probability)); +} + +struct predictor_hash_traits: predictor_hash, + typed_noop_remove <edge_prediction *> {}; + +/* Return true if edge prediction P is not in DATA hash set. */ + +static bool +not_removed_prediction_p (edge_prediction *p, void *data) +{ + hash_set<edge_prediction *> *remove = (hash_set<edge_prediction *> *) data; + return !remove->contains (p); +} + +/* Prune predictions for a basic block BB. Currently we do following + clean-up steps: + + 1) remove duplicate prediction that is guessed with the same probability + (different than 1/2) to both edge + 2) remove duplicates for a prediction that belongs with the same probability + to a single edge + + */ + +static void +prune_predictions_for_bb (basic_block bb) +{ + edge_prediction **preds = bb_predictions->get (bb); + + if (preds) + { + hash_table <predictor_hash_traits> s (13); + hash_set <edge_prediction *> remove; + + /* Step 1: identify predictors that should be removed. */ + for (edge_prediction *pred = *preds; pred; pred = pred->ep_next) + { + edge_prediction *existing = s.find (pred); + if (existing) + { + if (pred->ep_edge == existing->ep_edge + && pred->ep_probability == existing->ep_probability) + { + /* Remove a duplicate predictor. */ + dump_prediction (dump_file, pred->ep_predictor, + pred->ep_probability, bb, + REASON_SINGLE_EDGE_DUPLICATE, pred->ep_edge); + + remove.add (pred); + } + else if (pred->ep_edge != existing->ep_edge + && pred->ep_probability == existing->ep_probability + && pred->ep_probability != REG_BR_PROB_BASE / 2) + { + /* Remove both predictors as they predict the same + for both edges. */ + dump_prediction (dump_file, existing->ep_predictor, + pred->ep_probability, bb, + REASON_EDGE_PAIR_DUPLICATE, + existing->ep_edge); + dump_prediction (dump_file, pred->ep_predictor, + pred->ep_probability, bb, + REASON_EDGE_PAIR_DUPLICATE, + pred->ep_edge); + + remove.add (existing); + remove.add (pred); + } + } + + edge_prediction **slot2 = s.find_slot (pred, INSERT); + *slot2 = pred; + } + + /* Step 2: Remove predictors. */ + filter_predictions (preds, not_removed_prediction_p, &remove); + } +} + /* Combine predictions into single probability and store them into CFG. Remove now useless prediction entries. If DRY_RUN is set, only produce dumps and do not modify profile. */ @@ -914,7 +1077,10 @@ combine_predictions_for_bb (basic_block bb, bool dry_run) if (dump_file) fprintf (dump_file, "Predictions for bb %i\n", bb->index); + prune_predictions_for_bb (bb); + edge_prediction **preds = bb_predictions->get (bb); + if (preds) { /* We implement "first match" heuristics and use probability guessed @@ -980,18 +1146,18 @@ combine_predictions_for_bb (basic_block bb, bool dry_run) first_match = true; if (!found) - dump_prediction (dump_file, PRED_NO_PREDICTION, combined_probability, bb, true); + dump_prediction (dump_file, PRED_NO_PREDICTION, combined_probability, bb); else { dump_prediction (dump_file, PRED_DS_THEORY, combined_probability, bb, - !first_match); + !first_match ? REASON_NONE : REASON_IGNORED); dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability, bb, - first_match); + first_match ? REASON_NONE : REASON_IGNORED); } if (first_match) combined_probability = best_probability; - dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true); + dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb); if (preds) { @@ -1000,10 +1166,9 @@ combine_predictions_for_bb (basic_block bb, bool dry_run) enum br_predictor predictor = pred->ep_predictor; int probability = pred->ep_probability; - if (pred->ep_edge != EDGE_SUCC (bb, 0)) - probability = REG_BR_PROB_BASE - probability; dump_prediction (dump_file, predictor, probability, bb, - !first_match || best_predictor == predictor); + (!first_match || best_predictor == predictor) + ? REASON_NONE : REASON_IGNORED, pred->ep_edge); } } clear_bb_predictions (bb); @@ -1640,18 +1805,6 @@ predict_loops (void) if (predicted_by_p (bb, PRED_CONTINUE)) continue; - /* Loop branch heuristics - predict an edge back to a - loop's head as taken. */ - if (bb == loop->latch) - { - e = find_edge (loop->latch, loop->header); - if (e) - { - header_found = 1; - predict_edge_def (e, PRED_LOOP_BRANCH, TAKEN); - } - } - /* Loop exit heuristics - predict an edge exiting the loop if the conditional has no loop header successors as not taken. */ if (!header_found diff --git a/gcc/predict.def b/gcc/predict.def index e1c5faee258..c0a3f3684a9 100644 --- a/gcc/predict.def +++ b/gcc/predict.def @@ -88,12 +88,6 @@ DEF_PREDICTOR (PRED_NORETURN, "noreturn call", PROB_VERY_LIKELY, DEF_PREDICTOR (PRED_COLD_FUNCTION, "cold function call", PROB_VERY_LIKELY, PRED_FLAG_FIRST_MATCH) -/* Loopback edge is taken. - FIXME: This is currently disabled because loop_optimizer_init force - loops to have simple latches. */ -DEF_PREDICTOR (PRED_LOOP_BRANCH, "loop branch", HITRATE (86), - PRED_FLAG_FIRST_MATCH) - /* Edge causing loop to terminate is probably not taken. */ DEF_PREDICTOR (PRED_LOOP_EXIT, "loop exit", HITRATE (92), PRED_FLAG_FIRST_MATCH) diff --git a/gcc/pretty-print.c b/gcc/pretty-print.c index d805da4178c..8febda02f9f 100644 --- a/gcc/pretty-print.c +++ b/gcc/pretty-print.c @@ -279,7 +279,7 @@ pp_indent (pretty_printer *pp) %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions. %c: character. %s: string. - %p: pointer. + %p: pointer (printed in a host-dependent manner). %r: if pp_show_color(pp), switch to color identified by const char *. %R: if pp_show_color(pp), reset color. %m: strerror(text->err_no) - does not consume a value from args_ptr. @@ -1317,8 +1317,8 @@ test_pp_format () assert_pp_format ("A 12345678", "%c %x", 'A', 0x12345678); assert_pp_format ("hello world 12345678", "%s %x", "hello world", 0x12345678); - assert_pp_format ("0xcafebabe 12345678", "%p %x", (void *)0xcafebabe, - 0x12345678); + /* We can't test for %p; the pointer is printed in an implementation-defined + manner. */ assert_pp_format ("normal colored normal 12345678", "normal %rcolored%R normal %x", "error", 0x12345678); diff --git a/gcc/profile.c b/gcc/profile.c index 9925bb568c6..4519e7d8558 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-iterator.h" #include "tree-cfg.h" #include "dumpfile.h" +#include "cfgloop.h" #include "profile.h" @@ -1329,9 +1330,21 @@ branch_prob (void) coverage_end_function (lineno_checksum, cfg_checksum); if (flag_branch_probabilities && profile_info) { + struct loop *loop; if (dump_file && (dump_flags & TDF_DETAILS)) report_predictor_hitrates (); profile_status_for_fn (cfun) = PROFILE_READ; + + /* At this moment we have precise loop iteration count estimates. + Record them to loop structure before the profile gets out of date. */ + FOR_EACH_LOOP (loop, 0) + if (loop->header->count) + { + gcov_type nit = expected_loop_iterations_unbounded (loop); + widest_int bound = gcov_type_to_wide_int (nit); + loop->any_estimate = false; + record_niter_bound (loop, bound, true, false); + } compute_function_frequency (); } } diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 89a7a11e0bc..c931349f0f4 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -97,6 +97,9 @@ All implicitly popped input regs must be closer to the top of the reg-stack than any input that is not implicitly popped. + All explicitly referenced input operands may not "skip" a reg. + Otherwise we can have holes in the stack. + 3. It is possible that if an input dies in an insn, reload might use the input reg for an output reload. Consider this example: @@ -461,6 +464,7 @@ check_asm_stack_operands (rtx_insn *insn) char reg_used_as_output[FIRST_PSEUDO_REGISTER]; char implicitly_dies[FIRST_PSEUDO_REGISTER]; + char explicitly_used[FIRST_PSEUDO_REGISTER]; rtx *clobber_reg = 0; int n_inputs, n_outputs; @@ -568,6 +572,7 @@ check_asm_stack_operands (rtx_insn *insn) popped. */ memset (implicitly_dies, 0, sizeof (implicitly_dies)); + memset (explicitly_used, 0, sizeof (explicitly_used)); for (i = n_outputs; i < n_outputs + n_inputs; i++) if (STACK_REG_P (recog_data.operand[i])) { @@ -581,6 +586,8 @@ check_asm_stack_operands (rtx_insn *insn) if (j < n_clobbers || op_alt[i].matches >= 0) implicitly_dies[REGNO (recog_data.operand[i])] = 1; + else if (reg_class_size[(int) op_alt[i].cl] == 1) + explicitly_used[REGNO (recog_data.operand[i])] = 1; } /* Search for first non-popped reg. */ @@ -600,6 +607,23 @@ check_asm_stack_operands (rtx_insn *insn) malformed_asm = 1; } + /* Search for first not-explicitly used reg. */ + for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++) + if (! implicitly_dies[i] && ! explicitly_used[i]) + break; + + /* If there are any other explicitly used regs, that's an error. */ + for (; i < LAST_STACK_REG + 1; i++) + if (explicitly_used[i]) + break; + + if (i != LAST_STACK_REG + 1) + { + error_for_asm (insn, + "explicitly used regs must be grouped at top of stack"); + malformed_asm = 1; + } + /* Enforce rule #3: If any input operand uses the "f" constraint, all output constraints must use the "&" earlyclobber. @@ -607,7 +631,7 @@ check_asm_stack_operands (rtx_insn *insn) record any earlyclobber. */ for (i = n_outputs; i < n_outputs + n_inputs; i++) - if (op_alt[i].matches == -1) + if (STACK_REG_P (recog_data.operand[i]) && op_alt[i].matches == -1) { int j; diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c index e9121b89338..934e700b2e1 100644 --- a/gcc/selftest-run-tests.c +++ b/gcc/selftest-run-tests.c @@ -48,6 +48,7 @@ selftest::run_tests () vec_c_tests (); pretty_print_c_tests (); wide_int_cc_tests (); + ggc_tests_c_tests (); /* Mid-level data structures. */ input_c_tests (); diff --git a/gcc/selftest.h b/gcc/selftest.h index dba4bb7624f..d1f8accfe12 100644 --- a/gcc/selftest.h +++ b/gcc/selftest.h @@ -47,6 +47,7 @@ extern void et_forest_c_tests (); extern void fold_const_c_tests (); extern void function_tests_c_tests (); extern void gimple_c_tests (); +extern void ggc_tests_c_tests (); extern void hash_map_tests_c_tests (); extern void hash_set_tests_c_tests (); extern void input_c_tests (); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 95980f547bd..3e089e759ce 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -564,8 +564,6 @@ default_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, tree vectype, int misalign ATTRIBUTE_UNUSED) { - unsigned elements; - switch (type_of_cost) { case scalar_stmt: @@ -589,8 +587,7 @@ default_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, return 3; case vec_construct: - elements = TYPE_VECTOR_SUBPARTS (vectype); - return elements / 2 + 1; + return TYPE_VECTOR_SUBPARTS (vectype) - 1; default: gcc_unreachable (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6c78af3a7f6..d0dc9b7bc1d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,311 @@ +2016-06-13 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/71478 + * gcc.dg/pr71478.c: Remove dg-require-effective-target vect_int. + Add -Wno-psabi -w to dg-options. + +2016-06-13 Kelvin Nilsen <kelvin@gcc.gnu.org> + + * gcc.target/powerpc/vadsdu-0.c: New test. + * gcc.target/powerpc/vadsdu-1.c: New test. + * gcc.target/powerpc/vadsdu-2.c: New test. + * gcc.target/powerpc/vadsdu-3.c: New test. + * gcc.target/powerpc/vadsdu-4.c: New test. + * gcc.target/powerpc/vadsdu-5.c: New test. + * gcc.target/powerpc/vadsdub-1.c: New test. + * gcc.target/powerpc/vadsdub-2.c: New test. + * gcc.target/powerpc/vadsduh-1.c: New test. + * gcc.target/powerpc/vadsduh-2.c: New test. + * gcc.target/powerpc/vadsduw-1.c: New test. + * gcc.target/powerpc/vadsduw-2.c: New test. + +2016-06-13 David Malcolm <dmalcolm@redhat.com> + + * gcc.dg/c99-init-2.c (c): Update expected error message. + * gcc.dg/init-bad-8.c (foo): Likewise. + * gcc.dg/spellcheck-fields-3.c: New test case. + +2016-06-13 Martin Liska <mliska@suse.cz> + + * gcc.dg/predict-1.c: Distinguish between "loop iv compare" + and "guess loop iv compared" heuristics. + * gcc.dg/predict-2.c: Likewise. + * gcc.dg/predict-3.c: Likewise. + * gcc.dg/predict-4.c: Likewise. + * gcc.dg/predict-5.c: Likewise. + * gcc.dg/predict-6.c: Likewise. + +2016-06-13 Marek Polacek <polacek@redhat.com> + + PR middle-end/71476 + * c-c++-common/Wswitch-unreachable-4.c: New test. + * gcc.dg/Wswitch-unreachable-2.c: New test. + * g++.dg/tm/jump1.C: Move dg-warning. + +2016-06-13 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/renaming10.ad[sb]: New test. + +2016-06-13 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/70673 + * gfortran.dg/pr70673.f90: New test. + +2016-06-13 Richard Biener <rguenther@suse.de> + + PR middle-end/64516 + * gcc.dg/align-3.c: New testcase. + +2016-06-13 Martin Liska <mliska@suse.cz> + + * gcc.target/i386/pr71458.c: New test. + +2016-06-12 Uros Bizjak <ubizjak@gmail.com> + + PR target/71241 + * testsuite/gcc.dg/torture/float128-nan.c: New test. + +2016-06-12 Dominique d'Humieres <dominiq@lps.ens.fr> + + PR target/60751 + * gfortran.dg/guality/pr41558.f90: Remove extra comma in WRITE + statement. + +2016-06-11 Dominique d'Humieres <dominiq@lps.ens.fr> + + PR target/60751 + * gfortran.dg/comma_IO_extension_1.f90: New test. + * gfortran.dg/comma_IO_extension_2.f90: Likewise. + * gfortran.dg/array_constructor_49.f90: Remove extra comma in WRITE + statement. + * gfortran.dg/graphite/pr38083.f90: Likewise. + * gfortran.dg/integer_exponentiation_6.F90: Likewise and add + missing format. + +2016-06-11 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/case_character.adb: New test. + +2016-06-11 Segher Boessenkool <segher@kernel.crashing.org> + + PR middle-end/71310 + * gcc.target/powerpc/pr71310.c: New testcase. + +2016-06-11 Kugan Vivekanandarajah <kuganv@linaro.org> + + PR middle-end/71478 + * gcc.dg/pr71478.c: New test. + +2016-06-10 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/71494 + * gcc.c-torture/execute/pr71494.c: New test. + + PR c/68657 + * gcc.target/i386/pr68657.c: New test. + + PR inline-asm/68843 + * gcc.target/i386/pr68843-2.c: Add dg-do run and empty dg-options. + (test): Add -masm=intel alternatives. + +2016-06-10 Martin Sebor <msebor@redhat.com> + + PR c/71392 + * c-c++-common/builtin-arith-overflow-1.c: Add test cases. + +2016-06-10 Jeff Law <law@redhat.com> + + PR tree-optimization/71335 + * gcc.c-torture/execute/pr71335.c: New test. + +2016-06-10 David Malcolm <dmalcolm@redhat.com> + + * gcc.dg/plugin/must-tail-call-2.c: Remove all details from + the various "cannot tail-call: " messages. + +2016-06-10 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.target/arm/pr37780_1.c: Use arm_arch_v6t2 effective target + and options. + +2016-06-10 Maxim Ostapenko <m.ostapenko@samsung.com> + + PR sanitizer/71480 + * c-c++-common/asan/pr71480.c: New test. + +2016-06-10 H.J. Lu <hongjiu.lu@intel.com> + + * gcc.dg/guality/pr68037-1.c (ASMNAME): New. + (ASMNAME2): Likewise. + (main): Replace fn in asm statement with ASMNAME ("fn"). + * gcc.dg/guality/pr68037-2.c: Likewise. + * gcc.dg/guality/pr68037-3.c: Likewise. + * gcc.dg/torture/pr68037-1.c: Likewise. + * gcc.dg/torture/pr68037-2.c: Likewise. + * gcc.dg/torture/pr68037-3.c: Likewise. + +2016-06-10 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR inline-asm/68843 + * gcc.target/i386/pr68843-1.c: New test. + * gcc.target/i386/pr68843-2.c: New test. + +2016-06-10 Thomas Schwinge <thomas@codesourcery.com> + Cesar Philippidis <cesar@codesourcery.com> + + PR middle-end/71373 + * gcc.dg/goacc/nested-function-1.c: New file. + * gcc.dg/goacc/nested-function-2.c: Likewise. + * gcc.dg/goacc/pr71373.c: Likewise. + * gfortran.dg/goacc/cray-2.f95: Likewise. + * gfortran.dg/goacc/loop-1-2.f95: Likewise. + * gfortran.dg/goacc/loop-3-2.f95: Likewise. + * gfortran.dg/goacc/cray.f95: Update. + * gfortran.dg/goacc/loop-1.f95: Likewise. + * gfortran.dg/goacc/loop-3.f95: Likewise. + * gfortran.dg/goacc/subroutines.f90: Update, and rename to... + * gfortran.dg/goacc/nested-function-1.f90: ... this new file. + +2016-06-10 Thomas Schwinge <thomas@codesourcery.com> + + * c-c++-common/goacc/combined-directives.c: XFAIL tree scanning + for OpenACC tile clauses. + * gfortran.dg/goacc/combined-directives.f90: Likewise. + + PR c/71381 + * c-c++-common/goacc/cache-1.c: Update. Move invalid usage tests + to... + * c-c++-common/goacc/cache-2.c: ... this new file. + * gfortran.dg/goacc/cache-1.f95: Move invalid usage tests to... + * gfortran.dg/goacc/cache-2.f95: ... this new file. + * gfortran.dg/goacc/coarray.f95: Update OpenACC cache directive + usage. + * gfortran.dg/goacc/cray.f95: Likewise. + * gfortran.dg/goacc/loop-1.f95: Likewise. + +2016-06-10 Alan Hayward <alan.hayward@arm.com> + + PR tree-optimization/71407 + PR tree-optimization/71416 + * gcc.dg/vect/pr71407.c: New + * gcc.dg/vect/pr71416-1.c: New + * gcc.dg/vect/pr71416-2.c: New + +2016-06-10 Richard Biener <rguenther@suse.de> + + PR middle-end/71477 + * gcc.dg/torture/pr71477.c: New testcase. + +2016-06-09 Julia Koval <julia.koval@intel.com> + + * gcc.target/i386/interrupt-12.c: Fix test for -fpic and corei7. + * gcc.target/i386/interrupt-13.c: Likewise. + * gcc.target/i386/interrupt-15.c: Likewise. + * gcc.target/i386/interrupt-14.c: Fix test for -fpic. + * gcc.target/i386/interrupt-24.c: Likewise. + * gcc.target/i386/interrupt-3.c: Fix test for corei7. + * gcc.target/i386/interrupt-9.c: Likewise. + * gcc.target/i386/interrupt-redzone-2.c: Likewise. + +2016-06-09 Martin Sebor <msebor@redhat.com> + + PR c/70883 + * c-c++-common/builtin-arith-overflow-1.c: Adjust diagnostic text. + * gcc.dg/builtin-constant_p-1.c: Same. + * gcc.dg/builtins-error.c: Same. + * gcc.dg/pr70859.c: Same. + +2016-06-09 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> + + * gcc.c-torture/execute/bswap-2.c: Require int32plus. + * gcc.dg/torture/pr68067-1.c: Likewise. + * gcc.dg/torture/pr68067-2.c: Likewise. + +2016-06-09 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> + + * gcc.dg/stack-usage-1.c (SIZE): Consider return address + when setting SIZE. + +2016-06-09 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/71465 + * g++.dg/inherit/crash5.C: New. + Revert: + 2016-06-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/70202 + * g++.dg/inherit/crash5.C: New. + * g++.dg/inherit/virtual1.C: Adjust. + +2016-06-09 Martin Liska <mliska@suse.cz> + + * g++.dg/predict-loop-exit-1.C: Scan for a new dump format. + * g++.dg/predict-loop-exit-2.C: Likewise. + * g++.dg/predict-loop-exit-3.C: Likewise. + * gcc.dg/predict-1.c: Likewise. + * gcc.dg/predict-2.c: Likewise. + * gcc.dg/predict-3.c: Likewise. + * gcc.dg/predict-4.c: Likewise. + * gcc.dg/predict-5.c: Likewise. + * gcc.dg/predict-6.c: Likewise. + * gcc.dg/predict-7.c: Likewise. + +2016-06-09 Richard Biener <rguenther@suse.de> + + PR tree-optimization/71462 + * gcc.dg/torture/pr71462.c: New testcase. + +2016-06-09 Marek Polacek <polacek@redhat.com> + + PR c/65471 + * gcc.dg/c11-generic-3.c: New test. + +2016-06-08 Paolo Carlini <paolo.carlini@oracle.com> + + * g++.dg/init/array42.C: New. + * g++.dg/init/array43.C: Likewise. + * g++.dg/init/array44.C: Likewise. + * g++.dg/init/array45.C: Likewise. + * g++.dg/cpp0x/constexpr-ice10.C: Test column number too. + * g++.dg/cpp0x/constexpr-incomplete1.C: Likewise. + * g++.dg/cpp1y/auto-fn27.C: Likewise. + * g++.dg/gomp/pr35751.C: Likewise. + * g++.dg/init/array23.C: Likewise. + * g++.dg/init/brace2.C: Likewise. + * g++.dg/init/brace6.C: Likewise. + +2016-06-08 Martin Sebor <msebor@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/70507 + PR c/68120 + * c-c++-common/builtin-arith-overflow-1.c: Add test cases. + * c-c++-common/builtin-arith-overflow-2.c: New test. + * g++.dg/ext/builtin-arith-overflow-1.C: New test. + * g++.dg/cpp0x/constexpr-arith-overflow.C: New test. + * g++.dg/cpp1y/constexpr-arith-overflow.C: New test. + +2016-06-08 Jakub Jelinek <jakub@redhat.com> + + PR c++/71442 + * g++.dg/cpp0x/Wunused-variable-1.C: New test. + +2016-06-08 Alan Lawrence <alan.lawrence@arm.com> + + * gcc.target/aarch64/aapcs64/aapcs64.exp: Also execute rec_*.c + * gcc.target/aarch64/aapcs64/rec_align-5.c: New. + * gcc.target/aarch64/aapcs64/rec_align-6.c: New. + * gcc.target/aarch64/aapcs64/rec_align-7.c: New. + * gcc.target/aarch64/aapcs64/rec_align-8.c: New. + * gcc.target/aarch64/aapcs64/rec_align-9.c: New. + * gcc.target/aarch64/aapcs64/test_align-5.c: New. + * gcc.target/aarch64/aapcs64/test_align-6.c: New. + * gcc.target/aarch64/aapcs64/test_align-7.c: New. + * gcc.target/aarch64/aapcs64/test_align-8.c: New. + * gcc.target/aarch64/aapcs64/test_align-9.c: New. + * gcc.target/aarch64/aapcs64/rec_vaarg-1.c: New. + * gcc.target/aarch64/aapcs64/rec_vaarg-2.c: New. + 2016-06-08 Richard Biener <rguenther@suse.de> PR tree-optimization/68558 diff --git a/gcc/testsuite/ChangeLog.meissner b/gcc/testsuite/ChangeLog.meissner index 5edf22bc119..0b96f1e34b2 100644 --- a/gcc/testsuite/ChangeLog.meissner +++ b/gcc/testsuite/ChangeLog.meissner @@ -1,3 +1,7 @@ +2016-06-13 Michael Meissner <meissner@linux.vnet.ibm.com> + + Merge up to 237393. + 2016-06-08 Michael Meissner <meissner@linux.vnet.ibm.com> * gcc.target/powerpc/p9-dimode1.c: New test for allowing DImode in diff --git a/gcc/testsuite/c-c++-common/Wswitch-unreachable-4.c b/gcc/testsuite/c-c++-common/Wswitch-unreachable-4.c new file mode 100644 index 00000000000..e7378a7cf18 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wswitch-unreachable-4.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ + +void +foo (int a, int b) +{ + switch (a) + { + { int c; } + { int d; } + { int e; } + b++; /* { dg-warning "statement will never be executed" } */ + case 1: + break; + } + + switch (a) + { + { int c; } + { int d = 1; } /* { dg-warning "statement will never be executed" } */ + { int e; } + b++; + case 1: + break; + } +} diff --git a/gcc/testsuite/c-c++-common/asan/pr71480.c b/gcc/testsuite/c-c++-common/asan/pr71480.c new file mode 100644 index 00000000000..c23ea5385b4 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pr71480.c @@ -0,0 +1,42 @@ +/* { dg-do run } */ + +__attribute__ ((noinline, noclone)) int +foo (char *c) +{ + asm volatile ("" : : "r" (c) : "memory"); + return 1; +} + +__attribute__ ((noinline, noclone)) void +bar (char *c) +{ + asm volatile ("" : : "r" (c) : "memory"); +} + +int main () +{ + char tpl[20] = "/tmp/test.XXXXXX"; + char tpl2[20] = "/tmp/test.XXXXXX"; + int fd = foo (tpl); + int fd2 = foo (tpl2); + if (fd == -1) + { + if (fd2 != -1) + bar (tpl2); + return 1; + } + + if (fd2 == -1) + return 1; + + bar (tpl); + bar (tpl2); + + if (__builtin_strcmp (tpl, "/tmp/test.XXXXXX") != 0) + return 1; + + if (__builtin_strcmp (tpl, tpl2) != 0) + return 1; + + return 0; +} diff --git a/gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c b/gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c index 69b508386d5..3576748e1ee 100644 --- a/gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c +++ b/gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c @@ -1,11 +1,210 @@ +/* Test exercising invalid calls to arithmetic overflow checking built-ins, + including PR c/71392 - SEGV calling integer overflow built-ins with a null + pointer, (issuing a warning for such invocations). */ /* { dg-do compile } */ +/* { dg-additional-options "-Wnonnull" } + +/* Verify that calls with fewer or more than 3 arguments to the generic + __builtin_op_overflow functions are rejected. */ + +#ifndef __cplusplus +#define bool _Bool +#endif + +int +generic_0 (void) +{ + int x = __builtin_add_overflow (); /* { dg-error "too few arguments to function" } */ + x += __builtin_sub_overflow (); /* { dg-error "too few arguments to function" } */ + x += __builtin_mul_overflow (); /* { dg-error "too few arguments to function" } */ + x += __builtin_add_overflow_p (); /* { dg-error "too few arguments to function" } */ + x += __builtin_sub_overflow_p (); /* { dg-error "too few arguments to function" } */ + x += __builtin_mul_overflow_p (); /* { dg-error "too few arguments to function" } */ + return x; +} + +int +generic_1 (int a) +{ + int x = __builtin_add_overflow (a); /* { dg-error "too few arguments to function" } */ + x += __builtin_sub_overflow (a); /* { dg-error "too few arguments to function" } */ + x += __builtin_mul_overflow (a); /* { dg-error "too few arguments to function" } */ + + /* Literal argument. */ + x += __builtin_add_overflow (1); /* { dg-error "too few arguments to function" } */ + x += __builtin_sub_overflow (2); /* { dg-error "too few arguments to function" } */ + x += __builtin_mul_overflow (3); /* { dg-error "too few arguments to function" } */ + return x; +} + +int +generic_2 (int a, int b) +{ + int x = __builtin_add_overflow (a, b);/* { dg-error "too few arguments to function" } */ + x += __builtin_sub_overflow (a, b); /* { dg-error "too few arguments to function" } */ + x += __builtin_mul_overflow (a, b); /* { dg-error "too few arguments to function" } */ + x += __builtin_add_overflow (a, 1); /* { dg-error "too few arguments to function" } */ + x += __builtin_sub_overflow (a, 2); /* { dg-error "too few arguments to function" } */ + x += __builtin_mul_overflow (a, 3); /* { dg-error "too few arguments to function" } */ + x += __builtin_add_overflow (4, b); /* { dg-error "too few arguments to function" } */ + x += __builtin_sub_overflow (5, b); /* { dg-error "too few arguments to function" } */ + x += __builtin_mul_overflow (6, b); /* { dg-error "too few arguments to function" } */ + return x; +} + +/* Verify that calls with the correct number of arguments to the generic + __builtin_op_overflow functions are accepted. */ + +int +generic_3 (int a, int b, int c) +{ + int x = __builtin_add_overflow (a, b, &c); + x += __builtin_sub_overflow (a, b, &c); + x += __builtin_mul_overflow (a, b, &c); + x += __builtin_add_overflow (a, 1, &c); + x += __builtin_sub_overflow (a, 2, &c); + x += __builtin_mul_overflow (a, 3, &c); + x += __builtin_add_overflow (4, b, &c); + x += __builtin_sub_overflow (5, b, &c); + x += __builtin_mul_overflow (6, b, &c); + x += __builtin_add_overflow (7, 8, &c); + x += __builtin_sub_overflow (9, 10, &c); + x += __builtin_mul_overflow (11, 12, &c); + + /* Verify that a null pointer to an integer is diagnosed. */ + + /* The following two are rejected due to c/71479 - error on + __builtin_add_overflow with bool or enum pointer as last argument. + + x += __builtin_add_overflow (0, 0, (bool *)0); + + enum E { e0 }; + x += __builtin_add_overflow (0, 0, (enum E *)0); + */ + + x += __builtin_sub_overflow (0, 0, (char *)0); /* { dg-warning "null argument" } */ + x += __builtin_add_overflow (0, 0, (short *)0); /* { dg-warning "null argument" } */ + x += __builtin_add_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_sub_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_mul_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_add_overflow (a, 1, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_sub_overflow (a, 2, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_mul_overflow (a, 3, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_add_overflow (4, b, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_sub_overflow (5, b, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_mul_overflow (6, b, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_add_overflow (7, 8, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_sub_overflow (9, 10, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_mul_overflow (11, 12, (int *)0); /* { dg-warning "null argument" } */ + + return x; +} + +int +generic_4 (int a, int b, int *c, int d) +{ + int x = __builtin_add_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */ + x += __builtin_sub_overflow (a, b, c, d, d, d); /* { dg-error "too many arguments to function" } */ + x += __builtin_sub_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */ + x += __builtin_mul_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */ + return x; +} + +/* Verify that calls with fewer or more than 3 arguments to the type + specific forms of the __builtin_op_overflow functions are rejected. */ + +int +generic_wrong_type (int a, int b) +{ + void *p = 0; + double d = 0; + int x = __builtin_add_overflow (a, b, p); /* { dg-error "does not have pointer to integer type" } */ + x += __builtin_sub_overflow (a, b, &p); /* { dg-error "does not have pointer to integer type" } */ + x += __builtin_mul_overflow (a, b, &d); /* { dg-error "does not have pointer to integer type" } */ + + /* Also verify literal arguments. */ + x += __builtin_add_overflow (1, 1, p); /* { dg-error "does not have pointer to integer type" } */ + x += __builtin_sub_overflow (1, 1, &p); /* { dg-error "does not have pointer to integer type" } */ + x += __builtin_mul_overflow (1, 1, &d); /* { dg-error "does not have pointer to integer type" } */ + return x; +} + +/* Verify that calls with fewer than 2 or more than 3 arguments to + the typed __builtin_op_overflow functions are rejected. */ +int +typed_0 (void) +{ + int x = __builtin_add_overflow (); /* { dg-error "too few arguments to function" } */ + x += __builtin_sub_overflow (); /* { dg-error "too few arguments to function" } */ + x += __builtin_mul_overflow (); /* { dg-error "too few arguments to function" } */ + return x; +} + +int +typed_1 (int a) +{ + int x = __builtin_sadd_overflow (a); /* { dg-error "too few arguments to function" } */ + x += __builtin_ssub_overflow (a); /* { dg-error "too few arguments to function" } */ + x += __builtin_smul_overflow (a); /* { dg-error "too few arguments to function" } */ + return x; +} int -f1 (void) +typed_2 (int a, int b) { - int x = __builtin_add_overflow (); /* { dg-error "not enough arguments to function" } */ - x += __builtin_sub_overflow (); /* { dg-error "not enough arguments to function" } */ - x += __builtin_mul_overflow (); /* { dg-error "not enough arguments to function" } */ + int x = __builtin_sadd_overflow (a, b); /* { dg-error "too few arguments to function" } */ + x += __builtin_ssub_overflow (a, b); /* { dg-error "too few arguments to function" } */ + x += __builtin_smul_overflow (a, b); /* { dg-error "too few arguments to function" } */ + return x; +} + +/* Exercise PR c/71392 - SEGV calling integer overflow built-ins with + a null pointer. Verify that calls with a null argument are diagnosed + with -Wnonnull. */ + +int +typed_3_null (int a, int b) +{ + int x = 0; + + x += __builtin_sadd_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_uadd_overflow (a, b, (unsigned *)0); /* { dg-warning "null argument" } */ + + x += __builtin_saddl_overflow (a, b, (long *)0); /* { dg-warning "null argument" } */ + x += __builtin_uaddl_overflow (a, b, (unsigned long *)0); /* { dg-warning "null argument" } */ + + x += __builtin_saddll_overflow (a, b, (long long *)0); /* { dg-warning "null argument" } */ + x += __builtin_uaddll_overflow (a, b, (unsigned long long *)0); /* { dg-warning "null argument" } */ + + + x += __builtin_ssub_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_usub_overflow (a, b, (unsigned *)0); /* { dg-warning "null argument" } */ + + x += __builtin_ssubl_overflow (a, b, (long *)0); /* { dg-warning "null argument" } */ + x += __builtin_usubl_overflow (a, b, (unsigned long *)0); /* { dg-warning "null argument" } */ + + x += __builtin_ssubll_overflow (a, b, (long long *)0); /* { dg-warning "null argument" } */ + x += __builtin_usubll_overflow (a, b, (unsigned long long *)0); /* { dg-warning "null argument" } */ + + + x += __builtin_smul_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */ + x += __builtin_umul_overflow (a, b, (unsigned *)0); /* { dg-warning "null argument" } */ + + x += __builtin_smull_overflow (a, b, (long *)0); /* { dg-warning "null argument" } */ + x += __builtin_umull_overflow (a, b, (unsigned long *)0); /* { dg-warning "null argument" } */ + + x += __builtin_smulll_overflow (a, b, (long long *)0); /* { dg-warning "null argument" } */ + x += __builtin_umulll_overflow (a, b, (unsigned long long *)0); /* { dg-warning "null argument" } */ + + return x; +} + +int +typed_4 (int a, int b, int *c, int d) +{ + int x = __builtin_sadd_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */ + x += __builtin_ssub_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */ + x += __builtin_smul_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */ return x; } @@ -15,15 +214,15 @@ f2 (int a, int b, int *c, int d) int x = __builtin_add_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */ x += __builtin_sub_overflow (a, b, c, d, d, d); /* { dg-error "too many arguments to function" } */ x += __builtin_mul_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */ + x += __builtin_add_overflow_p (a, b, d, d); /* { dg-error "too many arguments to function" } */ + x += __builtin_sub_overflow_p (a, b, d, d, 1, d); /* { dg-error "too many arguments to function" } */ + x += __builtin_mul_overflow_p (a, b, d, d); /* { dg-error "too many arguments to function" } */ + return x; } enum E { e0 = 0, e1 = 1 }; -#ifndef __cplusplus -#define bool _Bool -#endif - int f3 (float fa, int a, _Complex long int ca, double fb, void *pb, int b, enum E eb, bool bb, int *c) { @@ -33,6 +232,15 @@ f3 (float fa, int a, _Complex long int ca, double fb, void *pb, int b, enum E eb x += __builtin_add_overflow (a, pb, c); /* { dg-error "argument 2 in call to function\[^\n\r]*does not have integral type" } */ x += __builtin_sub_overflow (a, eb, c); x += __builtin_mul_overflow (a, bb, c); + x += __builtin_add_overflow_p (fa, b, a); /* { dg-error "argument 1 in call to function\[^\n\r]*does not have integral type" } */ + x += __builtin_sub_overflow_p (ca, b, eb); /* { dg-error "argument 1 in call to function\[^\n\r]*does not have integral type" } */ + x += __builtin_mul_overflow_p (a, fb, bb); /* { dg-error "argument 2 in call to function\[^\n\r]*does not have integral type" } */ + x += __builtin_add_overflow_p (a, pb, a); /* { dg-error "argument 2 in call to function\[^\n\r]*does not have integral type" } */ + x += __builtin_sub_overflow_p (a, eb, eb); + x += __builtin_mul_overflow_p (a, bb, bb); + x += __builtin_add_overflow_p (a, b, fa); /* { dg-error "argument 3 in call to function\[^\n\r]*does not have integral type" } */ + x += __builtin_sub_overflow_p (a, b, ca); /* { dg-error "argument 3 in call to function\[^\n\r]*does not have integral type" } */ + x += __builtin_mul_overflow_p (a, b, c); /* { dg-error "argument 3 in call to function\[^\n\r]*does not have integral type" } */ return x; } diff --git a/gcc/testsuite/c-c++-common/builtin-arith-overflow-2.c b/gcc/testsuite/c-c++-common/builtin-arith-overflow-2.c new file mode 100644 index 00000000000..4cbceff3ed2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/builtin-arith-overflow-2.c @@ -0,0 +1,493 @@ +/* PR c/68120 - can't easily deal with integer overflow at compile time */ +/* { dg-do run } */ +/* { dg-additional-options "-Wno-long-long" } */ + +#define SCHAR_MAX __SCHAR_MAX__ +#define SHRT_MAX __SHRT_MAX__ +#define INT_MAX __INT_MAX__ +#define LONG_MAX __LONG_MAX__ +#define LLONG_MAX __LONG_LONG_MAX__ + +#define SCHAR_MIN (-__SCHAR_MAX__ - 1) +#define SHRT_MIN (-__SHRT_MAX__ - 1) +#define INT_MIN (-__INT_MAX__ - 1) +#define LONG_MIN (-__LONG_MAX__ - 1) +#define LLONG_MIN (-__LONG_LONG_MAX__ - 1) + +#define UCHAR_MAX (SCHAR_MAX * 2U + 1) +#define USHRT_MAX (SHRT_MAX * 2U + 1) +#define UINT_MAX (INT_MAX * 2U + 1) +#define ULONG_MAX (LONG_MAX * 2LU + 1) +#define ULLONG_MAX (LLONG_MAX * 2LLU + 1) + +#define USCHAR_MIN (-__USCHAR_MAX__ - 1) +#define USHRT_MIN (-__USHRT_MAX__ - 1) +#define UINT_MIN (-__UINT_MAX__ - 1) +#define ULONG_MIN (-__ULONG_MAX__ - 1) +#define ULLONG_MIN (-__ULONG_LONG_MAX__ - 1) + +/* Number of failed runtime assertions. */ +int nfails; + +void __attribute__ ((noclone, noinline)) +runtime_assert (int expr, int line) +{ + if (!expr) + { + __builtin_printf ("line %i: assertion failed\n", line); + ++nfails; + } +} + +/* Helper macros for run-time testing. */ +#define add(x, y) ((x) + (y)) +#define sadd(x, y) ((x) + (y)) +#define saddl(x, y) ((x) + (y)) +#define saddll(x, y) ((x) + (y)) +#define uadd(x, y) ((x) + (y)) +#define uaddl(x, y) ((x) + (y)) +#define uaddll(x, y) ((x) + (y)) +#define sub(x, y) ((x) - (y)) +#define ssub(x, y) ((x) - (y)) +#define ssubl(x, y) ((x) - (y)) +#define ssubll(x, y) ((x) - (y)) +#define usub(x, y) ((x) - (y)) +#define usubl(x, y) ((x) - (y)) +#define usubll(x, y) ((x) - (y)) +#define mul(x, y) ((x) * (y)) +#define smul(x, y) ((x) * (y)) +#define smull(x, y) ((x) * (y)) +#define smulll(x, y) ((x) * (y)) +#define umul(x, y) ((x) * (y)) +#define umull(x, y) ((x) * (y)) +#define umulll(x, y) ((x) * (y)) + +int main (void) +{ + +#if __cplusplus >= 201103L +# define StaticAssert(expr) static_assert ((expr), #expr) +#elif __STDC_VERSION__ >= 201112L +# define StaticAssert(expr) _Static_assert ((expr), #expr) +#else + /* The following pragma has no effect due to bug 70888 - #pragma + diagnostic ignored -Wlong-long ineffective with __LONG_LONG_MAX__ + in c++98 mode. */ +# pragma GCC diagnostic ignored "-Wlong-long" +# pragma GCC diagnostic ignored "-Wunused-local-typedefs" + +# define CONCAT(a, b) a ## b +# define CAT(a, b) CONCAT (a, b) +# define StaticAssert(expr) \ + typedef int CAT (StaticAssert_, __LINE__) [1 - 2 * !(expr)] +#endif + + /* Make extra effort to prevent constant folding seeing the constant + values of the arguments and optimizing the run-time test into + a constant. */ +#define RuntimeAssert(op, T, U, x, y, vflow) \ + do { \ + volatile T a = (x), b = (y); \ + U c = 0; \ + volatile int vf = __builtin_ ## op ## _overflow (a, b, &c); \ + runtime_assert ((vf == vflow), __LINE__); \ + if (vf == 0) \ + runtime_assert (op (a, b) == c, __LINE__); \ + } while (0) + + /* Verify that each call to the type-generic __builtin_op_overflow(x, y) + yields a constant expression equal to z indicating whether or not + the constant expression (x op y) overflows when evaluated in type T. */ +# define G_TEST(op, T, x, y, vflow) \ + RuntimeAssert(op, __typeof__ (op (x, y)), T, x, y, vflow); \ + StaticAssert ((vflow) == __builtin_ ## op ## _overflow_p ((x), (y), (T)0)) + + /* Addition. */ + G_TEST (add, signed char, 0, 0, 0); + G_TEST (add, signed char, 0, SCHAR_MAX, 0); + G_TEST (add, signed char, 1, SCHAR_MAX, 1); + G_TEST (add, signed char, SCHAR_MAX, SCHAR_MAX, 1); + G_TEST (add, signed char, 0, SCHAR_MIN, 0); + G_TEST (add, signed char, -1, SCHAR_MIN, 1); + /* Verify any slicing in the result type doesn't prevent the overflow + from being detected. */ + G_TEST (add, signed char, UCHAR_MAX + 1, 0, 1); + G_TEST (add, signed char, UCHAR_MAX + 1, 1, 1); + G_TEST (add, signed char, 1, UCHAR_MAX + 1, 1); + + G_TEST (add, unsigned char, 0, 0, 0); + /* Verify any slicing in the result type doesn't prevent the overflow + from being detected. */ + G_TEST (add, unsigned char, UCHAR_MAX + 1, 0, 1); + G_TEST (add, unsigned char, UCHAR_MAX + 1, 1, 1); + G_TEST (add, unsigned char, 1, UCHAR_MAX + 1, 1); + + G_TEST (add, short, 0, 0, 0); + G_TEST (add, short, 0, SHRT_MAX, 0); + G_TEST (add, short, 1, SHRT_MAX, 1); + G_TEST (add, short, SHRT_MAX, SHRT_MAX, 1); + G_TEST (add, short, 0, SHRT_MIN, 0); + G_TEST (add, short, -1, SHRT_MIN, 1); + G_TEST (add, short, SHRT_MIN, SHRT_MIN, 1); + + G_TEST (add, int, 0, 0, 0); + G_TEST (add, int, 0, INT_MAX, 0); + G_TEST (add, int, 1, INT_MAX, 1); + G_TEST (add, int, INT_MAX, INT_MAX, 1); + G_TEST (add, int, 0, INT_MIN, 0); + G_TEST (add, int, -1, INT_MIN, 1); + G_TEST (add, int, INT_MIN, INT_MIN, 1); + + G_TEST (add, long, 0, 0, 0); + G_TEST (add, long, 0, LONG_MAX, 0); + G_TEST (add, long, 1, LONG_MAX, 1); + G_TEST (add, long, LONG_MAX, LONG_MAX, 1); + G_TEST (add, long, 0, LONG_MIN, 0); + G_TEST (add, long, -1, LONG_MIN, 1); + G_TEST (add, long, LONG_MIN, LONG_MIN, 1); + + G_TEST (add, long long, 0, 0, 0); + G_TEST (add, long long, 0, LLONG_MAX, 0); + G_TEST (add, long long, 1, LLONG_MAX, 1); + G_TEST (add, long long, LLONG_MAX, LLONG_MAX, 1); + G_TEST (add, long long, 0, LLONG_MIN, 0); + G_TEST (add, long long, -1, LLONG_MIN, 1); + G_TEST (add, long long, LLONG_MIN, LLONG_MIN, 1); + + /* Subtraction */ + G_TEST (sub, unsigned char, 0, 0, 0); + G_TEST (sub, unsigned char, 0, UCHAR_MAX, 1); + G_TEST (sub, unsigned char, 1, UCHAR_MAX, 1); + + G_TEST (sub, unsigned char, UCHAR_MAX, UCHAR_MAX, 0); + G_TEST (sub, unsigned short, 0, 0, 0); + G_TEST (sub, unsigned short, 0, USHRT_MAX, 1); + G_TEST (sub, unsigned short, 1, USHRT_MAX, 1); + G_TEST (sub, unsigned short, USHRT_MAX, USHRT_MAX, 0); + + G_TEST (sub, unsigned, 0, 0, 0); + G_TEST (sub, unsigned, 0, UINT_MAX, 1); + G_TEST (sub, unsigned, 1, UINT_MAX, 1); + G_TEST (sub, unsigned, UINT_MAX, UINT_MAX, 0); + + G_TEST (sub, unsigned long, 0, 0, 0); + G_TEST (sub, unsigned long, 0, ULONG_MAX, 1); + G_TEST (sub, unsigned long, 1, ULONG_MAX, 1); + G_TEST (sub, unsigned long, ULONG_MAX, ULONG_MAX, 0); + + G_TEST (sub, unsigned long long, 0, 0, 0); + G_TEST (sub, unsigned long long, 0, ULLONG_MAX, 1); + G_TEST (sub, unsigned long long, 1, ULLONG_MAX, 1); + G_TEST (sub, unsigned long long, ULLONG_MAX, ULLONG_MAX, 0); + + G_TEST (sub, signed char, 0, 0, 0); + G_TEST (sub, signed char, 0, SCHAR_MAX, 0); + G_TEST (sub, signed char, 1, SCHAR_MAX, 0); + G_TEST (sub, signed char, SCHAR_MAX, SCHAR_MAX, 0); + G_TEST (sub, signed char, SCHAR_MIN, 1, 1); + G_TEST (sub, signed char, 0, SCHAR_MIN, 1); + G_TEST (sub, signed char, -1, SCHAR_MIN, 0); + + G_TEST (sub, short, 0, 0, 0); + G_TEST (sub, short, 0, SHRT_MAX, 0); + G_TEST (sub, short, 1, SHRT_MAX, 0); + G_TEST (sub, short, SHRT_MAX, SHRT_MAX, 0); + G_TEST (sub, short, 0, SHRT_MIN, 1); + G_TEST (sub, short, -1, SHRT_MIN, 0); + G_TEST (sub, short, SHRT_MIN, SHRT_MIN, 0); + + G_TEST (sub, int, 0, 0, 0); + G_TEST (sub, int, 0, INT_MAX, 0); + G_TEST (sub, int, 1, INT_MAX, 0); + G_TEST (sub, int, INT_MAX, INT_MAX, 0); + G_TEST (sub, int, 0, INT_MIN, 1); + G_TEST (sub, int, -1, INT_MIN, 0); + G_TEST (sub, int, INT_MIN, INT_MIN, 0); + + G_TEST (sub, long, 0, 0, 0); + G_TEST (sub, long, 0, LONG_MAX, 0); + G_TEST (sub, long, 1, LONG_MAX, 0); + G_TEST (sub, long, LONG_MAX, LONG_MAX, 0); + G_TEST (sub, long, 0, LONG_MIN, 1); + G_TEST (sub, long, -1, LONG_MIN, 0); + G_TEST (sub, long, LONG_MIN, LONG_MIN, 0); + + G_TEST (sub, long long, 0, 0, 0); + G_TEST (sub, long long, 0, LLONG_MAX, 0); + G_TEST (sub, long long, 1, LLONG_MAX, 0); + G_TEST (sub, long long, LLONG_MAX, LLONG_MAX, 0); + G_TEST (sub, long long, 0, LLONG_MIN, 1); + G_TEST (sub, long long, -1, LLONG_MIN, 0); + G_TEST (sub, long long, LLONG_MIN, LLONG_MIN, 0); + + G_TEST (sub, unsigned char, 0, 0, 0); + G_TEST (sub, unsigned char, 0, UCHAR_MAX, 1); + G_TEST (sub, unsigned char, 1, UCHAR_MAX, 1); + G_TEST (sub, unsigned char, UCHAR_MAX, UCHAR_MAX, 0); + + G_TEST (sub, unsigned short, 0, 0, 0); + G_TEST (sub, unsigned short, 0, USHRT_MAX, 1); + G_TEST (sub, unsigned short, 1, USHRT_MAX, 1); + G_TEST (sub, unsigned short, USHRT_MAX, USHRT_MAX, 0); + + G_TEST (sub, unsigned, 0, 0, 0); + G_TEST (sub, unsigned, 0, UINT_MAX, 1); + G_TEST (sub, unsigned, 1, UINT_MAX, 1); + G_TEST (sub, unsigned, UINT_MAX, UINT_MAX, 0); + + G_TEST (sub, unsigned long, 0, 0, 0); + G_TEST (sub, unsigned long, 0, ULONG_MAX, 1); + G_TEST (sub, unsigned long, 1, ULONG_MAX, 1); + G_TEST (sub, unsigned long, ULONG_MAX, ULONG_MAX, 0); + + G_TEST (sub, unsigned long long, 0, 0, 0); + G_TEST (sub, unsigned long long, 0, ULLONG_MAX, 1); + G_TEST (sub, unsigned long long, 1, ULLONG_MAX, 1); + G_TEST (sub, unsigned long long, ULLONG_MAX, ULLONG_MAX, 0); + + /* Multiplication. */ + G_TEST (mul, unsigned char, 0, 0, 0); + G_TEST (mul, unsigned char, 0, UCHAR_MAX, 0); + G_TEST (mul, unsigned char, 1, UCHAR_MAX, 0); + G_TEST (mul, unsigned char, 2, UCHAR_MAX, 1); + G_TEST (mul, unsigned char, UCHAR_MAX, UCHAR_MAX, 1); + + G_TEST (mul, unsigned short, 0, 0, 0); + G_TEST (mul, unsigned short, 0, USHRT_MAX, 0); + G_TEST (mul, unsigned short, 1, USHRT_MAX, 0); + G_TEST (mul, unsigned short, USHRT_MAX, 2, 1); + G_TEST (mul, unsigned short, USHRT_MAX, USHRT_MAX, 1); + + G_TEST (mul, unsigned, 0, 0, 0); + G_TEST (mul, unsigned, 0, UINT_MAX, 0); + G_TEST (mul, unsigned, 1, UINT_MAX, 0); + G_TEST (mul, unsigned, 2, UINT_MAX, 1); + G_TEST (mul, unsigned, UINT_MAX, UINT_MAX, 1); + + G_TEST (mul, unsigned long, 0, 0, 0); + G_TEST (mul, unsigned long, 0, ULONG_MAX, 0); + G_TEST (mul, unsigned long, 1, ULONG_MAX, 0); + G_TEST (mul, unsigned long, 2, ULONG_MAX, 1); + G_TEST (mul, unsigned long, ULONG_MAX, ULONG_MAX, 1); + + G_TEST (mul, unsigned long long, 0, 0, 0); + G_TEST (mul, unsigned long long, 0, ULLONG_MAX, 0); + G_TEST (mul, unsigned long long, 1, ULLONG_MAX, 0); + G_TEST (mul, unsigned long long, 2, ULLONG_MAX, 1); + G_TEST (mul, unsigned long long, ULLONG_MAX, ULLONG_MAX, 1); + + G_TEST (mul, signed char, 0, 0, 0); + G_TEST (mul, signed char, 0, SCHAR_MAX, 0); + G_TEST (mul, signed char, 1, SCHAR_MAX, 0); + G_TEST (mul, signed char, SCHAR_MAX, SCHAR_MAX, 1); + G_TEST (mul, signed char, SCHAR_MIN, 1, 0); + G_TEST (mul, signed char, 0, SCHAR_MIN, 0); + G_TEST (mul, signed char, -1, SCHAR_MIN, 1); + + G_TEST (mul, short, 0, 0, 0); + G_TEST (mul, short, 0, SHRT_MAX, 0); + G_TEST (mul, short, 1, SHRT_MAX, 0); + G_TEST (mul, short, SHRT_MAX, SHRT_MAX, 1); + G_TEST (mul, short, 0, SHRT_MIN, 0); + G_TEST (mul, short, -1, SHRT_MIN, 1); + G_TEST (mul, short, SHRT_MIN, SHRT_MIN, 1); + + G_TEST (mul, int, 0, 0, 0); + G_TEST (mul, int, 0, INT_MAX, 0); + G_TEST (mul, int, 1, INT_MAX, 0); + G_TEST (mul, int, INT_MAX, INT_MAX, 1); + G_TEST (mul, int, 0, INT_MIN, 0); + G_TEST (mul, int, -1, INT_MIN, 1); + G_TEST (mul, int, INT_MIN, INT_MIN, 1); + + G_TEST (mul, long, 0, 0, 0); + G_TEST (mul, long, 0, LONG_MAX, 0); + G_TEST (mul, long, 1, LONG_MAX, 0); + G_TEST (mul, long, LONG_MAX, LONG_MAX, 1); + G_TEST (mul, long, 0, LONG_MIN, 0); + G_TEST (mul, long, -1, LONG_MIN, 1); + G_TEST (mul, long, LONG_MIN, LONG_MIN, 1); + + G_TEST (mul, long long, 0, 0, 0); + G_TEST (mul, long long, 0, LLONG_MAX, 0); + G_TEST (mul, long long, 1, LLONG_MAX, 0); + G_TEST (mul, long long, LLONG_MAX, LLONG_MAX, 1); + G_TEST (mul, long long, 0, LLONG_MIN, 0); + G_TEST (mul, long long, -1, LLONG_MIN, 1); + G_TEST (mul, long long, LLONG_MIN, LLONG_MIN, 1); + + G_TEST (mul, unsigned char, 0, 0, 0); + G_TEST (mul, unsigned char, 0, UCHAR_MAX, 0); + G_TEST (mul, unsigned char, 1, UCHAR_MAX, 0); + G_TEST (mul, unsigned char, UCHAR_MAX, UCHAR_MAX, 1); + + G_TEST (mul, unsigned short, 0, 0, 0); + G_TEST (mul, unsigned short, 0, USHRT_MAX, 0); + G_TEST (mul, unsigned short, 1, USHRT_MAX, 0); + G_TEST (mul, unsigned short, USHRT_MAX, USHRT_MAX, 1); + + G_TEST (mul, unsigned, 0, 0, 0); + G_TEST (mul, unsigned, 0, UINT_MAX, 0); + G_TEST (mul, unsigned, 1, UINT_MAX, 0); + G_TEST (mul, unsigned, UINT_MAX, UINT_MAX, 1); + + G_TEST (mul, unsigned long, 0, 0, 0); + G_TEST (mul, unsigned long, 0, ULONG_MAX, 0); + G_TEST (mul, unsigned long, 1, ULONG_MAX, 0); + G_TEST (mul, unsigned long, ULONG_MAX, ULONG_MAX, 1); + + G_TEST (mul, unsigned long long, 0, 0, 0); + G_TEST (mul, unsigned long long, 0, ULLONG_MAX, 0); + G_TEST (mul, unsigned long long, 1, ULLONG_MAX, 0); + G_TEST (mul, unsigned long long, ULLONG_MAX, ULLONG_MAX, 1); + + /* Verify that each call to the type-specific __builtin_op_overflow + evaluates to a (not-necessarily constant) expression indicating + whether or not the constant expression (x op y) overflows. + The type-specific forms of the built-ins detect overflow after + arithmetic promotions and so unlike the type-generic overloads + cannot detect overflow in char or short types. */ + +#define T_TEST(op, T, x, y, vflow) \ + RuntimeAssert (op, T, __typeof__ ((x) + (y)), x, y, vflow) + + /* Signed int addition. */ + T_TEST (sadd, signed char, 0, 0, 0); + T_TEST (sadd, signed char, 0, SCHAR_MAX, 0); + T_TEST (sadd, signed char, 1, SCHAR_MAX, 0); + T_TEST (sadd, signed char, SCHAR_MAX, SCHAR_MAX, 0); + T_TEST (sadd, signed char, 0, SCHAR_MIN, 0); + T_TEST (sadd, signed char, -1, SCHAR_MIN, 0); + + T_TEST (sadd, short, 0, 0, 0); + T_TEST (sadd, short, 0, SHRT_MAX, 0); + T_TEST (sadd, short, 1, SHRT_MAX, 0); + T_TEST (sadd, short, SHRT_MAX, SHRT_MAX, 0); + T_TEST (sadd, short, 0, SHRT_MIN, 0); + T_TEST (sadd, short, -1, SHRT_MIN, 0); + T_TEST (sadd, short, SHRT_MIN, SHRT_MIN, 0); + + T_TEST (sadd, int, 0, 0, 0); + T_TEST (sadd, int, 0, INT_MAX, 0); + T_TEST (sadd, int, 1, INT_MAX, 1); + T_TEST (sadd, int, INT_MAX, INT_MAX, 1); + T_TEST (sadd, int, 0, INT_MIN, 0); + T_TEST (sadd, int, -1, INT_MIN, 1); + T_TEST (sadd, int, INT_MIN, INT_MIN, 1); + + /* Signed long addition. */ + T_TEST (saddl, long, 0L, 0L, 0); + T_TEST (saddl, long, 0L, LONG_MAX, 0); + T_TEST (saddl, long, 1L, LONG_MAX, 1); + T_TEST (saddl, long, LONG_MAX, LONG_MAX, 1); + T_TEST (saddl, long, 0L, LONG_MIN, 0); + T_TEST (saddl, long, -1L, LONG_MIN, 1); + T_TEST (saddl, long, LONG_MIN, LONG_MIN, 1); + + T_TEST (saddll, long long, 0LL, 0LL, 0); + T_TEST (saddll, long long, 0LL, LLONG_MAX, 0); + T_TEST (saddll, long long, 1LL, LLONG_MAX, 1); + T_TEST (saddll, long long, LLONG_MAX, LLONG_MAX, 1); + T_TEST (saddll, long long, 0LL, LLONG_MIN, 0); + T_TEST (saddll, long long, -1LL, LLONG_MIN, 1); + T_TEST (saddll, long long, LLONG_MIN, LLONG_MIN, 1); + + /* Unsigned int addition. */ + T_TEST (uadd, unsigned char, 0U, 0U, 0); + T_TEST (uadd, unsigned char, 0U, UCHAR_MAX, 0); + T_TEST (uadd, unsigned char, 1U, UCHAR_MAX, 0); + T_TEST (uadd, unsigned char, UCHAR_MAX, UCHAR_MAX, 0); + + T_TEST (uadd, unsigned short, 0U, 0U, 0); + T_TEST (uadd, unsigned short, 0U, USHRT_MAX, 0); + T_TEST (uadd, unsigned short, 1U, USHRT_MAX, 0); + T_TEST (uadd, unsigned short, USHRT_MAX, USHRT_MAX, 0); + + T_TEST (uadd, unsigned, 0U, 0U, 0); + T_TEST (uadd, unsigned, 0U, UINT_MAX, 0); + T_TEST (uadd, unsigned, 1U, UINT_MAX, 1); + T_TEST (uadd, unsigned, UINT_MAX, UINT_MAX, 1); + + /* Unsigned long addition. */ + T_TEST (uaddl, unsigned long, 0UL, 0UL, 0); + T_TEST (uaddl, unsigned long, 0UL, ULONG_MAX, 0); + T_TEST (uaddl, unsigned long, 1UL, ULONG_MAX, 1); + T_TEST (uaddl, unsigned long, ULONG_MAX, ULONG_MAX, 1); + + T_TEST (uaddll, unsigned long long, 0ULL, 0ULL, 0); + T_TEST (uaddll, unsigned long long, 0ULL, ULLONG_MAX, 0); + T_TEST (uaddll, unsigned long long, 1ULL, ULLONG_MAX, 1); + T_TEST (uaddll, unsigned long long, ULLONG_MAX, ULLONG_MAX, 1); + + /* Signed int subtraction. */ + T_TEST (ssub, signed char, 0, 0, 0); + T_TEST (ssub, signed char, 0, SCHAR_MAX, 0); + T_TEST (ssub, signed char, 1, SCHAR_MAX, 0); + T_TEST (ssub, signed char, SCHAR_MAX, SCHAR_MAX, 0); + T_TEST (ssub, signed char, 0, SCHAR_MIN, 0); + T_TEST (ssub, signed char, -1, SCHAR_MIN, 0); + + T_TEST (ssub, short, 0, 0, 0); + T_TEST (ssub, short, 0, SHRT_MAX, 0); + T_TEST (ssub, short, 1, SHRT_MAX, 0); + T_TEST (ssub, short, SHRT_MAX, SHRT_MAX, 0); + T_TEST (ssub, short, 0, SHRT_MIN, 0); + T_TEST (ssub, short, -1, SHRT_MIN, 0); + T_TEST (ssub, short, SHRT_MIN, SHRT_MIN, 0); + + T_TEST (ssub, int, 0, 0, 0); + T_TEST (ssub, int, 0, INT_MAX, 0); + T_TEST (ssub, int, 1, INT_MAX, 0); + T_TEST (ssub, int, INT_MAX, INT_MAX, 0); + T_TEST (ssub, int, 0, INT_MIN, 1); + T_TEST (ssub, int, -1, INT_MIN, 0); + T_TEST (ssub, int, INT_MIN, INT_MIN, 0); + + /* Signed long subtraction. */ + T_TEST (ssubl, long, 0L, 0L, 0); + T_TEST (ssubl, long, 0L, LONG_MAX, 0); + T_TEST (ssubl, long, 1L, LONG_MAX, 0); + T_TEST (ssubl, long, LONG_MAX, LONG_MAX, 0); + T_TEST (ssubl, long, 0L, LONG_MIN, 1); + T_TEST (ssubl, long, -1L, LONG_MIN, 0); + T_TEST (ssubl, long, LONG_MIN, LONG_MIN, 0); + + /* Signed long long subtraction. */ + T_TEST (ssubll, long long, 0LL, 0LL, 0); + T_TEST (ssubll, long long, 0LL, LLONG_MAX, 0); + T_TEST (ssubll, long long, 1LL, LLONG_MAX, 0); + T_TEST (ssubll, long long, LLONG_MAX, LLONG_MAX, 0); + T_TEST (ssubll, long long, 0LL, LLONG_MIN, 1); + T_TEST (ssubll, long long, -1LL, LLONG_MIN, 0); + T_TEST (ssubll, long long, LLONG_MIN, LLONG_MIN, 0); + + /* Unsigned int subtraction. */ + T_TEST (usub, unsigned char, 0U, 0U, 0); + T_TEST (usub, unsigned char, 0U, UCHAR_MAX, 1); + T_TEST (usub, unsigned char, 1U, UCHAR_MAX, 1); + T_TEST (usub, unsigned char, UCHAR_MAX, UCHAR_MAX, 0); + + T_TEST (usub, unsigned short, 0U, 0U, 0); + T_TEST (usub, unsigned short, 0U, USHRT_MAX, 1); + T_TEST (usub, unsigned short, 1U, USHRT_MAX, 1); + T_TEST (usub, unsigned short, USHRT_MAX, USHRT_MAX, 0); + + T_TEST (usub, unsigned, 0U, 0U, 0); + T_TEST (usub, unsigned, 0U, UINT_MAX, 1); + T_TEST (usub, unsigned, 1U, UINT_MAX, 1); + T_TEST (usub, unsigned, UINT_MAX, UINT_MAX, 0); + + /* Unsigned long subtraction. */ + T_TEST (usubl, unsigned long, 0UL, 0UL, 0); + T_TEST (usubl, unsigned long, 0UL, ULONG_MAX, 1); + T_TEST (usubl, unsigned long, 1UL, ULONG_MAX, 1); + T_TEST (usubl, unsigned long, ULONG_MAX, ULONG_MAX, 0); + + /* Unsigned long long subtraction. */ + T_TEST (usubll, unsigned long long, 0ULL, 0ULL, 0); + T_TEST (usubll, unsigned long long, 0ULL, ULLONG_MAX, 1); + T_TEST (usubll, unsigned long long, 1ULL, ULLONG_MAX, 1); + T_TEST (usubll, unsigned long long, ULLONG_MAX, ULLONG_MAX, 0); + + return 0; +} diff --git a/gcc/testsuite/c-c++-common/goacc/cache-1.c b/gcc/testsuite/c-c++-common/goacc/cache-1.c index 950334102db..1d4759e738c 100644 --- a/gcc/testsuite/c-c++-common/goacc/cache-1.c +++ b/gcc/testsuite/c-c++-common/goacc/cache-1.c @@ -1,3 +1,7 @@ +/* OpenACC cache directive: valid usage. */ +/* For execution testing, this file is "#include"d from + libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c. */ + int main (int argc, char **argv) { @@ -21,57 +25,31 @@ main (int argc, char **argv) int n = 1; const int len = n; -#pragma acc cache /* { dg-error "expected '\\\(' before end of line" } */ - -#pragma acc cache a[0:N] /* { dg-error "expected '\\\(' before 'a'" } */ - /* { dg-bogus "expected end of line before 'a'" "" { xfail c++ } 26 } */ - -#pragma acc cache (a) /* { dg-error "expected '\\\['" } */ - -#pragma acc cache ( /* { dg-error "expected (identifier|unqualified-id) before end of line" } */ - -#pragma acc cache () /* { dg-error "expected (identifier|unqualified-id) before '\\\)' token" } */ - -#pragma acc cache (,) /* { dg-error "expected (identifier|unqualified-id) before '(,|\\\))' token" } */ - -#pragma acc cache (a[0:N] /* { dg-error "expected '\\\)' before end of line" } */ - -#pragma acc cache (a[0:N],) /* { dg-error "expected (identifier|unqualified-id) before '(,|\\\))' token" "" { xfail c } } */ - -#pragma acc cache (a[0:N]) copyin (a[0:N]) /* { dg-error "expected end of line before 'copyin'" } */ - -#pragma acc cache () /* { dg-error "expected (identifier|unqualified-id) before '\\\)' token" } */ - -#pragma acc cache (a[0:N] b[0:N]) /* { dg-error "expected '\\\)' before 'b'" } */ - -#pragma acc cache (a[0:N] b[0:N}) /* { dg-error "expected '\\\)' before 'b'" } */ - /* { dg-bogus "expected end of line before '\\\}' token" "" { xfail c++ } 47 } */ - -#pragma acc cache (a[0:N] /* { dg-error "expected '\\\)' before end of line" } */ - -#pragma acc cache (a[ii]) /* { dg-error "'ii' is not a constant" } */ - -#pragma acc cache (a[idx:n]) /* { dg-error "'n' is not a constant" } */ - -#pragma acc cache (a[0:N]) ( /* { dg-error "expected end of line before '\\(' token" } */ - -#pragma acc cache (a[0:N]) ii /* { dg-error "expected end of line before 'ii'" } */ - -#pragma acc cache (a[0:N] ii) /* { dg-error "expected '\\)' before 'ii'" } */ - + /* Have at it, GCC! */ #pragma acc cache (a[0:N]) - #pragma acc cache (a[0:N], a[0:N]) - #pragma acc cache (a[0:N], b[0:N]) - #pragma acc cache (a[0]) - #pragma acc cache (a[0], a[1], b[0:N]) - +#pragma acc cache (a[i - 5]) +#pragma acc cache (a[i + 5:len]) +#pragma acc cache (a[i + 5:len - 1]) +#pragma acc cache (b[i]) +#pragma acc cache (b[i:len]) +#pragma acc cache (a[ii]) +#pragma acc cache (a[ii:len]) +#pragma acc cache (b[ii - 1]) +#pragma acc cache (b[ii - 1:len]) +#pragma acc cache (b[i - ii + 1]) +#pragma acc cache (b[i + ii - 1:len]) +#pragma acc cache (b[i * ii - 1:len + 1]) +#pragma acc cache (a[idx + 2]) +#pragma acc cache (a[idx:len + 2]) #pragma acc cache (a[idx]) - #pragma acc cache (a[idx:len]) +#pragma acc cache (a[idx + 2:len]) +#pragma acc cache (a[idx + 2 + i:len]) +#pragma acc cache (a[idx + 2 + i + ii:len]) b[ii] = a[ii]; } diff --git a/gcc/testsuite/c-c++-common/goacc/cache-2.c b/gcc/testsuite/c-c++-common/goacc/cache-2.c new file mode 100644 index 00000000000..f7175157915 --- /dev/null +++ b/gcc/testsuite/c-c++-common/goacc/cache-2.c @@ -0,0 +1,57 @@ +/* OpenACC cache directive: invalid usage. */ + +int +main (int argc, char **argv) +{ +#define N 2 + int a[N], b[N]; + int i; + + for (i = 0; i < N; i++) + { + a[i] = 3; + b[i] = 0; + } + +#pragma acc parallel copyin (a[0:N]) copyout (b[0:N]) +{ + int ii; + + for (ii = 0; ii < N; ii++) + { + const int idx = ii; + int n = 1; + const int len = n; + +#pragma acc cache /* { dg-error "expected '\\\(' before end of line" } */ +#pragma acc cache a[0:N] /* { dg-error "expected '\\\(' before 'a'" } */ + /* { dg-bogus "expected end of line before 'a'" "" { xfail c++ } 27 } */ +#pragma acc cache (a) /* { dg-error "expected '\\\['" } */ +#pragma acc cache ( /* { dg-error "expected (identifier|unqualified-id) before end of line" } */ +#pragma acc cache () /* { dg-error "expected (identifier|unqualified-id) before '\\\)' token" } */ +#pragma acc cache (,) /* { dg-error "expected (identifier|unqualified-id) before '(,|\\\))' token" } */ +#pragma acc cache (a[0:N] /* { dg-error "expected '\\\)' before end of line" } */ +#pragma acc cache (a[0:N],) /* { dg-error "expected (identifier|unqualified-id) before '(,|\\\))' token" "" { xfail c } } */ +#pragma acc cache (a[0:N]) copyin (a[0:N]) /* { dg-error "expected end of line before 'copyin'" } */ +#pragma acc cache () /* { dg-error "expected (identifier|unqualified-id) before '\\\)' token" } */ +#pragma acc cache (a[0:N] b[0:N]) /* { dg-error "expected '\\\)' before 'b'" } */ +#pragma acc cache (a[0:N] b[0:N}) /* { dg-error "expected '\\\)' before 'b'" } */ + /* { dg-bogus "expected end of line before '\\\}' token" "" { xfail c++ } 38 } */ +#pragma acc cache (a[0:N] /* { dg-error "expected '\\\)' before end of line" } */ +#pragma acc cache (a[0:N]) ( /* { dg-error "expected end of line before '\\(' token" } */ +#pragma acc cache (a[0:N]) ii /* { dg-error "expected end of line before 'ii'" } */ +#pragma acc cache (a[0:N] ii) /* { dg-error "expected '\\)' before 'ii'" } */ + + b[ii] = a[ii]; + } +} + + + for (i = 0; i < N; i++) + { + if (a[i] != b[i]) + __builtin_abort (); + } + + return 0; +} diff --git a/gcc/testsuite/c-c++-common/goacc/combined-directives.c b/gcc/testsuite/c-c++-common/goacc/combined-directives.c index c2a3c57b48b..3fa800d7bbe 100644 --- a/gcc/testsuite/c-c++-common/goacc/combined-directives.c +++ b/gcc/testsuite/c-c++-common/goacc/combined-directives.c @@ -111,6 +111,7 @@ test () // { dg-final { scan-tree-dump-times "acc loop vector" 2 "gimple" } } // { dg-final { scan-tree-dump-times "acc loop seq" 2 "gimple" } } // { dg-final { scan-tree-dump-times "acc loop auto" 2 "gimple" } } -// { dg-final { scan-tree-dump-times "acc loop tile.2, 3" 2 "gimple" } } +// XFAILed: OpenACC tile clauses are discarded during gimplification. +// { dg-final { scan-tree-dump-times "acc loop tile.2, 3" 2 "gimple" { xfail *-*-* } } } // { dg-final { scan-tree-dump-times "acc loop independent private.i" 2 "gimple" } } // { dg-final { scan-tree-dump-times "private.z" 2 "gimple" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/Wunused-variable-1.C b/gcc/testsuite/g++.dg/cpp0x/Wunused-variable-1.C new file mode 100644 index 00000000000..39592b26a58 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wunused-variable-1.C @@ -0,0 +1,37 @@ +// PR c++/71442 +// { dg-do compile { target c++11 } } +// { dg-options "-Wunused-variable" } + +struct C +{ + template<typename... Ts> + int operator()(Ts &&...) + { + return sizeof...(Ts); + } +}; + +int +foo () +{ + C {} (1, 1L, 1LL, 1.0); +} + +template<int N> +void +bar () +{ + char a; // { dg-warning "unused variable" } + short b; // { dg-warning "unused variable" } + int c; // { dg-warning "unused variable" } + long d; // { dg-warning "unused variable" } + long long e; // { dg-warning "unused variable" } + float f; // { dg-warning "unused variable" } + double g; // { dg-warning "unused variable" } +} + +void +baz () +{ + bar <0> (); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-arith-overflow.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-arith-overflow.C new file mode 100644 index 00000000000..a63c0a1ef54 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-arith-overflow.C @@ -0,0 +1,212 @@ +// PR c++/70507 - integer overflow builtins not constant expressions +// { dg-do compile { target c++11 } } + +#define SCHAR_MAX __SCHAR_MAX__ +#define SHRT_MAX __SHRT_MAX__ +#define INT_MAX __INT_MAX__ +#define LONG_MAX __LONG_MAX__ +#define LLONG_MAX __LONG_LONG_MAX__ + +#define SCHAR_MIN (-__SCHAR_MAX__ - 1) +#define SHRT_MIN (-__SHRT_MAX__ - 1) +#define INT_MIN (-__INT_MAX__ - 1) +#define LONG_MIN (-__LONG_MAX__ - 1) +#define LLONG_MIN (-__LONG_LONG_MAX__ - 1) + +#define UCHAR_MAX (SCHAR_MAX * 2U + 1) +#define USHRT_MAX (SHRT_MAX * 2U + 1) +#define UINT_MAX (INT_MAX * 2U + 1) +#define ULONG_MAX (LONG_MAX * 2LU + 1) +#define ULLONG_MAX (LLONG_MAX * 2LLU + 1) + +#define USCHAR_MIN (-__USCHAR_MAX__ - 1) +#define USHRT_MIN (-__USHRT_MAX__ - 1) +#define UINT_MIN (-__UINT_MAX__ - 1) +#define ULONG_MIN (-__ULONG_MAX__ - 1) +#define ULLONG_MIN (-__ULONG_LONG_MAX__ - 1) + +#define Assert(expr) static_assert ((expr), #expr) + +template <class T> +constexpr T add (T x, T y, T z = T ()) +{ + return __builtin_add_overflow (x, y, &z) ? 0 : z; +} + +template <class T> +constexpr T sub (T x, T y, T z = T ()) +{ + return __builtin_sub_overflow (x, y, &z) ? 0 : z; +} + +template <class T> +constexpr T mul (T x, T y, T z = T ()) +{ + return __builtin_mul_overflow (x, y, &z) ? 0 : z; +} + +#define TEST_ADD(T, x, y, z) Assert (z == add<T>(x, y)) +#define TEST_SUB(T, x, y, z) Assert (z == sub<T>(x, y)) +#define TEST_MUL(T, x, y, z) Assert (z == mul<T>(x, y)) + + +TEST_ADD (signed char, 0, 0, 0); +TEST_ADD (signed char, 0, SCHAR_MAX, SCHAR_MAX); +TEST_ADD (signed char, 1, SCHAR_MAX, 0); // overflow +TEST_ADD (signed char, SCHAR_MAX, SCHAR_MAX, 0); // overflow +TEST_ADD (signed char, 0, SCHAR_MIN, SCHAR_MIN); +TEST_ADD (signed char, -1, SCHAR_MIN, 0); // overflow + +TEST_ADD (short, 0, 0, 0); +TEST_ADD (short, 0, SHRT_MAX, SHRT_MAX); +TEST_ADD (short, 1, SHRT_MAX, 0); // overflow +TEST_ADD (short, SHRT_MAX, SHRT_MAX, 0); // overflow +TEST_ADD (short, 0, SHRT_MIN, SHRT_MIN); +TEST_ADD (short, -1, SHRT_MIN, 0); // overflow +TEST_ADD (short, SHRT_MIN, SHRT_MIN, 0); // overflow + +TEST_ADD (int, 0, 0, 0); +TEST_ADD (int, 0, INT_MAX, INT_MAX); +TEST_ADD (int, 1, INT_MAX, 0); // overflow +TEST_ADD (int, INT_MAX, INT_MAX, 0); // overflow +TEST_ADD (int, 0, INT_MIN, INT_MIN); +TEST_ADD (int, -1, INT_MIN, 0); // overflow +TEST_ADD (int, INT_MIN, INT_MIN, 0); // overflow + +TEST_ADD (long, 0, 0, 0); +TEST_ADD (long, 0, LONG_MAX, LONG_MAX); +TEST_ADD (long, 1, LONG_MAX, 0); // overflow +TEST_ADD (long, LONG_MAX, LONG_MAX, 0); // overflow +TEST_ADD (long, 0, LONG_MIN, LONG_MIN); +TEST_ADD (long, -1, LONG_MIN, 0); // overflow +TEST_ADD (long, LONG_MIN, LONG_MIN, 0); // overflow + +TEST_ADD (long long, 0, 0, 0); +TEST_ADD (long long, 0, LLONG_MAX, LLONG_MAX); +TEST_ADD (long long, 1, LLONG_MAX, 0); // overflow +TEST_ADD (long long, LLONG_MAX, LLONG_MAX, 0); // overflow +TEST_ADD (long long, 0, LLONG_MIN, LLONG_MIN); +TEST_ADD (long long, -1, LLONG_MIN, 0); // overflow +TEST_ADD (long long, LLONG_MIN, LLONG_MIN, 0); // overflow + +TEST_ADD (unsigned char, 0, 0, 0); +TEST_ADD (unsigned char, 0, UCHAR_MAX, UCHAR_MAX); +TEST_ADD (unsigned char, 1, UCHAR_MAX, 0); // overflow + +TEST_ADD (unsigned char, UCHAR_MAX, UCHAR_MAX, 0); // overflow +TEST_ADD (unsigned short, 0, 0, 0); +TEST_ADD (unsigned short, 0, USHRT_MAX, USHRT_MAX); +TEST_ADD (unsigned short, 1, USHRT_MAX, 0); // overflow +TEST_ADD (unsigned short, USHRT_MAX, USHRT_MAX, 0); // overflow + +TEST_ADD (unsigned, 0, 0, 0); +TEST_ADD (unsigned, 0, UINT_MAX, UINT_MAX); +TEST_ADD (unsigned, 1, UINT_MAX, 0); // overflow +TEST_ADD (unsigned, UINT_MAX, UINT_MAX, 0); // overflow + +TEST_ADD (unsigned long, 0, 0, 0); +TEST_ADD (unsigned long, 0, ULONG_MAX, ULONG_MAX); +TEST_ADD (unsigned long, 1, ULONG_MAX, 0); // overflow +TEST_ADD (unsigned long, ULONG_MAX, ULONG_MAX, 0); // overflow + +TEST_ADD (unsigned long long, 0, 0, 0); +TEST_ADD (unsigned long long, 0, ULLONG_MAX, ULLONG_MAX); +TEST_ADD (unsigned long long, 1, ULLONG_MAX, 0); // overflow +TEST_ADD (unsigned long long, ULLONG_MAX, ULLONG_MAX, 0); // overflow + + +// Make sure the built-ins are accepted in the following contexts +// where constant expressions are required and that they return +// the expected overflow value. + +namespace Enum { + +enum Add { + a0 = __builtin_add_overflow_p ( 1, 1, 0), + a1 = __builtin_add_overflow_p (INT_MAX, 1, 0) +}; + +Assert (a0 == 0); +Assert (a1 == 1); + +enum Sub { + s0 = __builtin_sub_overflow_p ( 1, 1, 0), + s1 = __builtin_sub_overflow_p (INT_MIN, 1, 0) +}; + +Assert (s0 == 0); +Assert (s1 == 1); + +enum Mul { + m0 = __builtin_add_overflow_p ( 1, 1, 0), + m1 = __builtin_add_overflow_p (INT_MAX, INT_MAX, 0) +}; + +Assert (m0 == 0); +Assert (m1 == 1); + +} // namespace Enum + +namespace TemplateArg { + +template <class T, class U, class V, + T x, U y, bool v, bool z = __builtin_add_overflow_p (x, y, V ())> +struct Add { + Assert (z == v); +}; + +template <class T, class U, class V, + T x, U y, bool v, bool z = __builtin_sub_overflow_p (x, y, V ())> +struct Sub { + Assert (z == v); +}; + +template <class T, class U, class V, + T x, U y, bool v, bool z = __builtin_mul_overflow_p (x, y, V ())> +struct Mul { + Assert (z == v); +}; + +template struct Add<int, int, int, 1, 1, false>; +template struct Add<int, int, int, 1, INT_MAX, true>; + +template struct Sub<int, int, int, 1, 1, false>; +template struct Sub<int, int, int, -2, INT_MAX, true>; + +template struct Mul<int, int, int, 1, 1, false>; +template struct Mul<int, int, int, 2, INT_MAX / 2 + 1, true>; + +} // namespace TemplateArg + +#if __cplusplus >= 201402L + +namespace Initializer { + +struct Result { + int res; + bool vflow; +}; + +constexpr Result +add_vflow (int a, int b) +{ +#if 1 + Result res = { a + b, __builtin_add_overflow_p (a, b, int ()) }; +#else + // The following fails to compile because of c++/71391 - error + // on aggregate initialization with side-effects in a constexpr + // function + int c = 0; + Result res = { 0, __builtin_add_overflow (a, b, &c) }; + res.c = c; +#endif + return res; +} + +constexpr Result sum = add_vflow (123, 456); +Assert (sum.res == 123 + 456); +Assert (!sum.vflow); + +} // namespace Initializer + +#endif // __cplusplus >= 201402L diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice10.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice10.C index f6fc80cdc70..51612737847 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice10.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice10.C @@ -4,5 +4,5 @@ struct A { constexpr A() {} - static constexpr A a[2] = {}; // { dg-error "incomplete" } + static constexpr A a[2] = {}; // { dg-error "22:elements of array 'constexpr const A A::a \\\[2\\\]' have incomplete type" } }; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete1.C index 514cca59c33..7b0d83e608d 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete1.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete1.C @@ -2,6 +2,6 @@ struct A { - static constexpr A a = 1; // { dg-error "incomplete" } + static constexpr A a = 1; // { dg-error "22:'constexpr const A A::a' has incomplete type" } constexpr A(int i) { } }; diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C index c9291c2b8e4..b114df2fdd5 100644 --- a/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C @@ -31,7 +31,7 @@ F<T>::bar (const G &) { auto s = I; typedef decltype (s) L; - auto u =[&](L) { auto t = foo (J::K (), 0); }; // { dg-error "" } + auto u =[&](L) { auto t = foo (J::K (), 0); }; // { dg-error "25:'void t' has incomplete type" } } struct B { typedef int G; diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-arith-overflow.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-arith-overflow.C new file mode 100644 index 00000000000..7ca0033d217 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-arith-overflow.C @@ -0,0 +1,229 @@ +// Test to exercise that the type-specific integer arithmetic built-ins +// with overflow checking can be used in C++ 14 constant expressions. +// -Woverflow is disabled to prevent (bogus?) G++ warnings. +// { dg-do compile { target c++14 } } +// { dg-additional-options "-Wno-overflow" } + +#define SCHAR_MAX __SCHAR_MAX__ +#define SHRT_MAX __SHRT_MAX__ +#define INT_MAX __INT_MAX__ +#define LONG_MAX __LONG_MAX__ +#define LLONG_MAX __LONG_LONG_MAX__ + +#define SCHAR_MIN (-__SCHAR_MAX__ - 1) +#define SHRT_MIN (-__SHRT_MAX__ - 1) +#define INT_MIN (-__INT_MAX__ - 1) +#define LONG_MIN (-__LONG_MAX__ - 1) +#define LLONG_MIN (-__LONG_LONG_MAX__ - 1) + +#define UCHAR_MAX (SCHAR_MAX * 2U + 1) +#define USHRT_MAX (SHRT_MAX * 2U + 1) +#define UINT_MAX (INT_MAX * 2U + 1) +#define ULONG_MAX (LONG_MAX * 2LU + 1) +#define ULLONG_MAX (LLONG_MAX * 2LLU + 1) + +#define USCHAR_MIN (-__USCHAR_MAX__ - 1) +#define USHRT_MIN (-__USHRT_MAX__ - 1) +#define UINT_MIN (-__UINT_MAX__ - 1) +#define ULONG_MIN (-__ULONG_MAX__ - 1) +#define ULLONG_MIN (-__ULONG_LONG_MAX__ - 1) + +// Helper macros. +#define sadd(x, y) ((x) + (y)) +#define saddl(x, y) ((x) + (y)) +#define saddll(x, y) ((x) + (y)) +#define uadd(x, y) ((x) + (y)) +#define uaddl(x, y) ((x) + (y)) +#define uaddll(x, y) ((x) + (y)) +#define ssub(x, y) ((x) - (y)) +#define ssubl(x, y) ((x) - (y)) +#define ssubll(x, y) ((x) - (y)) +#define usub(x, y) ((x) - (y)) +#define usubl(x, y) ((x) - (y)) +#define usubll(x, y) ((x) - (y)) +#define smul(x, y) ((x) * (y)) +#define smull(x, y) ((x) * (y)) +#define smulll(x, y) ((x) * (y)) +#define umul(x, y) ((x) * (y)) +#define umull(x, y) ((x) * (y)) +#define umulll(x, y) ((x) * (y)) + +// Result object. +template <class T> +struct Res +{ + constexpr Res (T a, bool v): z (a), v (v) { } + T z; bool v; +}; + +template <class T> +constexpr bool operator== (Res<T> a, Res<T> b) +{ + return a.z == b.z && a.v == b.v; +} + +#define StaticAssert(expr) static_assert ((expr), #expr) + +#define CONCAT(a, b) a ## b +#define CAT(a, b) CONCAT (a, b) + +// Helper to determine the type of the result of the arithmetic +// as specified by the built-ins. +template <class T> struct ResType { typedef T type; }; +template <> struct ResType<signed char> { typedef int type; }; +template <> struct ResType<unsigned char> { typedef unsigned type; }; +template <> struct ResType<signed short> { typedef int type; }; +template <> struct ResType<unsigned short> { typedef unsigned type; }; + +// Macro to define a single test case verifying that integer overflow +// is detected when expected, and when not, that the result matches +// the result computed using ordinary arithmetic. The result cannot +// be tested in the presence of overflow since it's not a core +// constant expression. +#define TEST(op, T, x, y, vflow) \ + constexpr Res<T> CAT (op, __LINE__)(T a, T b) \ + { \ + ResType<T>::type c = 0; \ + bool v = __builtin_ ## op ## _overflow (a, b, &c); \ + return Res<T>(c, v); \ + } \ + StaticAssert (vflow ? CAT (op, __LINE__)(x, y).v \ + : CAT (op, __LINE__)(x, y) == Res<T>(op (x, y), vflow)) + +/* Signed int addition. */ +TEST (sadd, signed char, 0, 0, 0); +TEST (sadd, signed char, 0, SCHAR_MAX, 0); +TEST (sadd, signed char, 1, SCHAR_MAX, 0); +TEST (sadd, signed char, SCHAR_MAX, SCHAR_MAX, 0); +TEST (sadd, signed char, 0, SCHAR_MIN, 0); +TEST (sadd, signed char, -1, SCHAR_MIN, 0); + +TEST (sadd, short, 0, 0, 0); +TEST (sadd, short, 0, SHRT_MAX, 0); +TEST (sadd, short, 1, SHRT_MAX, 0); +TEST (sadd, short, SHRT_MAX, SHRT_MAX, 0); +TEST (sadd, short, 0, SHRT_MIN, 0); +TEST (sadd, short, -1, SHRT_MIN, 0); +TEST (sadd, short, SHRT_MIN, SHRT_MIN, 0); + +TEST (sadd, int, 0, 0, 0); +TEST (sadd, int, 0, INT_MAX, 0); +TEST (sadd, int, 1, INT_MAX, 1); +TEST (sadd, int, INT_MAX, INT_MAX, 1); +TEST (sadd, int, 0, INT_MIN, 0); +TEST (sadd, int, -1, INT_MIN, 1); +TEST (sadd, int, INT_MIN, INT_MIN, 1); + +/* Signed long addition. */ +TEST (saddl, long, 0L, 0L, 0); +TEST (saddl, long, 0L, LONG_MAX, 0); +TEST (saddl, long, 1L, LONG_MAX, 1); +TEST (saddl, long, LONG_MAX, LONG_MAX, 1); +TEST (saddl, long, 0L, LONG_MIN, 0); +TEST (saddl, long, -1L, LONG_MIN, 1); +TEST (saddl, long, LONG_MIN, LONG_MIN, 1); + +TEST (saddll, long long, 0LL, 0LL, 0); +TEST (saddll, long long, 0LL, LLONG_MAX, 0); +TEST (saddll, long long, 1LL, LLONG_MAX, 1); +TEST (saddll, long long, LLONG_MAX, LLONG_MAX, 1); +TEST (saddll, long long, 0LL, LLONG_MIN, 0); +TEST (saddll, long long, -1LL, LLONG_MIN, 1); +TEST (saddll, long long, LLONG_MIN, LLONG_MIN, 1); + +/* Unsigned int addition. */ +TEST (uadd, unsigned char, 0U, 0U, 0); +TEST (uadd, unsigned char, 0U, UCHAR_MAX, 0); +TEST (uadd, unsigned char, 1U, UCHAR_MAX, 0); +TEST (uadd, unsigned char, UCHAR_MAX, UCHAR_MAX, 0); + +TEST (uadd, unsigned short, 0U, 0U, 0); +TEST (uadd, unsigned short, 0U, USHRT_MAX, 0); +TEST (uadd, unsigned short, 1U, USHRT_MAX, 0); +TEST (uadd, unsigned short, USHRT_MAX, USHRT_MAX, 0); + +TEST (uadd, unsigned, 0U, 0U, 0); +TEST (uadd, unsigned, 0U, UINT_MAX, 0); +TEST (uadd, unsigned, 1U, UINT_MAX, 1); +TEST (uadd, unsigned, UINT_MAX, UINT_MAX, 1); + +/* Unsigned long addition. */ +TEST (uaddl, unsigned long, 0UL, 0UL, 0); +TEST (uaddl, unsigned long, 0UL, ULONG_MAX, 0); +TEST (uaddl, unsigned long, 1UL, ULONG_MAX, 1); +TEST (uaddl, unsigned long, ULONG_MAX, ULONG_MAX, 1); + +TEST (uaddll, unsigned long long, 0ULL, 0ULL, 0); +TEST (uaddll, unsigned long long, 0ULL, ULLONG_MAX, 0); +TEST (uaddll, unsigned long long, 1ULL, ULLONG_MAX, 1); +TEST (uaddll, unsigned long long, ULLONG_MAX, ULLONG_MAX, 1); + +/* Signed int subtraction. */ +TEST (ssub, signed char, 0, 0, 0); +TEST (ssub, signed char, 0, SCHAR_MAX, 0); +TEST (ssub, signed char, 1, SCHAR_MAX, 0); +TEST (ssub, signed char, SCHAR_MAX, SCHAR_MAX, 0); +TEST (ssub, signed char, 0, SCHAR_MIN, 0); +TEST (ssub, signed char, -1, SCHAR_MIN, 0); + +TEST (ssub, short, 0, 0, 0); +TEST (ssub, short, 0, SHRT_MAX, 0); +TEST (ssub, short, 1, SHRT_MAX, 0); +TEST (ssub, short, SHRT_MAX, SHRT_MAX, 0); +TEST (ssub, short, 0, SHRT_MIN, 0); +TEST (ssub, short, -1, SHRT_MIN, 0); +TEST (ssub, short, SHRT_MIN, SHRT_MIN, 0); + +TEST (ssub, int, 0, 0, 0); +TEST (ssub, int, 0, INT_MAX, 0); +TEST (ssub, int, 1, INT_MAX, 0); +TEST (ssub, int, INT_MAX, INT_MAX, 0); +TEST (ssub, int, 0, INT_MIN, 1); +TEST (ssub, int, -1, INT_MIN, 0); +TEST (ssub, int, INT_MIN, INT_MIN, 0); + +/* Signed long subtraction. */ +TEST (ssubl, long, 0L, 0L, 0); +TEST (ssubl, long, 0L, LONG_MAX, 0); +TEST (ssubl, long, 1L, LONG_MAX, 0); +TEST (ssubl, long, LONG_MAX, LONG_MAX, 0); +TEST (ssubl, long, 0L, LONG_MIN, 1); +TEST (ssubl, long, -1L, LONG_MIN, 0); +TEST (ssubl, long, LONG_MIN, LONG_MIN, 0); + +/* Signed long long subtraction. */ +TEST (ssubll, long long, 0LL, 0LL, 0); +TEST (ssubll, long long, 0LL, LLONG_MAX, 0); +TEST (ssubll, long long, 1LL, LLONG_MAX, 0); +TEST (ssubll, long long, LLONG_MAX, LLONG_MAX, 0); +TEST (ssubll, long long, 0LL, LLONG_MIN, 1); +TEST (ssubll, long long, -1LL, LLONG_MIN, 0); +TEST (ssubll, long long, LLONG_MIN, LLONG_MIN, 0); + +/* Unsigned int subtraction. */ +TEST (usub, unsigned char, 0U, 0U, 0); +TEST (usub, unsigned char, 0U, UCHAR_MAX, 1); +TEST (usub, unsigned char, 1U, UCHAR_MAX, 1); +TEST (usub, unsigned char, UCHAR_MAX, UCHAR_MAX, 0); + +TEST (usub, unsigned short, 0U, 0U, 0); +TEST (usub, unsigned short, 0U, USHRT_MAX, 1); +TEST (usub, unsigned short, 1U, USHRT_MAX, 1); +TEST (usub, unsigned short, USHRT_MAX, USHRT_MAX, 0); + +TEST (usub, unsigned, 0U, 0U, 0); +TEST (usub, unsigned, 0U, UINT_MAX, 1); +TEST (usub, unsigned, 1U, UINT_MAX, 1); +TEST (usub, unsigned, UINT_MAX, UINT_MAX, 0); + +/* Unsigned long subtraction. */ +TEST (usubl, unsigned long, 0UL, 0UL, 0); +TEST (usubl, unsigned long, 0UL, ULONG_MAX, 1); +TEST (usubl, unsigned long, 1UL, ULONG_MAX, 1); +TEST (usubl, unsigned long, ULONG_MAX, ULONG_MAX, 0); + +/* Unsigned long long subtraction. */ +TEST (usubll, unsigned long long, 0ULL, 0ULL, 0); +TEST (usubll, unsigned long long, 0ULL, ULLONG_MAX, 1); +TEST (usubll, unsigned long long, 1ULL, ULLONG_MAX, 1); +TEST (usubll, unsigned long long, ULLONG_MAX, ULLONG_MAX, 0); diff --git a/gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C b/gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C new file mode 100644 index 00000000000..669eea2cbd2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C @@ -0,0 +1,11 @@ +// { dg-do compile } + +enum A { B = 1, C = 2, D = __builtin_add_overflow_p (B, C, C) }; +int e[__builtin_add_overflow_p (B, C, C) + 1]; +template <int N> int foo (int); + +void +bar () +{ + foo <__builtin_add_overflow_p (B, C, C) + 1> (0); +} diff --git a/gcc/testsuite/g++.dg/gomp/pr35751.C b/gcc/testsuite/g++.dg/gomp/pr35751.C index 0b6cded5929..a8acce05f51 100644 --- a/gcc/testsuite/g++.dg/gomp/pr35751.C +++ b/gcc/testsuite/g++.dg/gomp/pr35751.C @@ -5,8 +5,8 @@ void foo (int i) { - extern int a[i]; // { dg-error "storage size of" } - static int b[i]; // { dg-error "storage size of" } + extern int a[i]; // { dg-error "14:storage size of" } + static int b[i]; // { dg-error "14:storage size of" } #pragma omp parallel { diff --git a/gcc/testsuite/g++.dg/inherit/crash5.C b/gcc/testsuite/g++.dg/inherit/crash5.C index bce999ccbe5..5a4002e0f8a 100644 --- a/gcc/testsuite/g++.dg/inherit/crash5.C +++ b/gcc/testsuite/g++.dg/inherit/crash5.C @@ -1,10 +1,6 @@ -// PR c++/70202 +// PR c++/71465 -class A -{ - virtual void foo () { } -}; -class B : public A, A { }; // { dg-error "duplicate base type" } - -B b1, &b2 = b1; -A a = b2; +struct A { virtual void foo () {} }; +struct B : virtual A {}; +struct C : virtual A {}; +struct D : C, B, C {}; // { dg-error "duplicate base type" } diff --git a/gcc/testsuite/g++.dg/inherit/virtual1.C b/gcc/testsuite/g++.dg/inherit/virtual1.C index 1199b815f56..08bcbb143cf 100644 --- a/gcc/testsuite/g++.dg/inherit/virtual1.C +++ b/gcc/testsuite/g++.dg/inherit/virtual1.C @@ -5,8 +5,8 @@ struct A virtual ~A() {} }; -struct B : A, virtual A {}; // { dg-error "duplicate base" } +struct B : A, virtual A {}; // { dg-error "duplicate base|forward declaration" } -struct C : A, B {}; // { dg-error "duplicate base" } +struct C : A, B {}; // { dg-error "duplicate base|invalid use" } -C c; +C c; // { dg-error "aggregate" } diff --git a/gcc/testsuite/g++.dg/init/array23.C b/gcc/testsuite/g++.dg/init/array23.C index 80ffb0a98cc..fbcd39e2c3a 100644 --- a/gcc/testsuite/g++.dg/init/array23.C +++ b/gcc/testsuite/g++.dg/init/array23.C @@ -3,4 +3,4 @@ // array struct A {A();int A::* t;}; -A x[]; // { dg-error "size" } +A x[]; // { dg-error "3:array size missing" } diff --git a/gcc/testsuite/g++.dg/init/array42.C b/gcc/testsuite/g++.dg/init/array42.C new file mode 100644 index 00000000000..d16a9ea11ce --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array42.C @@ -0,0 +1 @@ +char a[] = ("abc"); // { dg-warning "6:array 'a' initialized by parenthesized string literal" } diff --git a/gcc/testsuite/g++.dg/init/array43.C b/gcc/testsuite/g++.dg/init/array43.C new file mode 100644 index 00000000000..37ef2411518 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array43.C @@ -0,0 +1,2 @@ +int a[] = 0; // { dg-error "5:initializer fails to determine size" } +// { dg-error "11:array must be initialized" "" { target *-*-* } 1 } diff --git a/gcc/testsuite/g++.dg/init/array44.C b/gcc/testsuite/g++.dg/init/array44.C new file mode 100644 index 00000000000..5643c81f218 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array44.C @@ -0,0 +1 @@ +int a[] = { }; // { dg-error "5:zero-size array" } diff --git a/gcc/testsuite/g++.dg/init/array45.C b/gcc/testsuite/g++.dg/init/array45.C new file mode 100644 index 00000000000..ee4451df5ff --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array45.C @@ -0,0 +1 @@ +int a[]; // { dg-error "5:storage size" } diff --git a/gcc/testsuite/g++.dg/init/brace2.C b/gcc/testsuite/g++.dg/init/brace2.C index 50dc4813954..e6307525fbf 100644 --- a/gcc/testsuite/g++.dg/init/brace2.C +++ b/gcc/testsuite/g++.dg/init/brace2.C @@ -3,6 +3,6 @@ int x = { 2 }; const char * y = { "hello" }; int a = 2; -int b = { 2,3 }; // { dg-error "requires one element in initializer" } +int b = { 2,3 }; // { dg-error "5:scalar object 'b' requires one element in initializer" } int c = { { 2 } } ; // { dg-error "braces around scalar initializer" } int d = {}; // { dg-error "initializer" "" { target { ! c++11 } } } diff --git a/gcc/testsuite/g++.dg/init/brace6.C b/gcc/testsuite/g++.dg/init/brace6.C index 0fa818c80c0..f8452351d12 100644 --- a/gcc/testsuite/g++.dg/init/brace6.C +++ b/gcc/testsuite/g++.dg/init/brace6.C @@ -17,8 +17,8 @@ struct D { int c; }; int main() { int i = { 1 }; - int j = { 1, 2 }; /* { dg-error "requires one element" } */ - A a = { 6 }; /* { dg-error "initialize" "" { target { ! c++11 } } } */ + int j = { 1, 2 }; /* { dg-error "8:scalar object 'j' requires one element" } */ + A a = { 6 }; /* { dg-error "6:in C\\+\\+98 'a' must be initialized" "" { target { ! c++11 } } } */ B b = { 6 }; /* { dg-error "" } */ C c = { 6 }; /* { dg-error "too many initializers" } */ D d = { 6 }; diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-1.C b/gcc/testsuite/g++.dg/predict-loop-exit-1.C index 357397f512b..88262eb9d00 100644 --- a/gcc/testsuite/g++.dg/predict-loop-exit-1.C +++ b/gcc/testsuite/g++.dg/predict-loop-exit-1.C @@ -9,5 +9,5 @@ void test() { return; } -/* { dg-final { scan-tree-dump-times "extra loop exit heuristics:" 2 "profile_estimate"} } */ -/* { dg-final { scan-tree-dump-times "loop exit heuristics:" 3 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "extra loop exit heuristics of edge\[^:\]*:" 2 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "loop exit heuristics of edge\[^:\]*:" 3 "profile_estimate"} } */ diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-2.C b/gcc/testsuite/g++.dg/predict-loop-exit-2.C index 172fab120c8..15e9866d897 100644 --- a/gcc/testsuite/g++.dg/predict-loop-exit-2.C +++ b/gcc/testsuite/g++.dg/predict-loop-exit-2.C @@ -9,5 +9,5 @@ void test() { return; } -/* { dg-final { scan-tree-dump-times "extra loop exit heuristics:" 1 "profile_estimate"} } */ -/* { dg-final { scan-tree-dump-times "loop exit heuristics:" 2 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "extra loop exit heuristics of edge\[^:\]*:" 1 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "loop exit heuristics of edge\[^:\]*:" 2 "profile_estimate"} } */ diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-3.C b/gcc/testsuite/g++.dg/predict-loop-exit-3.C index e6ceec80159..61af84b6f56 100644 --- a/gcc/testsuite/g++.dg/predict-loop-exit-3.C +++ b/gcc/testsuite/g++.dg/predict-loop-exit-3.C @@ -9,5 +9,5 @@ void test() { return; } -/* { dg-final { scan-tree-dump-times "extra loop exit heuristics:" 2 "profile_estimate"} } */ -/* { dg-final { scan-tree-dump-times "loop exit heuristics:" 3 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "extra loop exit heuristics of edge\[^:\]*:" 2 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "loop exit heuristics of edge\[^:\]*:" 3 "profile_estimate"} } */ diff --git a/gcc/testsuite/g++.dg/tm/jump1.C b/gcc/testsuite/g++.dg/tm/jump1.C index e28282dc624..a27c2011861 100644 --- a/gcc/testsuite/g++.dg/tm/jump1.C +++ b/gcc/testsuite/g++.dg/tm/jump1.C @@ -14,8 +14,8 @@ void f() switch (i) { - synchronized { // { dg-warning "statement will never be executed" } - ++i; + synchronized { + ++i; // { dg-warning "statement will never be executed" } case 42: // { dg-error "" } ++i; } diff --git a/gcc/testsuite/gcc.c-torture/execute/bswap-2.c b/gcc/testsuite/gcc.c-torture/execute/bswap-2.c index 88132fe7859..63e7807d3d9 100644 --- a/gcc/testsuite/gcc.c-torture/execute/bswap-2.c +++ b/gcc/testsuite/gcc.c-torture/execute/bswap-2.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target int32plus } */ + #ifdef __UINT32_TYPE__ typedef __UINT32_TYPE__ uint32_t; #else diff --git a/gcc/testsuite/gcc.c-torture/execute/pr71335.c b/gcc/testsuite/gcc.c-torture/execute/pr71335.c new file mode 100644 index 00000000000..cbfd99083d0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr71335.c @@ -0,0 +1,13 @@ +int a; +int +main () +{ + int b = 0; + while (a < 0 || b) + { + b = 0; + for (; b < 9; b++) + ; + } + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr71494.c b/gcc/testsuite/gcc.c-torture/execute/pr71494.c new file mode 100644 index 00000000000..f962f2c2e21 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr71494.c @@ -0,0 +1,22 @@ +/* PR middle-end/71494 */ + +int +main () +{ + void *label = &&out; + int i = 0; + void test (void) + { + label = &&out2; + goto *label; + out2:; + i++; + } + goto *label; + out: + i += 2; + test (); + if (i != 3) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/Wswitch-unreachable-2.c b/gcc/testsuite/gcc.dg/Wswitch-unreachable-2.c new file mode 100644 index 00000000000..343baea1245 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wswitch-unreachable-2.c @@ -0,0 +1,12 @@ +/* PR middle-end/71476 */ +/* { dg-do compile } */ +/* { dg-options "-Wswitch-unreachable" } */ + +void +foo (int a) +{ + switch (a) + { + void f (void) { } + } +} diff --git a/gcc/testsuite/gcc.dg/align-3.c b/gcc/testsuite/gcc.dg/align-3.c new file mode 100644 index 00000000000..5c97d5ac3cc --- /dev/null +++ b/gcc/testsuite/gcc.dg/align-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-expand" } */ + +typedef struct { char a[2]; } __attribute__((__packed__)) TU2; +unsigned short get16_unaligned(const void *p) { + unsigned short v; + *(TU2 *)(void *)(&v) = *(const TU2 *)p; + return v; +} + +/* { dg-final { scan-rtl-dump "MEM\[^\n\r\]*A8\\\]" "expand" } } */ diff --git a/gcc/testsuite/gcc.dg/builtin-constant_p-1.c b/gcc/testsuite/gcc.dg/builtin-constant_p-1.c index b0b34f4a1e1..f177fe34b2c 100644 --- a/gcc/testsuite/gcc.dg/builtin-constant_p-1.c +++ b/gcc/testsuite/gcc.dg/builtin-constant_p-1.c @@ -2,9 +2,9 @@ int main() { - if (__builtin_constant_p ()) /* { dg-error "not enough" } */ + if (__builtin_constant_p ()) /* { dg-error "too few arguments" } */ return 0; - if (__builtin_constant_p (5, 6)) /* { dg-error "too many" } */ + if (__builtin_constant_p (5, 6)) /* { dg-error "too many arguments" } */ return 1; return 0; } diff --git a/gcc/testsuite/gcc.dg/builtins-error.c b/gcc/testsuite/gcc.dg/builtins-error.c index 9ddf1b1e2ae..945d239d608 100644 --- a/gcc/testsuite/gcc.dg/builtins-error.c +++ b/gcc/testsuite/gcc.dg/builtins-error.c @@ -23,19 +23,19 @@ int test1(struct X x) int test2(double x) { - if (x == 1) return __builtin_fpclassify(1,2,3,4,5); /* { dg-error "not enough arguments" } */ - if (x == 2) return __builtin_isfinite(); /* { dg-error "not enough arguments" } */ - if (x == 3) return __builtin_isinf_sign(); /* { dg-error "not enough arguments" } */ - if (x == 4) return __builtin_isinf(); /* { dg-error "not enough arguments" } */ - if (x == 5) return __builtin_isnan(); /* { dg-error "not enough arguments" } */ - if (x == 6) return __builtin_isnormal(); /* { dg-error "not enough arguments" } */ - if (x == 7) return __builtin_isgreater(x); /* { dg-error "not enough arguments" } */ - if (x == 8) return __builtin_isgreaterequal(x); /* { dg-error "not enough arguments" } */ - if (x == 9) return __builtin_isless(x); /* { dg-error "not enough arguments" } */ - if (x == 10) return __builtin_islessequal(x); /* { dg-error "not enough arguments" } */ - if (x == 11) return __builtin_islessgreater(x); /* { dg-error "not enough arguments" } */ - if (x == 12) return __builtin_isunordered(x); /* { dg-error "not enough arguments" } */ - if (x == 13) return __builtin_signbit(); /* { dg-error "not enough arguments" } */ + if (x == 1) return __builtin_fpclassify(1,2,3,4,5); /* { dg-error "too few arguments" } */ + if (x == 2) return __builtin_isfinite(); /* { dg-error "too few arguments" } */ + if (x == 3) return __builtin_isinf_sign(); /* { dg-error "too few arguments" } */ + if (x == 4) return __builtin_isinf(); /* { dg-error "too few arguments" } */ + if (x == 5) return __builtin_isnan(); /* { dg-error "too few arguments" } */ + if (x == 6) return __builtin_isnormal(); /* { dg-error "too few arguments" } */ + if (x == 7) return __builtin_isgreater(x); /* { dg-error "too few arguments" } */ + if (x == 8) return __builtin_isgreaterequal(x); /* { dg-error "too few arguments" } */ + if (x == 9) return __builtin_isless(x); /* { dg-error "too few arguments" } */ + if (x == 10) return __builtin_islessequal(x); /* { dg-error "too few arguments" } */ + if (x == 11) return __builtin_islessgreater(x); /* { dg-error "too few arguments" } */ + if (x == 12) return __builtin_isunordered(x); /* { dg-error "too few arguments" } */ + if (x == 13) return __builtin_signbit(); /* { dg-error "too few arguments" } */ return 0; } diff --git a/gcc/testsuite/gcc.dg/c11-generic-3.c b/gcc/testsuite/gcc.dg/c11-generic-3.c new file mode 100644 index 00000000000..8bac21ed31f --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-generic-3.c @@ -0,0 +1,10 @@ +/* Test C11 _Generic. Test we follow the resolution of DR#423. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +char const *a = _Generic ("bla", char *: ""); +char const *b = _Generic ("bla", char[4]: ""); /* { dg-error "not compatible with any association" } */ +char const *c = _Generic ((int const) { 0 }, int: ""); +char const *d = _Generic ((int const) { 0 }, int const: ""); /* { dg-error "not compatible with any association" } */ +char const *e = _Generic (+(int const) { 0 }, int: ""); +char const *f = _Generic (+(int const) { 0 }, int const: ""); /* { dg-error "not compatible with any association" } */ diff --git a/gcc/testsuite/gcc.dg/c99-init-2.c b/gcc/testsuite/gcc.dg/c99-init-2.c index d3a331ff355..c07005be249 100644 --- a/gcc/testsuite/gcc.dg/c99-init-2.c +++ b/gcc/testsuite/gcc.dg/c99-init-2.c @@ -9,7 +9,7 @@ typedef struct { } A; A a = { [2] = 1 }; /* { dg-error "(array index in non-array)|(near initialization)" } */ int b[] = { .B = 1 }; /* { dg-error "(field name not in record)|(near initialization)" } */ -A c[] = { [0].D = 1 }; /* { dg-error "unknown field" } */ +A c[] = { [0].D = 1 }; /* { dg-error "15: has no member named .D." } */ int d; int e = { d++ }; /* { dg-error "(is not constant)|(near initialization)" } */ A f[2] = { [0].C[0] = 1, [2] = { 2, { 1, 2 } } };/* { dg-error "(array index in initializer exceeds array bounds)|(near initialization)" } */ diff --git a/gcc/testsuite/gcc.dg/goacc/nested-function-1.c b/gcc/testsuite/gcc.dg/goacc/nested-function-1.c new file mode 100644 index 00000000000..e17c0e2227f --- /dev/null +++ b/gcc/testsuite/gcc.dg/goacc/nested-function-1.c @@ -0,0 +1,100 @@ +/* Exercise nested function decomposition, gcc/tree-nested.c. */ +/* See gcc/testsuite/gfortran.dg/goacc/nested-function-1.f90 for the Fortran + version. */ + +int main () +{ +#define N 100 + int nonlocal_arg; + int nonlocal_a[N]; + int nonlocal_i; + int nonlocal_j; + + for (int i = 0; i < N; ++i) + nonlocal_a[i] = 5; + nonlocal_arg = 5; + + void local () + { + int local_i; + int local_arg; + int local_a[N]; + int local_j; + + for (int i = 0; i < N; ++i) + local_a[i] = 5; + local_arg = 5; + +#pragma acc kernels loop \ + gang(num:local_arg) worker(local_arg) vector(local_arg) \ + wait async(local_arg) + for (local_i = 0; local_i < N; ++local_i) + { +#pragma acc cache (local_a[local_i:5]) + local_a[local_i] = 100; +#pragma acc loop seq tile(*) + for (local_j = 0; local_j < N; ++local_j) + ; +#pragma acc loop auto independent tile(1) + for (local_j = 0; local_j < N; ++local_j) + ; + } + +#pragma acc kernels loop \ + gang(static:local_arg) worker(local_arg) vector(local_arg) \ + wait(local_arg, local_arg + 1, local_arg + 2) async + for (local_i = 0; local_i < N; ++local_i) + { +#pragma acc cache (local_a[local_i:4]) + local_a[local_i] = 100; +#pragma acc loop seq tile(1) + for (local_j = 0; local_j < N; ++local_j) + ; +#pragma acc loop auto independent tile(*) + for (local_j = 0; local_j < N; ++local_j) + ; + } + } + + void nonlocal () + { + for (int i = 0; i < N; ++i) + nonlocal_a[i] = 5; + nonlocal_arg = 5; + +#pragma acc kernels loop \ + gang(num:nonlocal_arg) worker(nonlocal_arg) vector(nonlocal_arg) \ + wait async(nonlocal_arg) + for (nonlocal_i = 0; nonlocal_i < N; ++nonlocal_i) + { +#pragma acc cache (nonlocal_a[nonlocal_i:3]) + nonlocal_a[nonlocal_i] = 100; +#pragma acc loop seq tile(2) + for (nonlocal_j = 0; nonlocal_j < N; ++nonlocal_j) + ; +#pragma acc loop auto independent tile(3) + for (nonlocal_j = 0; nonlocal_j < N; ++nonlocal_j) + ; + } + +#pragma acc kernels loop \ + gang(static:nonlocal_arg) worker(nonlocal_arg) vector(nonlocal_arg) \ + wait(nonlocal_arg, nonlocal_arg + 1, nonlocal_arg + 2) async + for (nonlocal_i = 0; nonlocal_i < N; ++nonlocal_i) + { +#pragma acc cache (nonlocal_a[nonlocal_i:2]) + nonlocal_a[nonlocal_i] = 100; +#pragma acc loop seq tile(*) + for (nonlocal_j = 0; nonlocal_j < N; ++nonlocal_j) + ; +#pragma acc loop auto independent tile(*) + for (nonlocal_j = 0; nonlocal_j < N; ++nonlocal_j) + ; + } + } + + local (); + nonlocal (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/goacc/nested-function-2.c b/gcc/testsuite/gcc.dg/goacc/nested-function-2.c new file mode 100644 index 00000000000..70c9ec8ebfa --- /dev/null +++ b/gcc/testsuite/gcc.dg/goacc/nested-function-2.c @@ -0,0 +1,45 @@ +/* Exercise nested function decomposition, gcc/tree-nested.c. */ + +int +main (void) +{ + int j = 0, k = 6, l = 7, m = 8; + void simple (void) + { + int i; +#pragma acc parallel + { +#pragma acc loop + for (i = 0; i < m; i+= k) + j = (m + i - j) * l; + } + } + void collapse (void) + { + int x, y, z; +#pragma acc parallel + { +#pragma acc loop collapse (3) + for (x = 0; x < k; x++) + for (y = -5; y < l; y++) + for (z = 0; z < m; z++) + j += x + y + z; + } + } + void reduction (void) + { + int x, y, z; +#pragma acc parallel reduction (+:j) + { +#pragma acc loop reduction (+:j) collapse (3) + for (x = 0; x < k; x++) + for (y = -5; y < l; y++) + for (z = 0; z < m; z++) + j += x + y + z; + } + } + simple(); + collapse(); + reduction(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/goacc/pr71373.c b/gcc/testsuite/gcc.dg/goacc/pr71373.c new file mode 100644 index 00000000000..9381752cc9d --- /dev/null +++ b/gcc/testsuite/gcc.dg/goacc/pr71373.c @@ -0,0 +1,41 @@ +/* Unintentional nested function usage. */ +/* Due to missing right braces '}', the following functions are parsed as + nested functions. This ran into an ICE. */ + +void foo (void) +{ + #pragma acc parallel + { + #pragma acc loop independent + for (int i = 0; i < 16; i++) + ; + // Note right brace '}' commented out here. + //} +} +void bar (void) +{ +} + +// Adding right brace '}' here, to make this compile. +} + + +// ..., and the other way round: + +void BAR (void) +{ +// Note right brace '}' commented out here. +//} + +void FOO (void) +{ + #pragma acc parallel + { + #pragma acc loop independent + for (int i = 0; i < 16; i++) + ; + } +} + +// Adding right brace '}' here, to make this compile. +} diff --git a/gcc/testsuite/gcc.dg/guality/pr68037-1.c b/gcc/testsuite/gcc.dg/guality/pr68037-1.c index c3ea645e92c..74f61ec5f96 100644 --- a/gcc/testsuite/gcc.dg/guality/pr68037-1.c +++ b/gcc/testsuite/gcc.dg/guality/pr68037-1.c @@ -14,6 +14,8 @@ typedef unsigned int uword_t __attribute__ ((mode (__word__))); #define STRING(x) XSTRING(x) #define XSTRING(x) #x +#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname struct interrupt_frame { @@ -53,7 +55,7 @@ main () push $" STRING (CS) "; \ push $" STRING (IP) "; \ push $" STRING (ERROR) "; \ - jmp fn"); + jmp " ASMNAME ("fn")); return 0; } diff --git a/gcc/testsuite/gcc.dg/guality/pr68037-2.c b/gcc/testsuite/gcc.dg/guality/pr68037-2.c index 6f7e920d106..c3cd73d2a65 100644 --- a/gcc/testsuite/gcc.dg/guality/pr68037-2.c +++ b/gcc/testsuite/gcc.dg/guality/pr68037-2.c @@ -13,6 +13,8 @@ typedef unsigned int uword_t __attribute__ ((mode (__word__))); #define STRING(x) XSTRING(x) #define XSTRING(x) #x +#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname struct interrupt_frame { @@ -49,7 +51,7 @@ main () push $" STRING (FLAGS) "; \ push $" STRING (CS) "; \ push $" STRING (IP) "; \ - jmp fn"); + jmp " ASMNAME ("fn")); return 0; } diff --git a/gcc/testsuite/gcc.dg/guality/pr68037-3.c b/gcc/testsuite/gcc.dg/guality/pr68037-3.c index 504a931eb33..6e054720f47 100644 --- a/gcc/testsuite/gcc.dg/guality/pr68037-3.c +++ b/gcc/testsuite/gcc.dg/guality/pr68037-3.c @@ -16,6 +16,8 @@ typedef int aligned __attribute__((aligned(64))); #define STRING(x) XSTRING(x) #define XSTRING(x) #x +#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname struct interrupt_frame { @@ -65,7 +67,7 @@ main () push $" STRING (FLAGS) "; \ push $" STRING (CS) "; \ push $" STRING (IP) "; \ - jmp fn"); + jmp " ASMNAME ("fn")); return 0; } diff --git a/gcc/testsuite/gcc.dg/init-bad-8.c b/gcc/testsuite/gcc.dg/init-bad-8.c index b321323219c..f7b0f7f6886 100644 --- a/gcc/testsuite/gcc.dg/init-bad-8.c +++ b/gcc/testsuite/gcc.dg/init-bad-8.c @@ -6,5 +6,5 @@ struct S { int i, j, k; }; void foo (void) { - struct S s = { .i = 1, .j = 2, .l = 4}; /* { dg-error "34:unknown field .l. specified in initializer" } */ + struct S s = { .i = 1, .j = 2, .l = 4}; /* { dg-error "35: .struct S. has no member named .l." } */ } diff --git a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c index c5504f8eed4..c6dfecd3245 100644 --- a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c +++ b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c @@ -14,7 +14,7 @@ returns_struct (int i) int __attribute__((noinline,noclone)) test_1 (int i) { - return returns_struct (i * 5).i; /* { dg-error "cannot tail-call: callee returns a structure" } */ + return returns_struct (i * 5).i; /* { dg-error "cannot tail-call: " } */ } int __attribute__((noinline,noclone)) @@ -29,14 +29,14 @@ int __attribute__((noinline,noclone)) test_2_caller (int i) { struct box b; - return test_2_callee (i + 1, b); /* { dg-error "cannot tail-call: callee required more stack slots than the caller" } */ + return test_2_callee (i + 1, b); /* { dg-error "cannot tail-call: " } */ } extern void setjmp (void); void test_3 (void) { - setjmp (); /* { dg-error "cannot tail-call: callee returns twice" } */ + setjmp (); /* { dg-error "cannot tail-call: " } */ } void @@ -45,7 +45,7 @@ test_4 (void) void nested (void) { } - nested (); /* { dg-error "cannot tail-call: nested function" } */ + nested (); /* { dg-error "cannot tail-call: " } */ } typedef void (fn_ptr_t) (void); @@ -54,5 +54,5 @@ volatile fn_ptr_t fn_ptr; void test_5 (void) { - fn_ptr (); /* { dg-error "cannot tail-call: callee does not return" } */ + fn_ptr (); /* { dg-error "cannot tail-call: " } */ } diff --git a/gcc/testsuite/gcc.dg/pr70859.c b/gcc/testsuite/gcc.dg/pr70859.c index 0a3c8437c66..e71b05237b0 100644 --- a/gcc/testsuite/gcc.dg/pr70859.c +++ b/gcc/testsuite/gcc.dg/pr70859.c @@ -41,19 +41,19 @@ fn0 (int n) int fn1 (void) { - if (__builtin_constant_p ()) /* { dg-error "7:not enough" } */ + if (__builtin_constant_p ()) /* { dg-error "7:too few" } */ return 0; if (__builtin_constant_p (1, 2)) /* { dg-error "7:too many" } */ return 1; - if (__builtin_isfinite ()) /* { dg-error "7:not enough" } */ + if (__builtin_isfinite ()) /* { dg-error "7:too few" } */ return 3; if (__builtin_isfinite (1, 2)) /* { dg-error "7:too many" } */ return 4; - if (__builtin_isless (0)) /* { dg-error "7:not enough" } */ + if (__builtin_isless (0)) /* { dg-error "7:too few" } */ return 5; if (__builtin_isless (1, 2, 3)) /* { dg-error "7:too many" } */ return 6; - if (__builtin_fpclassify (1, 2, 3, 4, 5)) /* { dg-error "7:not enough" } */ + if (__builtin_fpclassify (1, 2, 3, 4, 5)) /* { dg-error "7:too few" } */ return 7; if (__builtin_fpclassify (1, 2, 3, 4, 5, r, 6)) /* { dg-error "7:too many" } */ return 8; @@ -61,7 +61,7 @@ fn1 (void) return 9; if (__builtin_assume_aligned (p, r, p, p)) /* { dg-error "7:too many" } */ return 10; - if (__builtin_add_overflow ()) /* { dg-error "7:not enough" } */ + if (__builtin_add_overflow ()) /* { dg-error "7:too few" } */ return 11; if (__builtin_add_overflow (1, 2, 3, &r)) /* { dg-error "7:too many" } */ return 12; diff --git a/gcc/testsuite/gcc.dg/pr71478.c b/gcc/testsuite/gcc.dg/pr71478.c new file mode 100644 index 00000000000..17ec7ec62a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr71478.c @@ -0,0 +1,19 @@ +/* PR middle-end/71478 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -Wno-psabi -w" } */ + +typedef unsigned int __attribute__ ((vector_size (8))) uv2si; +typedef int __attribute__ ((vector_size (8))) v2si; + +uv2si bar (v2si); + +uv2si +foo (void) +{ + v2si x = (v2si) (0x00007fff80008000UL); + v2si y = (v2si) (0x8f997fff00000000UL); + uv2si z = x >= y; + uv2si k = bar (x); + uv2si j = k * __builtin_shuffle (z, z, (uv2si) {1, 3}); + return k * j; +} diff --git a/gcc/testsuite/gcc.dg/predict-1.c b/gcc/testsuite/gcc.dg/predict-1.c index 94f6b0190a1..10d62bac5d5 100644 --- a/gcc/testsuite/gcc.dg/predict-1.c +++ b/gcc/testsuite/gcc.dg/predict-1.c @@ -23,4 +23,4 @@ void foo (int bound) } } -/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 2.0%" 5 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "guess loop iv compare heuristics of edge\[^:\]*: 2.0%" 5 "profile_estimate"} } */ diff --git a/gcc/testsuite/gcc.dg/predict-2.c b/gcc/testsuite/gcc.dg/predict-2.c index f2fc49ddc47..aa915688c68 100644 --- a/gcc/testsuite/gcc.dg/predict-2.c +++ b/gcc/testsuite/gcc.dg/predict-2.c @@ -23,4 +23,4 @@ void foo (int base, int bound) } } -/* { dg-final { scan-tree-dump-not "loop iv compare heuristics" "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-not "guess loop iv compare heuristics of edge\[^:\]*:" "profile_estimate"} } */ diff --git a/gcc/testsuite/gcc.dg/predict-3.c b/gcc/testsuite/gcc.dg/predict-3.c index 08db59a559f..7274963b943 100644 --- a/gcc/testsuite/gcc.dg/predict-3.c +++ b/gcc/testsuite/gcc.dg/predict-3.c @@ -25,4 +25,4 @@ void foo (int bound) } } -/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 98.0%" 3 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "guess loop iv compare heuristics of edge\[^:\]*: 98.0%" 3 "profile_estimate"} } */ diff --git a/gcc/testsuite/gcc.dg/predict-4.c b/gcc/testsuite/gcc.dg/predict-4.c index 3e7fb7488a9..2ac2ec5721d 100644 --- a/gcc/testsuite/gcc.dg/predict-4.c +++ b/gcc/testsuite/gcc.dg/predict-4.c @@ -15,4 +15,4 @@ void foo (int bound) } } -/* { dg-final { scan-tree-dump "loop iv compare heuristics: 50.0%" "profile_estimate"} } */ +/* { dg-final { scan-tree-dump " loop iv compare heuristics of edge\[^:\]*: 50.0%" "profile_estimate"} } */ diff --git a/gcc/testsuite/gcc.dg/predict-5.c b/gcc/testsuite/gcc.dg/predict-5.c index 32178a8ea5f..135081de2a4 100644 --- a/gcc/testsuite/gcc.dg/predict-5.c +++ b/gcc/testsuite/gcc.dg/predict-5.c @@ -21,4 +21,4 @@ void foo (int base, int bound) } } -/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 98.0%" 4 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "guess loop iv compare heuristics of edge\[^:\]*: 98.0%" 4 "profile_estimate"} } */ diff --git a/gcc/testsuite/gcc.dg/predict-6.c b/gcc/testsuite/gcc.dg/predict-6.c index 16ad16fdb25..104683f7f43 100644 --- a/gcc/testsuite/gcc.dg/predict-6.c +++ b/gcc/testsuite/gcc.dg/predict-6.c @@ -21,4 +21,4 @@ void foo (int base, int bound) } } -/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 2.0%" 4 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "guess loop iv compare heuristics of edge\[^:\]*: 2.0%" 4 "profile_estimate"} } */ diff --git a/gcc/testsuite/gcc.dg/predict-7.c b/gcc/testsuite/gcc.dg/predict-7.c index a0ea37bdfa8..fe34ca5f744 100644 --- a/gcc/testsuite/gcc.dg/predict-7.c +++ b/gcc/testsuite/gcc.dg/predict-7.c @@ -13,4 +13,4 @@ void foo (int base) bar (i); } -/* { dg-final { scan-tree-dump-times "loop branch heuristics" 0 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "loop branch heuristics of edge\[^:\]*" 0 "profile_estimate"} } */ diff --git a/gcc/testsuite/gcc.dg/spellcheck-fields-3.c b/gcc/testsuite/gcc.dg/spellcheck-fields-3.c new file mode 100644 index 00000000000..003a0b5ea26 --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-fields-3.c @@ -0,0 +1,66 @@ +/* { dg-do compile } */ +/* { dg-options "-fdiagnostics-show-caret -std=c99" } */ + +/* Tests of incorrect name initializers. + Verify that we get underlines and, where appropriate, fixit hints. */ + +struct foo +{ + int foo; + int bar; +}; + +union u +{ + int color; + int shape; +}; + +/* Old-style named initializers. */ + +struct foo old_style_f = { + foa: 1, /* { dg-error ".struct foo. has no member named .foa.; did you mean .foo." } */ +/* { dg-begin-multiline-output "" } + foa: 1, + ^~~ + foo + { dg-end-multiline-output "" } */ + + this_does_not_match: 3 /* { dg-error ".struct foo. has no member named .this_does_not_match." } */ + +/* { dg-begin-multiline-output "" } + this_does_not_match: 3 + ^~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ +}; + +union u old_style_u = { colour: 3 }; /* { dg-error ".union u. has no member named .colour.; did you mean .color.?" } */ +/* { dg-begin-multiline-output "" } + union u old_style_u = { colour: 3 }; + ^~~~~~ + color + { dg-end-multiline-output "" } */ + +/* C99-style named initializers. */ + +struct foo c99_style_f = { + .foa = 1, /* { dg-error ".struct foo. has no member named .foa.; did you mean .foo." } */ +/* { dg-begin-multiline-output "" } + .foa = 1, + ^~~ + foo + { dg-end-multiline-output "" } */ + + .this_does_not_match = 3 /* { dg-error ".struct foo. has no member named .this_does_not_match." } */ +/* { dg-begin-multiline-output "" } + .this_does_not_match = 3 + ^~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ +}; + +union u c99_style_u = { .colour=3 }; /* { dg-error ".union u. has no member named .colour.; did you mean .color.?" } */ +/* { dg-begin-multiline-output "" } + union u c99_style_u = { .colour=3 }; + ^~~~~~ + color + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/stack-usage-1.c b/gcc/testsuite/gcc.dg/stack-usage-1.c index 7864c6a282b..bdc56565d97 100644 --- a/gcc/testsuite/gcc.dg/stack-usage-1.c +++ b/gcc/testsuite/gcc.dg/stack-usage-1.c @@ -64,7 +64,11 @@ # define SIZE 240 # endif #elif defined (__AVR__) -# define SIZE 254 +#if defined (__AVR_3_BYTE_PC__ ) +# define SIZE 251 /* 256 - 2 bytes for Y - 3 bytes for return address */ +#else +# define SIZE 252 /* 256 - 2 bytes for Y - 2 bytes for return address */ +#endif #elif defined (__s390x__) # define SIZE 96 /* 256 - 160 bytes for register save area */ #elif defined (__s390__) diff --git a/gcc/testsuite/gcc.dg/torture/float128-nan.c b/gcc/testsuite/gcc.dg/torture/float128-nan.c new file mode 100644 index 00000000000..b5706234987 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/float128-nan.c @@ -0,0 +1,101 @@ +/* Test __float128 NaN generation. */ +/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-effective-target fenv_exceptions } */ +/* { dg-options "" } */ + +#include <fenv.h> +#include <stdbool.h> + +typedef unsigned long long int uint64_t; + +typedef union +{ + __float128 value; + + struct +#ifdef __MINGW32__ + /* Make sure we are using gnu-style bitfield handling. */ + __attribute__ ((gcc_struct)) +#endif + { +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + unsigned negative:1; + unsigned exponent:15; + unsigned quiet_nan:1; + uint64_t mant_high:47; + uint64_t mant_low:64; +#else + uint64_t mant_low:64; + uint64_t mant_high:47; + unsigned quiet_nan:1; + unsigned exponent:15; + unsigned negative:1; +#endif + } nan; + +} ieee854_float128; + +bool +__attribute__((noinline, noclone)) +check_nan (__float128 val, bool quiet) +{ + ieee854_float128 u; + volatile __float128 tmp; + + u.value = val; + + if (u.nan.exponent != 0x7fff + || (u.nan.quiet_nan | u.nan.mant_high | u.nan.mant_low) == 0 + || u.nan.quiet_nan != quiet) + return false; + + if (!__builtin_isnan (u.value)) + return false; + + feclearexcept (FE_INVALID); + + tmp = u.value + u.value; + + if ((fetestexcept (FE_INVALID) != 0) == quiet) + return false; + + return true; +} + +int +main (void) +{ + __float128 nan; + + nan = __builtin_nanq (""); + + if (!check_nan (nan, true)) + __builtin_abort (); + + nan = __builtin_nanq ("0x0"); + + if (!check_nan (nan, true)) + __builtin_abort (); + + nan = __builtin_nanq ("0x1"); + + if (!check_nan (nan, true)) + __builtin_abort (); + + nan = __builtin_nansq (""); + + if (!check_nan (nan, false)) + __builtin_abort (); + + nan = __builtin_nansq ("0x0"); + + if (!check_nan (nan, false)) + __builtin_abort (); + + nan = __builtin_nansq ("0x1"); + + if (!check_nan (nan, false)) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr68037-1.c b/gcc/testsuite/gcc.dg/torture/pr68037-1.c index 15fe08c156f..23d7c6f397a 100644 --- a/gcc/testsuite/gcc.dg/torture/pr68037-1.c +++ b/gcc/testsuite/gcc.dg/torture/pr68037-1.c @@ -14,6 +14,8 @@ typedef unsigned int uword_t __attribute__ ((mode (__word__))); #define STRING(x) XSTRING(x) #define XSTRING(x) #x +#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname struct interrupt_frame { @@ -53,6 +55,6 @@ main () push $" STRING (CS) "; \ push $" STRING (IP) "; \ push $" STRING (ERROR) "; \ - jmp fn"); + jmp " ASMNAME ("fn")); return 0; } diff --git a/gcc/testsuite/gcc.dg/torture/pr68037-2.c b/gcc/testsuite/gcc.dg/torture/pr68037-2.c index 00ba7d45464..18f98442ceb 100644 --- a/gcc/testsuite/gcc.dg/torture/pr68037-2.c +++ b/gcc/testsuite/gcc.dg/torture/pr68037-2.c @@ -13,6 +13,8 @@ typedef unsigned int uword_t __attribute__ ((mode (__word__))); #define STRING(x) XSTRING(x) #define XSTRING(x) #x +#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname struct interrupt_frame { @@ -49,6 +51,6 @@ main () push $" STRING (FLAGS) "; \ push $" STRING (CS) "; \ push $" STRING (IP) "; \ - jmp fn"); + jmp " ASMNAME ("fn")); return 0; } diff --git a/gcc/testsuite/gcc.dg/torture/pr68037-3.c b/gcc/testsuite/gcc.dg/torture/pr68037-3.c index abf8adbc734..86324f1a8fb 100644 --- a/gcc/testsuite/gcc.dg/torture/pr68037-3.c +++ b/gcc/testsuite/gcc.dg/torture/pr68037-3.c @@ -16,6 +16,8 @@ typedef int aligned __attribute__((aligned(64))); #define STRING(x) XSTRING(x) #define XSTRING(x) #x +#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname struct interrupt_frame { @@ -65,6 +67,6 @@ main () push $" STRING (FLAGS) "; \ push $" STRING (CS) "; \ push $" STRING (IP) "; \ - jmp fn"); + jmp " ASMNAME ("fn")); return 0; } diff --git a/gcc/testsuite/gcc.dg/torture/pr68067-1.c b/gcc/testsuite/gcc.dg/torture/pr68067-1.c index a7b6aa041d9..f8ad3ca0168 100644 --- a/gcc/testsuite/gcc.dg/torture/pr68067-1.c +++ b/gcc/testsuite/gcc.dg/torture/pr68067-1.c @@ -1,4 +1,5 @@ /* { dg-do run } */ +/* { dg-require-effective-target int32plus } */ int main() { diff --git a/gcc/testsuite/gcc.dg/torture/pr68067-2.c b/gcc/testsuite/gcc.dg/torture/pr68067-2.c index 38a459bf7f1..e03bf227301 100644 --- a/gcc/testsuite/gcc.dg/torture/pr68067-2.c +++ b/gcc/testsuite/gcc.dg/torture/pr68067-2.c @@ -1,4 +1,5 @@ /* { dg-do run } */ +/* { dg-require-effective-target int32plus } */ int main() { diff --git a/gcc/testsuite/gcc.dg/torture/pr71462.c b/gcc/testsuite/gcc.dg/torture/pr71462.c new file mode 100644 index 00000000000..390b88673e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr71462.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ + +short a; +long b; +void fn1() +{ + int c = a = 1; + for (; a; a++) + { + for (; 9 <= 8;) + for (;;) { + a = 20; + for (; a <= 35; a++) + ; +line:; + } + if ((c += 264487869) == 9) + { + unsigned *d = 0; + for (; b;) + d = (unsigned *)&c; + if (d) + for (;;) + ; + } + } + goto line; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr71477.c b/gcc/testsuite/gcc.dg/torture/pr71477.c new file mode 100644 index 00000000000..c6d0c31817b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr71477.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ + +#define N 6 +int a; +void fn1() +{ + int k = 0; + for (; k < N;) + for (a = 0; a < N; k++) + a = k + N; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr71407.c b/gcc/testsuite/gcc.dg/vect/pr71407.c new file mode 100644 index 00000000000..761990de9f3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr71407.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +int a, c, d; +short b; + +void +fn1 () +{ + int e; + for (; c; c++) + { + for (; a; a++) + b = (short) a || e; + e = d; + } +} diff --git a/gcc/testsuite/gcc.dg/vect/pr71416-1.c b/gcc/testsuite/gcc.dg/vect/pr71416-1.c new file mode 100644 index 00000000000..8a2854889f9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr71416-1.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ + +short a; +char b, e; +static short c; +int d, f; +int main() { + short g; + for (; e; ++e) { + d = a; + f = 0; + if (b) + d = f = g >= c; + } + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/vect/pr71416-2.c b/gcc/testsuite/gcc.dg/vect/pr71416-2.c new file mode 100644 index 00000000000..d846ef17ef1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr71416-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +int a, b, d, e, f, g; +int *c; +void fn2 (int *); +void fn1() { fn2(&e); } + +void fn2(int *p1) { + for (;;) { + for (; a; a++) + if (*p1 = g || --f, b) + if (*c) + d = *p1; + if (*p1) + break; + } +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp b/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp index ad92994fe6c..9998d0bda23 100644 --- a/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp @@ -38,6 +38,16 @@ foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] { } } +# Test parameter receiving. +set additional_flags_for_rec $additional_flags +append additional_flags_for_rec " -fno-inline" +foreach src [lsort [glob -nocomplain $srcdir/$subdir/rec_*.c]] { + if {[runtest_file_p $runtests $src]} { + c-torture-execute [list $src] \ + $additional_flags_for_rec + } +} + # Test unnamed argument retrieval via the va_arg macro. foreach src [lsort [glob -nocomplain $srcdir/$subdir/va_arg-*.c]] { if {[runtest_file_p $runtests $src]} { diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-5.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-5.c new file mode 100644 index 00000000000..1b42c92ae59 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-5.c @@ -0,0 +1,44 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +extern void abort (void); + +typedef __attribute__ ((__aligned__ (8))) int alignedint; + +alignedint a = 11; +alignedint b = 13; +alignedint c = 17; +alignedint d = 19; +alignedint e = 23; +alignedint f = 29; +alignedint g = 31; +alignedint h = 37; +alignedint i = 41; +alignedint j = 43; + +void +test_passing_many_alignedint (alignedint x0, alignedint x1, alignedint x2, + alignedint x3, alignedint x4, alignedint x5, + alignedint x6, alignedint x7, alignedint stack, + alignedint stack8) +{ + if (x0 != a + || x1 != b + || x2 != c + || x3 != d + || x4 != e + || x5 != f + || x6 != g + || x7 != h + || stack != i + || stack8 !=j) + abort (); +} + +int +main (int argc, char **argv) +{ + test_passing_many_alignedint (a, b, c, d, e, f, g, h, i, j); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-6.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-6.c new file mode 100644 index 00000000000..a8d8b1bd1cb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-6.c @@ -0,0 +1,45 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + +/* The underlying struct here has alignment 8. */ +typedef struct __attribute__ ((__aligned__ (16))) + { + long x; + long y; + } overaligned; + +overaligned a = { 2, 3 }; +overaligned b = { 5, 8 }; +overaligned c = { 13, 21 }; + +void +test_passing_overaligned_struct (int x0, overaligned x1, int x3, int x4, + overaligned x5, int x7, int stack, + overaligned stack8) +{ + if (x0 != 7 || x3 != 9 || x4 != 11 || x7 != 15 || stack != 10) + abort (); + if (memcmp ((void *) &x1, (void *)&a, sizeof (overaligned))) + abort (); + if (memcmp ((void *) &x5, (void *)&b, sizeof (overaligned))) + abort (); + if (memcmp ((void *)&stack8, (void *)&c, sizeof (overaligned))) + abort (); + long addr = ((long) &stack8) & 15; + if (addr != 0) + { + __builtin_printf ("Alignment was %d\n", addr); + abort (); + } +} + +int +main (int argc, char **argv) +{ + test_passing_overaligned_struct (7, a, 9, 11, b, 15, 10, c); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-7.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-7.c new file mode 100644 index 00000000000..61e3c118183 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-7.c @@ -0,0 +1,47 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + +struct s + { + long x; + long y; + }; + +/* This still has size 16, so is still passed by value. */ +typedef __attribute__ ((__aligned__ (32))) struct s overaligned; + +/* A few structs, at 32-byte-aligned memory locations. */ +overaligned a = { 2, 3 }; +overaligned b = { 5, 8 }; +overaligned c = { 13, 21 }; + +void +test_pass_by_value (int x0, overaligned x1, int x3, int x4, overaligned x5, + int x7, int stack, overaligned stack8) +{ + if (x0 != 7 || x3 != 9 || x4 != 11 || x7 != 15 || stack != 10) + abort (); + if (memcmp ((void *) &x1, (void *)&a, sizeof (overaligned))) + abort (); + if (memcmp ((void *) &x5, (void *)&b, sizeof (overaligned))) + abort (); + if (memcmp ((void *)&stack8, (void *)&c, sizeof (overaligned))) + abort (); + long addr = ((long) &stack8) & 15; + if (addr != 0) + { + __builtin_printf ("Alignment was %d\n", addr); + abort (); + } +} + +int +main (int argc, char **argv) +{ + test_pass_by_value (7, a, 9, 11, b, 15, 10, c); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-8.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-8.c new file mode 100644 index 00000000000..c9351802191 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-8.c @@ -0,0 +1,37 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + +/* The alignment also gives this size 32, so will be passed by reference. */ +typedef struct __attribute__ ((__aligned__ (32))) + { + long x; + long y; + } overaligned; + +overaligned a = { 2, 3 }; + +void +test_pass_by_ref (int x0, overaligned x1, int x2) +{ + if (x0 != 7 || x2 != 9) + abort (); + if (memcmp ((void *) &x1, (void *)&a, sizeof (overaligned))) + abort (); + long addr = ((long) &x1) & 31; + if (addr != 0) + { + __builtin_printf ("Alignment was %d\n", addr); + abort (); + } +} + +int +main (int argc, char **argv) +{ + test_pass_by_ref (7, a, 9); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-9.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-9.c new file mode 100644 index 00000000000..81139f58269 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align-9.c @@ -0,0 +1,41 @@ +/* Test AAPCS layout (alignment) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n); +extern void abort (void); + +struct s + { + /* This forces the alignment and size of the struct to 16. */ + __attribute__ ((__aligned__ (16))) long x; + int y; + /* 4 bytes padding. */ + }; + +typedef struct s __attribute__ ((__aligned__ (8))) underaligned; + +underaligned a = { 1, 4 }; +underaligned b = { 9, 16 }; +underaligned c = { 25, 36 }; + +void +test_underaligned_struct (int x0, underaligned x2, int x4, underaligned x6, + int stack, underaligned stack16) +{ + if (x0 != 3 || x4 != 5 || stack != 7) + abort (); + if (memcmp ((void *) &x2, (void *)&a, sizeof (underaligned))) + abort (); + if (memcmp ((void *)&x6, (void *)&b, sizeof (underaligned))) + abort (); + if (memcmp ((void *)&stack16, (void *)&c, sizeof (underaligned))) + abort (); +} + +int +main (int argc, char **argv) +{ + test_underaligned_struct (3, a, 5, b, 7, c); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-1.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-1.c new file mode 100644 index 00000000000..109ddc214e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-1.c @@ -0,0 +1,38 @@ +/* Test AAPCS layout (alignment of varargs) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#include <stdarg.h> + +extern void abort (void); + +typedef __attribute__ ((__aligned__ (16))) long alignedlong; + +void +test_pass_overaligned_long_vaargs (long l, ...) +{ + va_list va; + va_start (va, l); + /* Arguments should be passed in the same registers as if they were ints. */ + while (l-- > 0) + if (va_arg (va, long) != l) + abort (); + va_end (va); +} + +int +main (int argc, char **argv) +{ + alignedlong a = 9; + alignedlong b = 8; + alignedlong c = 7; + alignedlong d = 6; + alignedlong e = 5; + alignedlong f = 4; + alignedlong g = 3; + alignedlong h = 2; + alignedlong i = 1; + alignedlong j = 0; + test_pass_overaligned_long_vaargs (a, b, c, d, e, f, g, h, i, j); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-2.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-2.c new file mode 100644 index 00000000000..dc4eb2fb382 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/rec_align_vaarg-2.c @@ -0,0 +1,28 @@ +/* Test AAPCS layout (alignment of varargs) for callee. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#include <stdarg.h> + +extern void abort (void); + +typedef __attribute__ ((__aligned__ (16))) int alignedint; + +void +test_pass_overaligned_int_vaargs (int i, ...) +{ + va_list va; + va_start (va, i); + /* alignedint should be pulled out of regs/stack just like an int. */ + while (i-- > 0) + if (va_arg (va, alignedint) != i) + abort (); + va_end (va); +} + +int +main (int argc, char **argv) +{ + test_pass_overaligned_int_vaargs (9, 8, 7, 6, 5, 4, 3, 2, 1, 0); + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-5.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-5.c new file mode 100644 index 00000000000..ac5673ee5c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-5.c @@ -0,0 +1,35 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "test_align-5.c" + +typedef __attribute__ ((__aligned__ (16))) long alignedint; + +alignedint a = 11; +alignedint b = 13; +alignedint c = 17; +alignedint d = 19; +alignedint e = 23; +alignedint f = 29; +alignedint g = 31; +alignedint h = 37; +alignedint i = 41; +alignedint j = 43; + +#include "abitest.h" +#else + ARG (alignedint, a, X0) + /* Attribute suggests R2, but we should use only natural alignment: */ + ARG (alignedint, b, X1) + ARG (alignedint, c, X2) + ARG (alignedint, d, X3) + ARG (alignedint, e, X4) + ARG (alignedint, f, X5) + ARG (alignedint, g, X6) + ARG (alignedint, h, X7) + ARG (alignedint, i, STACK) + /* Attribute would suggest STACK + 16 but should be ignored: */ + LAST_ARG (alignedint, j, STACK + 8) +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-6.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-6.c new file mode 100644 index 00000000000..20cbd941939 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-6.c @@ -0,0 +1,36 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "test_align-6.c" + +/* The underlying struct here has alignment 8. */ +typedef struct __attribute__ ((__aligned__ (16))) + { + long x; + long y; + } overaligned; + +/* A couple of instances, at 16-byte-aligned memory locations. */ +overaligned a = { 2, 3 }; +overaligned b = { 5, 8 }; +overaligned c = { 13, 21 }; + +#include "abitest.h" +#else + ARG (int, 7, W0) + /* Natural alignment should be 8. */ + ARG (overaligned, a, X1) + ARG (int, 9, W3) + ARG (int, 11, W4) + ARG (overaligned, b, X5) + ARG (int, 15, W7) +#ifndef __AAPCS64_BIG_ENDIAN__ + ARG (int, 10, STACK) +#else + ARG (int, 10, STACK + 4) +#endif + /* Natural alignment should be 8. */ + LAST_ARG (overaligned, c, STACK + 8) +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-7.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-7.c new file mode 100644 index 00000000000..6af422f27e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-7.c @@ -0,0 +1,38 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "test_align-7.c" + +struct s + { + long x; + long y; + }; + +/* This still has size 16, so is still passed by value. */ +typedef __attribute__ ((__aligned__ (32))) struct s overaligned; + +/* A few structs, at 32-byte-aligned memory locations. */ +overaligned a = { 2, 3 }; +overaligned b = { 5, 8 }; +overaligned c = { 13, 21 }; + +#include "abitest.h" +#else + ARG (int, 7, W0) + /* Alignment should be 8. */ + ARG (overaligned, a, X1) + ARG (int, 9, W3) + ARG (int, 11, W4) + ARG (overaligned, b, X5) + ARG (int, 15, W7) +#ifndef __AAPCS64_BIG_ENDIAN__ + ARG (int, 10, STACK) +#else + ARG (int, 10, STACK + 4) +#endif + /* Natural alignment should be 8. */ + LAST_ARG (overaligned, c, STACK + 8) +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-8.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-8.c new file mode 100644 index 00000000000..ad4dfe4b62c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-8.c @@ -0,0 +1,33 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "test_align-8.c" + +/* The alignment also gives this size 32, so will be passed by reference. */ +typedef struct __attribute__ ((__aligned__ (32))) + { + long x; + long y; + } overaligned; + +#define EXPECTED_STRUCT_SIZE 32 +extern void link_failure (void); +int +foo () +{ + /* Optimization gets rid of this before linking. */ + if (sizeof (overaligned) != EXPECTED_STRUCT_SIZE) + link_failure (); +} + +overaligned a = { 2, 3 }; + +#include "abitest.h" +#else + ARG (int, 7, W0) + /* Alignment should be 8. */ + PTR (overaligned, a, X1) + LAST_ARG (int, 9, W2) +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-9.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-9.c new file mode 100644 index 00000000000..0f5fa352a91 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align-9.c @@ -0,0 +1,47 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "test_align-9.c" + +struct s + { + /* This forces the alignment and size of the struct to 16. */ + __attribute__ ((__aligned__ (16))) long x; + int y; + /* 4 bytes padding. */ + }; + +typedef struct s __attribute__ ((__aligned__ (8))) underaligned; + +#define EXPECTED_STRUCT_SIZE 16 +extern void link_failure (void); +int +foo () +{ + /* Optimization gets rid of this before linking. */ + if (sizeof (struct s) != EXPECTED_STRUCT_SIZE) + link_failure (); +} + +underaligned a = { 1, 4 }; +underaligned b = { 9, 16 }; +underaligned c = { 25, 36 }; + +#include "abitest.h" +#else + ARG (int, 3, W0) + /* Object alignment is 16, so skip X1. */ + ARG (underaligned, a, X2) + ARG (int, 5, W4) + /* Object alignment is 16, so skip X5. */ + ARG (underaligned, b, X6) +#ifndef __AAPCS64_BIG_ENDIAN__ + ARG (int, 7, STACK) +#else + ARG (int, 7, STACK + 4) +#endif + /* Natural alignment should be 16. */ + LAST_ARG (underaligned, c, STACK + 16) +#endif diff --git a/gcc/testsuite/gcc.target/arm/pr37780_1.c b/gcc/testsuite/gcc.target/arm/pr37780_1.c index b954fe5ceb8..8e069200e9f 100644 --- a/gcc/testsuite/gcc.target/arm/pr37780_1.c +++ b/gcc/testsuite/gcc.target/arm/pr37780_1.c @@ -2,8 +2,9 @@ being defined at zero. */ /* { dg-do compile } */ -/* { dg-require-effective-target arm_arch_v5_ok } */ +/* { dg-require-effective-target arm_arch_v6t2_ok } */ /* { dg-options "-O2" } */ +/* { dg-add-options arm_arch_v6t2 } */ int fooctz (int i) diff --git a/gcc/testsuite/gcc.target/i386/interrupt-12.c b/gcc/testsuite/gcc.target/i386/interrupt-12.c index b04de5fa75d..23780050d76 100644 --- a/gcc/testsuite/gcc.target/i386/interrupt-12.c +++ b/gcc/testsuite/gcc.target/i386/interrupt-12.c @@ -15,16 +15,16 @@ fn1 (void *frame, uword_t error) /* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)(b|c|d)x" } } */ /* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)si" } } */ /* { dg-final { scan-assembler-not "(push|pop)l\[\\t \]*%edi" { target ia32 } } } */ -/* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%rax" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%rax" { target { { ! ia32 } && nonpic } } } } */ /* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%r\[0-9\]+" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:r|e)bp" 1 } } */ -/* { dg-final { scan-assembler-times "leave" 1 } } */ +/* { dg-final { scan-assembler-times "leave" 1 { target nonpic } } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%eax" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-times "movl\[\\t \]*-4\\(%ebp\\),\[\\t \]*%eax" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-times "pushq\[\\t \]*%rdi" 1 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "movq\[\\t \]*-8\\(%(?:r|e)bp\\),\[\\t \]*%rdi" 1 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "addl\[\\t \]*\\\$4,\[\\t \]*%esp" 1 { target ia32 } } } */ -/* { dg-final { scan-assembler-times "add(?:l|q)\[\\t \]*\\\$8,\[\\t \]*%\[re\]?sp" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "movq\[\\t \]*-8\\(%(?:r|e)bp\\),\[\\t \]*%rdi" 1 { target { { ! ia32 } && nonpic } } } } */ +/* { dg-final { scan-assembler "(addl|leal).*4.*%esp" { target ia32 } } } */ +/* { dg-final { scan-assembler "(add|lea)(?:l|q)\[\\t \]*\\\$?8.*,\[\\t \]*%\[re\]?sp" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "iret" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-times "iretq" 1 { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "\tcld" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/interrupt-13.c b/gcc/testsuite/gcc.target/i386/interrupt-13.c index 018602fd013..378145ec672 100644 --- a/gcc/testsuite/gcc.target/i386/interrupt-13.c +++ b/gcc/testsuite/gcc.target/i386/interrupt-13.c @@ -15,16 +15,16 @@ fn1 (void *frame, uword_t error) /* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)(b|c|d)x" } } */ /* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)si" } } */ /* { dg-final { scan-assembler-not "(push|pop)l\[\\t \]*%edi" { target ia32 } } } */ -/* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%rax" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%rax" { target { { ! ia32 } && nonpic } } } } */ /* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%r\[0-9\]+" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:r|e)bp" 1 } } */ -/* { dg-final { scan-assembler-times "leave" 1 } } */ +/* { dg-final { scan-assembler-times "leave" 1 { target nonpic } } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%eax" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-times "movl\[\\t \]*-4\\(%ebp\\),\[\\t \]*%eax" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-times "pushq\[\\t \]*%rdi" 1 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "movq\[\\t \]*-8\\(%(?:r|e)bp\\),\[\\t \]*%rdi" 1 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "addl\[\\t \]*\\\$4,\[\\t \]*%esp" 1 { target ia32 } } } */ -/* { dg-final { scan-assembler-times "add(?:l|q)\[\\t \]*\\\$8,\[\\t \]*%\[re\]?sp" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "movq\[\\t \]*-8\\(%(?:r|e)bp\\),\[\\t \]*%rdi" 1 { target { { ! ia32 } && nonpic } } } } */ +/* { dg-final { scan-assembler "(addl|leal).*4.*%esp" { target ia32 } } } */ +/* { dg-final { scan-assembler "(add|lea)(?:l|q)\[\\t \]*\\\$?8.*,\[\\t \]*%\[re\]?sp" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "iret" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-times "iretq" 1 { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "\tcld" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/interrupt-14.c b/gcc/testsuite/gcc.target/i386/interrupt-14.c index 6ed2cf2e42a..f574f4fafac 100644 --- a/gcc/testsuite/gcc.target/i386/interrupt-14.c +++ b/gcc/testsuite/gcc.target/i386/interrupt-14.c @@ -18,7 +18,7 @@ fn2 (void *frame) } /* { dg-final { scan-assembler-not "movups\[\\t .\]*%(x|y|z)mm\[0-9\]+" } } */ -/* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)(a|b|c|d)x" } } */ +/* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)(a|b|c|d)x" { target nonpic } } } */ /* { dg-final { scan-assembler-not "(push|pop)l\[\\t \]*%edi" { target ia32 } } } */ /* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)si" } } */ /* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%r\[8-9\]+" { target { ! ia32 } } } } */ @@ -26,7 +26,7 @@ fn2 (void *frame) /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:r|e)bp" 2 } } */ /* { dg-final { scan-assembler-times "leave" 2 { target ia32 } } } */ /* { dg-final { scan-assembler-times "pushq\[\\t \]*%rdi" 2 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "movq\[\\t \]*-8\\(%(?:r|e)bp\\),\[\\t \]*%rdi" 2 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "movq\[\\t \]*-8\\(%(?:r|e)bp\\),\[\\t \]*%rdi" 2 { target { { ! ia32 } && nonpic } } } } */ /* { dg-final { scan-assembler-times "iret" 2 { target ia32 } } } */ /* { dg-final { scan-assembler-times "iretq" 2 { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "\tcld" 2 } } */ diff --git a/gcc/testsuite/gcc.target/i386/interrupt-15.c b/gcc/testsuite/gcc.target/i386/interrupt-15.c index 9b53abee652..701ab2f4d33 100644 --- a/gcc/testsuite/gcc.target/i386/interrupt-15.c +++ b/gcc/testsuite/gcc.target/i386/interrupt-15.c @@ -22,16 +22,16 @@ fn2 (void *frame, uword_t error) /* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)(b|c|d)x" } } */ /* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)si" } } */ /* { dg-final { scan-assembler-not "(push|pop)l\[\\t \]*%edi" { target ia32 } } } */ -/* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%rax" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%rax" { target { { ! ia32 } && nonpic } } } } */ /* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%r\[0-9\]+" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:r|e)bp" 2 } } */ -/* { dg-final { scan-assembler-times "leave" 2 } } */ +/* { dg-final { scan-assembler-times "leave" 2 { target nonpic } } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%eax" 2 { target ia32 } } } */ /* { dg-final { scan-assembler-times "movl\[\\t \]*-4\\(%ebp\\),\[\\t \]*%eax" 2 { target ia32 } } } */ /* { dg-final { scan-assembler-times "pushq\[\\t \]*%rdi" 2 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "movq\[\\t \]*-8\\(%(?:r|e)bp\\),\[\\t \]*%rdi" 2 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "addl\[\\t \]*\\\$4,\[\\t \]*%esp" 2 { target ia32 } } } */ -/* { dg-final { scan-assembler-times "add(?:l|q)\[\\t \]*\\\$8,\[\\t \]*%\[re\]?sp" 2 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "movq\[\\t \]*-8\\(%(?:r|e)bp\\),\[\\t \]*%rdi" 2 { target { { ! ia32 } && nonpic } } } } */ +/* { dg-final { scan-assembler "(addl|leal).*4.*%esp" { target ia32 } } } */ +/* { dg-final { scan-assembler "(add|lea)(?:l|q)\[\\t \]*\\\$?8.*,\[\\t \]*%\[re\]?sp" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "iret" 2 { target ia32 } } } */ /* { dg-final { scan-assembler-times "iretq" 2 { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "\tcld" 2 } } */ diff --git a/gcc/testsuite/gcc.target/i386/interrupt-24.c b/gcc/testsuite/gcc.target/i386/interrupt-24.c index 0b95660128e..f7ec9da3f2b 100644 --- a/gcc/testsuite/gcc.target/i386/interrupt-24.c +++ b/gcc/testsuite/gcc.target/i386/interrupt-24.c @@ -13,7 +13,7 @@ foo (int i0, int i1, int i2, int i3, int i4, int i5, int i6, } /* { dg-final { scan-assembler-not "movups\[\\t \]*%(x|y|z)mm\[0-9\]+" } } */ -/* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)(a|b|c|d)x" } } */ +/* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)(a|b|c|d)x" { target nonpic } } } */ /* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)(d|s)i" } } */ /* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)bp" } } */ /* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%r\[0-9\]+" { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/interrupt-3.c b/gcc/testsuite/gcc.target/i386/interrupt-3.c index ec7dc71cfbc..6b53e1347e3 100644 --- a/gcc/testsuite/gcc.target/i386/interrupt-3.c +++ b/gcc/testsuite/gcc.target/i386/interrupt-3.c @@ -9,8 +9,8 @@ fn (void* frame, uword_t error) { } -/* { dg-final { scan-assembler-times "add(?:l|q)\[\\t \]*\\\$8,\[\\t \]*%\[re\]?sp" 1 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "addl\[\\t \]*\\\$4,\[\\t \]*%esp" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler "(add|lea)(?:l|q)\[\\t \]*\\\$?8.*,\[\\t \]*%\[re\]?sp" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "(addl|leal).*4.*%esp" { target ia32 } } } */ /* { dg-final { scan-assembler-times "iret" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-times "iretq" 1 { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-not "\tcld" } } */ diff --git a/gcc/testsuite/gcc.target/i386/interrupt-9.c b/gcc/testsuite/gcc.target/i386/interrupt-9.c index 490fb9c423b..2a297b25f5e 100644 --- a/gcc/testsuite/gcc.target/i386/interrupt-9.c +++ b/gcc/testsuite/gcc.target/i386/interrupt-9.c @@ -15,8 +15,8 @@ foo (void *frame, uword_t error_code) } /* { dg-final { scan-assembler-times "and\[lq\]?\[^\\n\]*-64,\[^\\n\]*sp" 1 } } */ -/* { dg-final { scan-assembler-times "add(?:l|q)\[\\t \]*\\\$8,\[\\t \]*%\[re\]?sp" 1 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "addl\[\\t \]*\\\$4,\[\\t \]*%esp" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler "(add|lea)(?:l|q)\[\\t \]*\\\$?8.*,\[\\t \]*%\[re\]?sp" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "(addl|leal).*4.*%esp" { target ia32 } } } */ /* { dg-final { scan-assembler-times "iret" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-times "iretq" 1 { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "\tcld" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/interrupt-redzone-2.c b/gcc/testsuite/gcc.target/i386/interrupt-redzone-2.c index a3fa776e2db..2577f43c916 100644 --- a/gcc/testsuite/gcc.target/i386/interrupt-redzone-2.c +++ b/gcc/testsuite/gcc.target/i386/interrupt-redzone-2.c @@ -29,5 +29,5 @@ fn (void *frame) "=m" (i12), "=m" (i13), "=m" (c)); } -/* { dg-final { scan-assembler-times "(?:sub|add)(?:l|q)\[\\t \]*\\\$\[0-9\]*,\[\\t \]*%\[re\]?sp" 2 } } */ +/* { dg-final { scan-assembler "(?:sub|add|lea)(?:l|q)\[\\t \]*.*\\\$?\[0-9\]*.*,\[\\t \]*%\[re\]?sp" } } */ /* { dg-final { scan-assembler-not "\tcld" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr68657.c b/gcc/testsuite/gcc.target/i386/pr68657.c new file mode 100644 index 00000000000..6f0d4987d39 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr68657.c @@ -0,0 +1,15 @@ +/* PR c/68657 */ +/* { dg-options "-mno-avx512f -Werror=psabi" } */ + +typedef int V __attribute__((vector_size (64))); + +void foo (V x, V *y) { /* { dg-error "AVX512F vector argument without AVX512F enabled" } */ + *y = x; +} + +V bar (V *x) { /* { dg-error "AVX512F vector return without AVX512F enabled" } */ + return *x; +} + +/* { dg-message "The ABI for passing parameters with 64-byte alignment has changed" "" { target *-*-* } 6 } */ +/* { dg-message "some warnings being treated as errors" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/i386/pr68843-1.c b/gcc/testsuite/gcc.target/i386/pr68843-1.c new file mode 100644 index 00000000000..da0676aa69b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr68843-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +double +test () +{ + double x = 1.0; + asm ("fld %1" /* { dg-error "explicitly used regs must be grouped at top of stack" } */ + : "=&t" (x) + : "u" (x)); + return x; +} diff --git a/gcc/testsuite/gcc.target/i386/pr68843-2.c b/gcc/testsuite/gcc.target/i386/pr68843-2.c new file mode 100644 index 00000000000..a7bd86c2c5a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr68843-2.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "" } */ + +int +__attribute__((noinline, noclone)) +test (double y) +{ + int a, b; + asm ("fistp{l (%1)| DWORD PTR [%1]}\n\t" + "mov{l (%1), %0| %0, DWORD PTR [%1]}" + : "=r" (a) + : "r" (&b), "t" (y) + : "st"); + return a; +} + +int +main () +{ + int t = -10; + + if (test (t) != t) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr71458.c b/gcc/testsuite/gcc.target/i386/pr71458.c new file mode 100644 index 00000000000..27e7764b5a0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr71458.c @@ -0,0 +1,7 @@ +/* { dg-do compile { target { ! x32 } } } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx -fsanitize=bounds" } */ +/* { dg-error "-fcheck-pointer-bounds is not supported with -fsanitize=bounds" "" { target *-*-* } 0 } */ + +enum {} a[0]; +void fn1(int); +void fn2() { fn1(a[-1]); } diff --git a/gcc/testsuite/gcc.target/powerpc/pr71310.c b/gcc/testsuite/gcc.target/powerpc/pr71310.c new file mode 100644 index 00000000000..6869a500943 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr71310.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2" } */ + +/* { dg-final { scan-assembler-not {\mld} } } */ +/* { dg-final { scan-assembler-not {\mlwz} } } */ +/* { dg-final { scan-assembler-times {\mlbz} 2 } } */ + +struct mmu_gather { + long end; + int fullmm : 1; +}; + +void __tlb_reset_range(struct mmu_gather *p1) +{ + if (p1->fullmm) + p1->end = 0; +} + +void tlb_gather_mmu(struct mmu_gather *p1) +{ + p1->fullmm = 1; + __tlb_reset_range(p1); +} diff --git a/gcc/testsuite/gcc.target/powerpc/vadsdu-0.c b/gcc/testsuite/gcc.target/powerpc/vadsdu-0.c new file mode 100644 index 00000000000..aa1d61de741 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsdu-0.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned int +doAbsoluteDifferenceUnsignedInt (__vector unsigned int *p, + __vector unsigned int *q) +{ + __vector unsigned int source_1, source_2; + __vector unsigned int result; + + source_1 = *p; + source_2 = *q; + + result = __builtin_vec_vadu (source_1, source_2); + return result; +} + +/* { dg-final { scan-assembler "vabsduw" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsdu-1.c b/gcc/testsuite/gcc.target/powerpc/vadsdu-1.c new file mode 100644 index 00000000000..cf10283b199 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsdu-1.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned int +doAbsoluteDifferenceUnsignedIntMacro (__vector unsigned int *p, + __vector unsigned int *q) +{ + __vector unsigned int result, source_1, source_2; + + source_1 = *p; + source_2 = *q; + + result = vec_absd (source_1, source_2); + return result; +} + +/* { dg-final { scan-assembler "vabsduw" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsdu-2.c b/gcc/testsuite/gcc.target/powerpc/vadsdu-2.c new file mode 100644 index 00000000000..27ea2b32559 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsdu-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned short +doAbsoluteDifferenceUnsignedShort (__vector unsigned short *p, + __vector unsigned short *q) +{ + __vector unsigned short source_1, source_2; + __vector unsigned short result; + + source_1 = *p; + source_2 = *q; + + result = __builtin_vec_vadu (source_1, source_2); + return result; +} + +/* { dg-final { scan-assembler "vabsduh" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsdu-3.c b/gcc/testsuite/gcc.target/powerpc/vadsdu-3.c new file mode 100644 index 00000000000..be0df32e220 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsdu-3.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned short +doAbsoluteDifferenceUnsignedShortMacro (__vector unsigned short *p, + __vector unsigned short *q) +{ + __vector unsigned short result, source_1, source_2; + + source_1 = *p; + source_2 = *q; + + result = vec_absd (source_1, source_2); + return result; +} + +/* { dg-final { scan-assembler "vabsduh" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsdu-4.c b/gcc/testsuite/gcc.target/powerpc/vadsdu-4.c new file mode 100644 index 00000000000..ffbd570c711 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsdu-4.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned char +doAbsoluteDifferenceUnsignedChar (__vector unsigned char *p, + __vector unsigned char *q) +{ + __vector unsigned char source_1, source_2; + __vector unsigned char result; + + source_1 = *p; + source_2 = *q; + + result = __builtin_vec_vadu (source_1, source_2); + return result; +} + +/* { dg-final { scan-assembler "vabsdub" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsdu-5.c b/gcc/testsuite/gcc.target/powerpc/vadsdu-5.c new file mode 100644 index 00000000000..20aa25efe21 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsdu-5.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned char +doAbsoluteDifferenceUnsignedCharMacro (__vector unsigned char *p, + __vector unsigned char *q) +{ + __vector unsigned char result, source_1, source_2; + + source_1 = *p; + source_2 = *q; + + result = vec_absd (source_1, source_2); + return result; +} + +/* { dg-final { scan-assembler "vabsdub" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsdub-1.c b/gcc/testsuite/gcc.target/powerpc/vadsdub-1.c new file mode 100644 index 00000000000..de1b9eef1cf --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsdub-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned char +doAbsoluteDifferenceUnsigned (__vector unsigned char *p, + __vector unsigned char *q) +{ + __vector unsigned char source_1, source_2; + __vector unsigned char uc_result; + + source_1 = *p; + source_2 = *q; + + uc_result = __builtin_vec_vadub (source_1, source_2); + return uc_result; +} + +/* { dg-final { scan-assembler "vabsdub" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsdub-2.c b/gcc/testsuite/gcc.target/powerpc/vadsdub-2.c new file mode 100644 index 00000000000..de1b9eef1cf --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsdub-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned char +doAbsoluteDifferenceUnsigned (__vector unsigned char *p, + __vector unsigned char *q) +{ + __vector unsigned char source_1, source_2; + __vector unsigned char uc_result; + + source_1 = *p; + source_2 = *q; + + uc_result = __builtin_vec_vadub (source_1, source_2); + return uc_result; +} + +/* { dg-final { scan-assembler "vabsdub" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsduh-1.c b/gcc/testsuite/gcc.target/powerpc/vadsduh-1.c new file mode 100644 index 00000000000..c208790d811 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsduh-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned short +doAbsoluteDifferenceUnsigned (__vector unsigned short *p, + __vector unsigned short *q) +{ + __vector unsigned short source_1, source_2; + __vector unsigned short us_result; + + source_1 = *p; + source_2 = *q; + + us_result = __builtin_vec_vaduh (source_1, source_2); + return us_result; +} + +/* { dg-final { scan-assembler "vabsduh" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsduh-2.c b/gcc/testsuite/gcc.target/powerpc/vadsduh-2.c new file mode 100644 index 00000000000..5fa2157e18e --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsduh-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned short +doAbsoluteDifferenceUnsignedMacro (__vector unsigned short *p, + __vector unsigned short *q) +{ + __vector unsigned short result, source_1, source_2; + + source_1 = *p; + source_2 = *q; + + result = vec_absdh (source_1, source_2); + return result; +} + +/* { dg-final { scan-assembler "vabsduh" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsduw-1.c b/gcc/testsuite/gcc.target/powerpc/vadsduw-1.c new file mode 100644 index 00000000000..6cb66ba4c9f --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsduw-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned int +doAbsoluteDifferenceUnsigned (__vector unsigned int *p, + __vector unsigned int *q) +{ + __vector unsigned int source_1, source_2; + __vector unsigned int ui_result; + + source_1 = *p; + source_2 = *q; + + ui_result = __builtin_vec_vaduw (source_1, source_2); + return ui_result; +} + +/* { dg-final { scan-assembler "vabsduw" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vadsduw-2.c b/gcc/testsuite/gcc.target/powerpc/vadsduw-2.c new file mode 100644 index 00000000000..a614cf6d4ae --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vadsduw-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9" } */ + +/* This test should succeed on both 32- and 64-bit configurations. */ +#include <altivec.h> + +__vector unsigned int +doAbsoluteDifferenceUnsignedMacro (__vector unsigned int *p, + __vector unsigned int *q) +{ + __vector unsigned int result, source_1, source_2; + + source_1 = *p; + source_2 = *q; + + result = vec_absdw (source_1, source_2); + return result; +} + +/* { dg-final { scan-assembler "vabsduw" } } */ diff --git a/gcc/testsuite/gfortran.dg/array_constructor_49.f90 b/gcc/testsuite/gfortran.dg/array_constructor_49.f90 index ca963d3ac73..0f5036a03da 100644 --- a/gcc/testsuite/gfortran.dg/array_constructor_49.f90 +++ b/gcc/testsuite/gfortran.dg/array_constructor_49.f90 @@ -6,7 +6,7 @@ program t integer :: ndim=2, ndfp=4, i character (len=8) :: line - write (unit=line,fmt='(4I2)'), (/ ( i, i = 1, ndfp ) /) + ndim + write (unit=line,fmt='(4I2)') (/ ( i, i = 1, ndfp ) /) + ndim if (line /= ' 3 4 5 6') call abort end program t ! { dg-final { scan-tree-dump-times "__var" 3 "original" } } diff --git a/gcc/testsuite/gfortran.dg/comma_IO_extension_1.f90 b/gcc/testsuite/gfortran.dg/comma_IO_extension_1.f90 new file mode 100644 index 00000000000..abbb69d66f6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/comma_IO_extension_1.f90 @@ -0,0 +1,8 @@ +! { dg-do compile } +! PR 60751 +! Contributed by Walter Spector <w6ws@earthlink.net> +program extracomma + implicit none + + write (*,*), 1, 2, 3 ! { dg-warning "Legacy Extension: Comma before i/o item list" } +end program diff --git a/gcc/testsuite/gfortran.dg/comma_IO_extension_2.f90 b/gcc/testsuite/gfortran.dg/comma_IO_extension_2.f90 new file mode 100644 index 00000000000..5e80a174201 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/comma_IO_extension_2.f90 @@ -0,0 +1,9 @@ +! { dg-do compile } +! { dg-options "-std=legacy" } +! PR 60751 +! Contributed by Walter Spector <w6ws@earthlink.net> +program extracomma + implicit none + + write (*,*), 1, 2, 3 +end program diff --git a/gcc/testsuite/gfortran.dg/goacc/cache-1.f95 b/gcc/testsuite/gfortran.dg/goacc/cache-1.f95 index 2aa9e053627..39fbf2cf55a 100644 --- a/gcc/testsuite/gfortran.dg/goacc/cache-1.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/cache-1.f95 @@ -1,4 +1,6 @@ -! { dg-do compile } +! OpenACC cache directive: valid usage. +! For execution testing, this file is "#include"d from +! libgomp/testsuite/libgomp.oacc-fortran/cache-1.f95. ! { dg-additional-options "-std=f2008" } program test @@ -6,11 +8,8 @@ program test integer :: i, d(10), e(5,13) do concurrent (i=1:5) - !$acc cache (d) !$acc cache (d(1:3)) !$acc cache (d(i:i+2)) - - !$acc cache (e) !$acc cache (e(1:3,2:4)) !$acc cache (e(i:i+2,i+1:i+3)) enddo diff --git a/gcc/testsuite/gfortran.dg/goacc/cache-2.f95 b/gcc/testsuite/gfortran.dg/goacc/cache-2.f95 new file mode 100644 index 00000000000..be818788556 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/cache-2.f95 @@ -0,0 +1,12 @@ +! OpenACC cache directive: invalid usage. +! { dg-additional-options "-std=f2008" } + +program test + implicit none + integer :: i, d(10), e(5,13) + + do concurrent (i=1:5) + !$acc cache (d) ! { dg-error "" "TODO" { xfail *-*-* } } + !$acc cache (e) ! { dg-error "" "TODO" { xfail *-*-* } } + enddo +end diff --git a/gcc/testsuite/gfortran.dg/goacc/coarray.f95 b/gcc/testsuite/gfortran.dg/goacc/coarray.f95 index 932e1f7fd0d..f30917b8a9c 100644 --- a/gcc/testsuite/gfortran.dg/goacc/coarray.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/coarray.f95 @@ -24,7 +24,7 @@ contains !$acc end parallel loop !$acc parallel loop do i = 1,5 - !$acc cache (a) + !$acc cache (a) ! { dg-error "" "TODO" { xfail *-*-* } } enddo !$acc end parallel loop !$acc update device (a) diff --git a/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90 b/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90 index 42a447ad06b..abb5e6b6c3d 100644 --- a/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90 +++ b/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90 @@ -143,7 +143,8 @@ end subroutine test ! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. vector" 2 "gimple" } } ! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. seq" 2 "gimple" } } ! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. auto" 2 "gimple" } } -! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. tile.2, 3" 2 "gimple" } } +! XFAILed: OpenACC tile clauses are discarded during gimplification. +! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. tile.2, 3" 2 "gimple" { xfail *-*-* } } } ! { dg-final { scan-tree-dump-times "acc loop private.i. independent" 2 "gimple" } } ! { dg-final { scan-tree-dump-times "private.z" 2 "gimple" } } ! { dg-final { scan-tree-dump-times "omp target oacc_\[^ \]+ map.force_tofrom:y" 2 "gimple" } } diff --git a/gcc/testsuite/gfortran.dg/goacc/cray-2.f95 b/gcc/testsuite/gfortran.dg/goacc/cray-2.f95 new file mode 100644 index 00000000000..51b79b53636 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/cray-2.f95 @@ -0,0 +1,56 @@ +! { dg-additional-options "-fcray-pointer" } +! See also cray.f95. + +program test + call oacc1 +contains + subroutine oacc1 + implicit none + integer :: i + real :: pointee + pointer (ptr, pointee) + !$acc declare device_resident (pointee) + !$acc declare device_resident (ptr) + !$acc data copy (pointee) ! { dg-error "Cray pointee" } + !$acc end data + !$acc data deviceptr (pointee) ! { dg-error "Cray pointee" } + !$acc end data + !$acc parallel private (pointee) ! { dg-error "Cray pointee" } + !$acc end parallel + !$acc host_data use_device (pointee) ! { dg-error "Cray pointee" } + !$acc end host_data + !$acc parallel loop reduction(+:pointee) ! { dg-error "Cray pointee" } + do i = 1,5 + enddo + !$acc end parallel loop + !$acc parallel loop + do i = 1,5 + !$acc cache (pointee) ! { dg-error "Cray pointee" } + enddo + !$acc end parallel loop + !$acc update device (pointee) ! { dg-error "Cray pointee" } + !$acc update host (pointee) ! { dg-error "Cray pointee" } + !$acc update self (pointee) ! { dg-error "Cray pointee" } + !$acc data copy (ptr) + !$acc end data + !$acc data deviceptr (ptr) ! { dg-error "Cray pointer" } + !$acc end data + !$acc parallel private (ptr) + !$acc end parallel + !$acc host_data use_device (ptr) ! { dg-error "Cray pointer" } + !$acc end host_data + !$acc parallel loop reduction(+:ptr) ! { dg-error "Cray pointer" } + do i = 1,5 + enddo + !$acc end parallel loop + !$acc parallel loop + do i = 1,5 + !TODO: This must fail, as in openacc-1_0-branch. + !$acc cache (ptr) ! { dg-error "" "TODO" { xfail *-*-* } } + enddo + !$acc end parallel loop + !$acc update device (ptr) + !$acc update host (ptr) + !$acc update self (ptr) + end subroutine oacc1 +end program test diff --git a/gcc/testsuite/gfortran.dg/goacc/cray.f95 b/gcc/testsuite/gfortran.dg/goacc/cray.f95 index a35ab0dc995..d6d531705a6 100644 --- a/gcc/testsuite/gfortran.dg/goacc/cray.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/cray.f95 @@ -1,5 +1,5 @@ -! { dg-do compile } ! { dg-additional-options "-fcray-pointer" } +! See also cray-2.f95. module test contains @@ -8,8 +8,8 @@ contains integer :: i real :: pointee pointer (ptr, pointee) - !$acc declare device_resident (pointee) - !$acc declare device_resident (ptr) + !$acc declare device_resident (pointee) + !$acc declare device_resident (ptr) !$acc data copy (pointee) ! { dg-error "Cray pointee" } !$acc end data !$acc data deviceptr (pointee) ! { dg-error "Cray pointee" } @@ -44,7 +44,8 @@ contains !$acc end parallel loop !$acc parallel loop do i = 1,5 - !$acc cache (ptr) ! TODO: This must fail, as in openacc-1_0-branch + !TODO: This must fail, as in openacc-1_0-branch. + !$acc cache (ptr) ! { dg-error "" "TODO" { xfail *-*-* } } enddo !$acc end parallel loop !$acc update device (ptr) diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-1-2.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-1-2.f95 new file mode 100644 index 00000000000..79665b948c3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/loop-1-2.f95 @@ -0,0 +1,176 @@ +! See also loop-1.f95. + +program test + call test1 +contains + +subroutine test1 + integer :: i, j, k, b(10) + integer, dimension (30) :: a + double precision :: d + real :: r + i = 0 + !$acc loop + do 100 ! { dg-error "cannot be a DO WHILE or DO without loop control" } + if (i .gt. 0) exit ! { dg-error "EXIT statement" } + 100 i = i + 1 + i = 0 + !$acc loop + do ! { dg-error "cannot be a DO WHILE or DO without loop control" } + if (i .gt. 0) exit ! { dg-error "EXIT statement" } + i = i + 1 + end do + i = 0 + !$acc loop + do 200 while (i .lt. 4) ! { dg-error "cannot be a DO WHILE or DO without loop control" } + 200 i = i + 1 + !$acc loop + do while (i .lt. 8) ! { dg-error "cannot be a DO WHILE or DO without loop control" } + i = i + 1 + end do + !$acc loop + do 300 d = 1, 30, 6 + i = d + 300 a(i) = 1 + ! { dg-warning "Deleted feature: Loop variable at .1. must be integer" "" { target *-*-* } 32 } + ! { dg-error "ACC LOOP iteration variable must be of type integer" "" { target *-*-* } 32 } + !$acc loop + do d = 1, 30, 5 + i = d + a(i) = 2 + end do + ! { dg-warning "Deleted feature: Loop variable at .1. must be integer" "" { target *-*-* } 38 } + ! { dg-error "ACC LOOP iteration variable must be of type integer" "" { target *-*-* } 38 } + !$acc loop + do i = 1, 30 + if (i .eq. 16) exit ! { dg-error "EXIT statement" } + end do + !$acc loop + outer: do i = 1, 30 + do j = 5, 10 + if (i .eq. 6 .and. j .eq. 7) exit outer ! { dg-error "EXIT statement" } + end do + end do outer + last: do i = 1, 30 + end do last + + ! different types of loop are allowed + !$acc loop + do i = 1,10 + end do + !$acc loop + do 400, i = 1,10 +400 a(i) = i + + ! after loop directive must be loop + !$acc loop + a(1) = 1 ! { dg-error "Expected DO loop" } + do i = 1,10 + enddo + + ! combined directives may be used with/without end + !$acc parallel loop + do i = 1,10 + enddo + !$acc parallel loop + do i = 1,10 + enddo + !$acc end parallel loop + !$acc kernels loop + do i = 1,10 + enddo + !$acc kernels loop + do i = 1,10 + enddo + !$acc end kernels loop + + !$acc kernels loop reduction(max:i) + do i = 1,10 + enddo + !$acc kernels + !$acc loop reduction(max:i) + do i = 1,10 + enddo + !$acc end kernels + + !$acc parallel loop collapse(0) ! { dg-error "constant positive integer" } + do i = 1,10 + enddo + + !$acc parallel loop collapse(-1) ! { dg-error "constant positive integer" } + do i = 1,10 + enddo + + !$acc parallel loop collapse(i) ! { dg-error "Constant expression required" } + do i = 1,10 + enddo + + !$acc parallel loop collapse(4) ! { dg-error "not enough DO loops for collapsed" } + do i = 1, 3 + do j = 4, 6 + do k = 5, 7 + a(i+j-k) = i + j + k + end do + end do + end do + !$acc parallel loop collapse(2) + do i = 1, 5, 2 + do j = i + 1, 7, i ! { dg-error "collapsed loops don.t form rectangular iteration space" } + end do + end do + !$acc parallel loop collapse(2) + do i = 1, 3 + do j = 4, 6 + end do + end do + !$acc parallel loop collapse(2) + do i = 1, 3 + do j = 4, 6 + end do + k = 4 + end do + !$acc parallel loop collapse(3-1) + do i = 1, 3 + do j = 4, 6 + end do + k = 4 + end do + !$acc parallel loop collapse(1+1) + do i = 1, 3 + do j = 4, 6 + end do + k = 4 + end do + !$acc parallel loop collapse(2) + do i = 1, 3 + do ! { dg-error "cannot be a DO WHILE or DO without loop control" } + end do + end do + !$acc parallel loop collapse(2) + do i = 1, 3 + do r = 4, 6 + end do + ! { dg-warning "Deleted feature: Loop variable at .1. must be integer" "" { target *-*-* } 151 } + ! { dg-error "ACC LOOP iteration variable must be of type integer" "" { target *-*-* } 151 } + end do + + ! Both seq and independent are not allowed + !$acc loop independent seq ! { dg-error "SEQ conflicts with INDEPENDENT" } + do i = 1,10 + enddo + + + !$acc cache (a(1:10)) ! { dg-error "ACC CACHE directive must be inside of loop" } + + do i = 1,10 + !$acc cache(a(i:i+1)) + enddo + + do i = 1,10 + !$acc cache(a(i:i+1)) + a(i) = i + !$acc cache(a(i+2:i+2+1)) + enddo + +end subroutine test1 +end program test diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-1.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-1.f95 index b5f9e038145..5f81b7a1d19 100644 --- a/gcc/testsuite/gfortran.dg/goacc/loop-1.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/loop-1.f95 @@ -1,8 +1,10 @@ +! See also loop-1-2.f95. + module test implicit none contains -subroutine test1 +subroutine test1 integer :: i, j, k, b(10) integer, dimension (30) :: a double precision :: d @@ -30,15 +32,15 @@ subroutine test1 do 300 d = 1, 30, 6 i = d 300 a(i) = 1 - ! { dg-warning "Deleted feature: Loop variable at .1. must be integer" "" { target *-*-* } 30 } - ! { dg-error "ACC LOOP iteration variable must be of type integer" "" { target *-*-* } 30 } + ! { dg-warning "Deleted feature: Loop variable at .1. must be integer" "" { target *-*-* } 32 } + ! { dg-error "ACC LOOP iteration variable must be of type integer" "" { target *-*-* } 32 } !$acc loop do d = 1, 30, 5 i = d a(i) = 2 end do - ! { dg-warning "Deleted feature: Loop variable at .1. must be integer" "" { target *-*-* } 36 } - ! { dg-error "ACC LOOP iteration variable must be of type integer" "" { target *-*-* } 36 } + ! { dg-warning "Deleted feature: Loop variable at .1. must be integer" "" { target *-*-* } 38 } + ! { dg-error "ACC LOOP iteration variable must be of type integer" "" { target *-*-* } 38 } !$acc loop do i = 1, 30 if (i .eq. 16) exit ! { dg-error "EXIT statement" } @@ -53,7 +55,7 @@ subroutine test1 end do last ! different types of loop are allowed - !$acc loop + !$acc loop do i = 1,10 end do !$acc loop @@ -65,8 +67,8 @@ subroutine test1 a(1) = 1 ! { dg-error "Expected DO loop" } do i = 1,10 enddo - - ! combined directives may be used with/without end + + ! combined directives may be used with/without end !$acc parallel loop do i = 1,10 enddo @@ -82,11 +84,11 @@ subroutine test1 enddo !$acc end kernels loop - !$acc kernels loop reduction(max:i) + !$acc kernels loop reduction(max:i) do i = 1,10 enddo - !$acc kernels - !$acc loop reduction(max:i) + !$acc kernels + !$acc loop reduction(max:i) do i = 1,10 enddo !$acc end kernels @@ -118,7 +120,7 @@ subroutine test1 end do !$acc parallel loop collapse(2) do i = 1, 3 - do j = 4, 6 + do j = 4, 6 end do end do !$acc parallel loop collapse(2) @@ -148,8 +150,8 @@ subroutine test1 do i = 1, 3 do r = 4, 6 end do - ! { dg-warning "Deleted feature: Loop variable at .1. must be integer" "" { target *-*-* } 149 } - ! { dg-error "ACC LOOP iteration variable must be of type integer" "" { target *-*-* } 149 } + ! { dg-warning "Deleted feature: Loop variable at .1. must be integer" "" { target *-*-* } 151 } + ! { dg-error "ACC LOOP iteration variable must be of type integer" "" { target *-*-* } 151 } end do ! Both seq and independent are not allowed @@ -158,15 +160,16 @@ subroutine test1 enddo - !$acc cache (a) ! { dg-error "inside of loop" } + !$acc cache (a(1:10)) ! { dg-error "ACC CACHE directive must be inside of loop" } do i = 1,10 - !$acc cache(a) + !$acc cache(a(i:i+1)) enddo do i = 1,10 + !$acc cache(a(i:i+1)) a(i) = i - !$acc cache(a) + !$acc cache(a(i+2:i+2+1)) enddo end subroutine test1 diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-3-2.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-3-2.f95 new file mode 100644 index 00000000000..9be74a85919 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/loop-3-2.f95 @@ -0,0 +1,58 @@ +! { dg-additional-options "-std=f2008" } +! See also loop-3.f95. + +program test + call test1 +contains +subroutine test1 + implicit none + integer :: i, j + + ! !$acc end loop not required by spec + !$acc loop + do i = 1,5 + enddo + !$acc end loop ! { dg-warning "Redundant" } + + !$acc loop + do i = 1,5 + enddo + j = 1 + !$acc end loop ! { dg-error "Unexpected" } + + !$acc parallel + !$acc loop + do i = 1,5 + enddo + !$acc end parallel + !$acc end loop ! { dg-error "Unexpected" } + + ! OpenACC supports Fortran 2008 do concurrent statement + !$acc loop + do concurrent (i = 1:5) + end do + + !$acc loop + outer_loop: do i = 1, 5 + inner_loop: do j = 1,5 + if (i .eq. j) cycle outer_loop + if (i .ne. j) exit outer_loop ! { dg-error "EXIT statement" } + end do inner_loop + end do outer_loop + + outer_loop1: do i = 1, 5 + !$acc loop + inner_loop1: do j = 1,5 + if (i .eq. j) cycle outer_loop1 ! { dg-error "CYCLE statement" } + end do inner_loop1 + end do outer_loop1 + + !$acc loop collapse(2) + outer_loop2: do i = 1, 5 + inner_loop2: do j = 1,5 + if (i .eq. j) cycle outer_loop2 ! { dg-error "CYCLE statement" } + if (i .ne. j) exit outer_loop2 ! { dg-error "EXIT statement" } + end do inner_loop2 + end do outer_loop2 +end subroutine test1 +end program test diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-3.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-3.f95 index 2a866c79234..30930f404f3 100644 --- a/gcc/testsuite/gfortran.dg/goacc/loop-3.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/loop-3.f95 @@ -1,10 +1,10 @@ -! { dg-do compile } ! { dg-additional-options "-std=f2008" } +! See also loop-3-2.f95. subroutine test1 implicit none integer :: i, j - + ! !$acc end loop not required by spec !$acc loop do i = 1,5 @@ -23,7 +23,7 @@ subroutine test1 enddo !$acc end parallel !$acc end loop ! { dg-error "Unexpected" } - + ! OpenACC supports Fortran 2008 do concurrent statement !$acc loop do concurrent (i = 1:5) @@ -35,7 +35,7 @@ subroutine test1 if (i .eq. j) cycle outer_loop if (i .ne. j) exit outer_loop ! { dg-error "EXIT statement" } end do inner_loop - end do outer_loop + end do outer_loop outer_loop1: do i = 1, 5 !$acc loop @@ -50,6 +50,5 @@ subroutine test1 if (i .eq. j) cycle outer_loop2 ! { dg-error "CYCLE statement" } if (i .ne. j) exit outer_loop2 ! { dg-error "EXIT statement" } end do inner_loop2 - end do outer_loop2 + end do outer_loop2 end subroutine test1 - diff --git a/gcc/testsuite/gfortran.dg/goacc/nested-function-1.f90 b/gcc/testsuite/gfortran.dg/goacc/nested-function-1.f90 new file mode 100644 index 00000000000..2fcaa400ee3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/nested-function-1.f90 @@ -0,0 +1,93 @@ +! Exercise nested function decomposition, gcc/tree-nested.c. +! See gcc/testsuite/gcc.dg/goacc/nested-function-1.c for the C version. + +program main + integer, parameter :: N = 100 + integer :: nonlocal_arg + integer :: nonlocal_a(N) + integer :: nonlocal_i + integer :: nonlocal_j + + nonlocal_a (:) = 5 + nonlocal_arg = 5 + + call local () + call nonlocal () + +contains + + subroutine local () + integer :: local_i + integer :: local_arg + integer :: local_a(N) + integer :: local_j + + local_a (:) = 5 + local_arg = 5 + + !$acc kernels loop & + !$acc gang(num:local_arg) worker(local_arg) vector(local_arg) & + !$acc wait async(local_arg) + do local_i = 1, N + !$acc cache (local_a(local_i:local_i + 5)) + local_a(local_i) = 100 + !$acc loop seq tile(*) + do local_j = 1, N + enddo + !$acc loop auto independent tile(1) + do local_j = 1, N + enddo + enddo + !$acc end kernels loop + + !$acc kernels loop & + !$acc gang(static:local_arg) worker(local_arg) vector(local_arg) & + !$acc wait(local_arg, local_arg + 1, local_arg + 2) async + do local_i = 1, N + !$acc cache (local_a(local_i:local_i + 4)) + local_a(local_i) = 100 + !$acc loop seq tile(1) + do local_j = 1, N + enddo + !$acc loop auto independent tile(*) + do local_j = 1, N + enddo + enddo + !$acc end kernels loop + end subroutine local + + subroutine nonlocal () + nonlocal_a (:) = 5 + nonlocal_arg = 5 + + !$acc kernels loop & + !$acc gang(num:nonlocal_arg) worker(nonlocal_arg) vector(nonlocal_arg) & + !$acc wait async(nonlocal_arg) + do nonlocal_i = 1, N + !$acc cache (nonlocal_a(nonlocal_i:nonlocal_i + 3)) + nonlocal_a(nonlocal_i) = 100 + !$acc loop seq tile(2) + do nonlocal_j = 1, N + enddo + !$acc loop auto independent tile(3) + do nonlocal_j = 1, N + enddo + enddo + !$acc end kernels loop + + !$acc kernels loop & + !$acc gang(static:nonlocal_arg) worker(nonlocal_arg) vector(nonlocal_arg) & + !$acc wait(nonlocal_arg, nonlocal_arg + 1, nonlocal_arg + 2) async + do nonlocal_i = 1, N + !$acc cache (nonlocal_a(nonlocal_i:nonlocal_i + 2)) + nonlocal_a(nonlocal_i) = 100 + !$acc loop seq tile(*) + do nonlocal_j = 1, N + enddo + !$acc loop auto independent tile(*) + do nonlocal_j = 1, N + enddo + enddo + !$acc end kernels loop + end subroutine nonlocal +end program main diff --git a/gcc/testsuite/gfortran.dg/goacc/subroutines.f90 b/gcc/testsuite/gfortran.dg/goacc/subroutines.f90 deleted file mode 100644 index 6cab798d458..00000000000 --- a/gcc/testsuite/gfortran.dg/goacc/subroutines.f90 +++ /dev/null @@ -1,73 +0,0 @@ -! Exercise how tree-nested.c handles gang, worker vector and seq. - -! { dg-do compile } - -program main - integer, parameter :: N = 100 - integer :: nonlocal_arg - integer :: nonlocal_a(N) - integer :: nonlocal_i - integer :: nonlocal_j - - nonlocal_a (:) = 5 - nonlocal_arg = 5 - - call local () - call nonlocal () - -contains - - subroutine local () - integer :: local_i - integer :: local_arg - integer :: local_a(N) - integer :: local_j - - local_a (:) = 5 - local_arg = 5 - - !$acc kernels loop gang(num:local_arg) worker(local_arg) vector(local_arg) - do local_i = 1, N - local_a(local_i) = 100 - !$acc loop seq - do local_j = 1, N - enddo - enddo - !$acc end kernels loop - - !$acc kernels loop gang(static:local_arg) worker(local_arg) & - !$acc vector(local_arg) - do local_i = 1, N - local_a(local_i) = 100 - !$acc loop seq - do local_j = 1, N - enddo - enddo - !$acc end kernels loop - end subroutine local - - subroutine nonlocal () - nonlocal_a (:) = 5 - nonlocal_arg = 5 - - !$acc kernels loop gang(num:nonlocal_arg) worker(nonlocal_arg) & - !$acc vector(nonlocal_arg) - do nonlocal_i = 1, N - nonlocal_a(nonlocal_i) = 100 - !$acc loop seq - do nonlocal_j = 1, N - enddo - enddo - !$acc end kernels loop - - !$acc kernels loop gang(static:nonlocal_arg) worker(nonlocal_arg) & - !$acc vector(nonlocal_arg) - do nonlocal_i = 1, N - nonlocal_a(nonlocal_i) = 100 - !$acc loop seq - do nonlocal_j = 1, N - enddo - enddo - !$acc end kernels loop - end subroutine nonlocal -end program main diff --git a/gcc/testsuite/gfortran.dg/graphite/pr38083.f90 b/gcc/testsuite/gfortran.dg/graphite/pr38083.f90 index da8c3cc7914..34d6ca83ad9 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr38083.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr38083.f90 @@ -8,7 +8,7 @@ SUBROUTINE IVSORT (IL,IH,NSEGS,IOUNIT) 10 IF (IL .GE. IH) GO TO 80 20 NSEGS = (IH + IL) / 2 IF (NSEGS .GT. MAXSGS) THEN - WRITE (IOUNIT),MAXSGS + WRITE (IOUNIT) MAXSGS ENDIF 80 NSEGS = NSEGS - 1 90 IF (IH - IL .GE. 11) GO TO 20 diff --git a/gcc/testsuite/gfortran.dg/guality/pr41558.f90 b/gcc/testsuite/gfortran.dg/guality/pr41558.f90 index 8a84de48a30..840b2384012 100644 --- a/gcc/testsuite/gfortran.dg/guality/pr41558.f90 +++ b/gcc/testsuite/gfortran.dg/guality/pr41558.f90 @@ -5,7 +5,7 @@ subroutine f (s) character(len=3) :: s - write (*,*), s ! { dg-final { gdb-test 7 "s" "'foo'" } } + write (*,*) s ! { dg-final { gdb-test 7 "s" "'foo'" } } end call f ('foo') end diff --git a/gcc/testsuite/gfortran.dg/integer_exponentiation_6.F90 b/gcc/testsuite/gfortran.dg/integer_exponentiation_6.F90 index 55c2543e705..4236ee61b65 100644 --- a/gcc/testsuite/gfortran.dg/integer_exponentiation_6.F90 +++ b/gcc/testsuite/gfortran.dg/integer_exponentiation_6.F90 @@ -1,4 +1,4 @@ ! { dg-options "-fno-range-check" } program test - write (*), (2_8 ** 64009999_8) / 2 + write (*,*) (2_8 ** 64009999_8) / 2 end program test diff --git a/gcc/testsuite/gfortran.dg/pr70673.f90 b/gcc/testsuite/gfortran.dg/pr70673.f90 new file mode 100644 index 00000000000..67856e0332e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr70673.f90 @@ -0,0 +1,25 @@ +! { dg-do run } +! +! Test the fix for PR70673 +! +! Contributed by David Kinniburgh <davidgkinniburgh@yahoo.co.uk> +! +module m +contains + subroutine s(inp) + character(*), intent(in) :: inp + character(:), allocatable :: a + a = a ! This used to ICE. + a = inp + a = a ! This used to ICE too + if ((len (a) .ne. 5) .or. (a .ne. "hello")) call abort + a = a(2:3) ! Make sure that temporary creation is not broken. + if ((len (a) .ne. 2) .or. (a .ne. "el")) call abort + deallocate (a) + a = a ! This would ICE too. + end subroutine s +end module m + + use m + call s("hello") +end diff --git a/gcc/testsuite/gnat.dg/case_character.adb b/gcc/testsuite/gnat.dg/case_character.adb new file mode 100644 index 00000000000..59c9b66987d --- /dev/null +++ b/gcc/testsuite/gnat.dg/case_character.adb @@ -0,0 +1,19 @@ +-- { dg-do run } + +procedure Case_Character is + + function Test (C : Character) return Integer is + begin + case C is + when ASCII.HT | ' ' .. Character'Last => return 1; + when others => return 0; + end case; + end; + +begin + + if Test ('A') /= 1 then + raise Program_Error; + end if; + +end; diff --git a/gcc/testsuite/gnat.dg/renaming10.adb b/gcc/testsuite/gnat.dg/renaming10.adb new file mode 100644 index 00000000000..07d4312b060 --- /dev/null +++ b/gcc/testsuite/gnat.dg/renaming10.adb @@ -0,0 +1,12 @@ +-- { dg-do compile } + +package body Renaming10 is + + function F (Input : Rec) return Natural is + Position : Natural renames Input.Position; + Index : Natural renames Natural'Succ(Position); + begin + return Index; + end; + +end Renaming10; diff --git a/gcc/testsuite/gnat.dg/renaming10.ads b/gcc/testsuite/gnat.dg/renaming10.ads new file mode 100644 index 00000000000..aeb9fc1a201 --- /dev/null +++ b/gcc/testsuite/gnat.dg/renaming10.ads @@ -0,0 +1,9 @@ +package Renaming10 is + + type Rec is record + Position : Natural; + end record; + + function F (Input : Rec) return Natural; + +end Renaming10; diff --git a/gcc/toplev.c b/gcc/toplev.c index 543b8a3dc72..f51d2cb2b77 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1276,6 +1276,15 @@ process_options (void) "Address Sanitizer"); flag_check_pointer_bounds = 0; } + + if (flag_sanitize & SANITIZE_BOUNDS) + { + error_at (UNKNOWN_LOCATION, + "-fcheck-pointer-bounds is not supported with " + "-fsanitize=bounds"); + flag_check_pointer_bounds = 0; + } + } /* One region RA really helps to decrease the code size. */ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 40e524bba9c..0fac49c3860 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -1126,7 +1126,7 @@ make_cond_expr_edges (basic_block bb) /* Called for each element in the hash table (P) as we delete the edge to cases hash table. - Clear all the TREE_CHAINs to prevent problems with copying of + Clear all the CASE_CHAINs to prevent problems with copying of SWITCH_EXPRs and structure sharing rules, then free the hash table element. */ diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 25a92aaa04b..62cb01fbba9 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -1114,6 +1114,8 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) case OMP_CLAUSE_GANG: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: + case OMP_CLAUSE_ASYNC: + case OMP_CLAUSE_WAIT: /* Several OpenACC clauses have optional arguments. Check if they are present. */ if (OMP_CLAUSE_OPERAND (clause, 0)) @@ -1197,8 +1199,33 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) case OMP_CLAUSE_SIMD: case OMP_CLAUSE_DEFAULTMAP: case OMP_CLAUSE_SEQ: + case OMP_CLAUSE_INDEPENDENT: + case OMP_CLAUSE_AUTO: break; + /* OpenACC tile clauses are discarded during gimplification. */ + case OMP_CLAUSE_TILE: + /* The following clause belongs to the OpenACC cache directive, which + is discarded during gimplification. */ + case OMP_CLAUSE__CACHE_: + /* The following clauses are only allowed in the OpenMP declare simd + directive, so not seen here. */ + case OMP_CLAUSE_UNIFORM: + case OMP_CLAUSE_INBRANCH: + case OMP_CLAUSE_NOTINBRANCH: + /* The following clauses are only allowed on OpenMP cancel and + cancellation point directives, which at this point have already + been lowered into a function call. */ + case OMP_CLAUSE_FOR: + case OMP_CLAUSE_PARALLEL: + case OMP_CLAUSE_SECTIONS: + case OMP_CLAUSE_TASKGROUP: + /* The following clauses are only added during OMP lowering; nested + function decomposition happens before that. */ + case OMP_CLAUSE__LOOPTEMP_: + case OMP_CLAUSE__SIMDUID_: + case OMP_CLAUSE__GRIDDIM_: + /* Anything else. */ default: gcc_unreachable (); } @@ -1332,7 +1359,7 @@ convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, { wi->val_only = true; wi->is_lhs = false; - *handled_ops_p = true; + *handled_ops_p = false; return NULL_TREE; } break; @@ -1790,6 +1817,8 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) case OMP_CLAUSE_GANG: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: + case OMP_CLAUSE_ASYNC: + case OMP_CLAUSE_WAIT: /* Several OpenACC clauses have optional arguments. Check if they are present. */ if (OMP_CLAUSE_OPERAND (clause, 0)) @@ -1878,8 +1907,33 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) case OMP_CLAUSE_SIMD: case OMP_CLAUSE_DEFAULTMAP: case OMP_CLAUSE_SEQ: + case OMP_CLAUSE_INDEPENDENT: + case OMP_CLAUSE_AUTO: break; + /* OpenACC tile clauses are discarded during gimplification. */ + case OMP_CLAUSE_TILE: + /* The following clause belongs to the OpenACC cache directive, which + is discarded during gimplification. */ + case OMP_CLAUSE__CACHE_: + /* The following clauses are only allowed in the OpenMP declare simd + directive, so not seen here. */ + case OMP_CLAUSE_UNIFORM: + case OMP_CLAUSE_INBRANCH: + case OMP_CLAUSE_NOTINBRANCH: + /* The following clauses are only allowed on OpenMP cancel and + cancellation point directives, which at this point have already + been lowered into a function call. */ + case OMP_CLAUSE_FOR: + case OMP_CLAUSE_PARALLEL: + case OMP_CLAUSE_SECTIONS: + case OMP_CLAUSE_TASKGROUP: + /* The following clauses are only added during OMP lowering; nested + function decomposition happens before that. */ + case OMP_CLAUSE__LOOPTEMP_: + case OMP_CLAUSE__SIMDUID_: + case OMP_CLAUSE__GRIDDIM_: + /* Anything else. */ default: gcc_unreachable (); } diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c index 77c5eb49f14..e87d29055d9 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -472,8 +472,11 @@ find_uses_to_rename (bitmap changed_bbs, bitmap *use_blocks, bitmap need_phis, if (changed_bbs) EXECUTE_IF_SET_IN_BITMAP (changed_bbs, 0, index, bi) - find_uses_to_rename_bb (BASIC_BLOCK_FOR_FN (cfun, index), use_blocks, - need_phis, use_flags); + { + bb = BASIC_BLOCK_FOR_FN (cfun, index); + if (bb) + find_uses_to_rename_bb (bb, use_blocks, need_phis, use_flags); + } else FOR_EACH_BB_FN (bb, cfun) find_uses_to_rename_bb (bb, use_blocks, need_phis, use_flags); diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 78040364a97..32fe2f91edd 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -3721,8 +3721,26 @@ estimate_numbers_of_iterations_loop (struct loop *loop) return; loop->estimate_state = EST_AVAILABLE; - /* Force estimate compuation but leave any existing upper bound in place. */ - loop->any_estimate = false; + + /* If we have a measured profile, use it to estimate the number of + iterations. Normally this is recorded by branch_prob right after + reading the profile. In case we however found a new loop, record the + information here. + + Explicitly check for profile status so we do not report + wrong prediction hitrates for guessed loop iterations heuristics. + Do not recompute already recorded bounds - we ought to be better on + updating iteration bounds than updating profile in general and thus + recomputing iteration bounds later in the compilation process will just + introduce random roundoff errors. */ + if (!loop->any_estimate + && loop->header->count != 0 + && profile_status_for_fn (cfun) >= PROFILE_READ) + { + gcov_type nit = expected_loop_iterations_unbounded (loop); + bound = gcov_type_to_wide_int (nit); + record_niter_bound (loop, bound, true, false); + } /* Ensure that loop->nb_iterations is computed if possible. If it turns out to be constant, we avoid undefined behavior implied bounds and instead @@ -3756,17 +3774,6 @@ estimate_numbers_of_iterations_loop (struct loop *loop) maybe_lower_iteration_bound (loop); - /* If we have a measured profile, use it to estimate the number of - iterations. Explicitly check for profile status so we do not report - wrong prediction hitrates for guessed loop iterations heuristics. */ - if (loop->header->count != 0 - && profile_status_for_fn (cfun) >= PROFILE_READ) - { - gcov_type nit = expected_loop_iterations_unbounded (loop); - bound = gcov_type_to_wide_int (nit); - record_niter_bound (loop, bound, true, false); - } - /* If we know the exact number of iterations of this loop, try to not break code with undefined behavior by not recording smaller maximum number of iterations. */ diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 36b34d37380..e32d503bfef 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -5303,8 +5303,7 @@ reassociate_bb (basic_block bb) && rhs_code == MULT_EXPR) { last = ops.last (); - if (((TREE_CODE (last->op) == INTEGER_CST - && integer_minus_onep (last->op)) + if ((integer_minus_onep (last->op) || real_minus_onep (last->op)) && !HONOR_SNANS (TREE_TYPE (lhs)) && (!HONOR_SIGNED_ZEROS (TREE_TYPE (lhs)) diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 730db04ff8b..0cbd2cd56f2 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -2089,11 +2089,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, /* We need to pre-pend vr->operands[0..i] to rhs. */ vec<vn_reference_op_s> old = vr->operands; if (i + 1 + rhs.length () > vr->operands.length ()) - { - vr->operands.safe_grow (i + 1 + rhs.length ()); - if (old == shared_lookup_references) - shared_lookup_references = vr->operands; - } + vr->operands.safe_grow (i + 1 + rhs.length ()); else vr->operands.truncate (i + 1 + rhs.length ()); FOR_EACH_VEC_ELT (rhs, j, vro) @@ -2244,8 +2240,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, { vec<vn_reference_op_s> old = vr->operands; vr->operands.safe_grow_cleared (2); - if (old == shared_lookup_references - && vr->operands != old) + if (old == shared_lookup_references) shared_lookup_references = vr->operands; } else diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c index 57f1f5c54da..139d376d1cb 100644 --- a/gcc/tree-ssa-threadbackward.c +++ b/gcc/tree-ssa-threadbackward.c @@ -109,6 +109,19 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path, /* Note BBI is not in the path yet, hence the +1 in the test below to make sure BBI is accounted for in the path length test. */ int path_length = path->length (); + + /* We can get a length of 0 here when the statement that + makes a conditional generate a compile-time constant + result is in the same block as the conditional. + + That's not really a jump threading opportunity, but instead is + simple cprop & simplification. We could handle it here if we + wanted by wiring up all the incoming edges. If we run this + early in IPA, that might be worth doing. For now we just + reject that case. */ + if (path_length == 0) + return NULL; + if (path_length + 1 > PARAM_VALUE (PARAM_MAX_FSM_THREAD_LENGTH)) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -376,34 +389,12 @@ convert_and_register_jump_thread_path (vec<basic_block, va_gc> *&path, basic_block bb1 = (*path)[path->length () - j - 1]; basic_block bb2 = (*path)[path->length () - j - 2]; - /* This can happen when we have an SSA_NAME as a PHI argument and - its initialization block is the head of the PHI argument's - edge. */ - if (bb1 == bb2) - continue; - edge e = find_edge (bb1, bb2); gcc_assert (e); jump_thread_edge *x = new jump_thread_edge (e, EDGE_FSM_THREAD); jump_thread_path->safe_push (x); } - /* As a consequence of the test for duplicate blocks in the path - above, we can get a path with no blocks. This happens if a - conditional can be fully evaluated at compile time using just - defining statements in the same block as the test. - - When we no longer push the block associated with a PHI argument - onto the stack, then this as well as the test in the loop above - can be removed. */ - if (jump_thread_path->length () == 0) - { - jump_thread_path->release (); - delete jump_thread_path; - path->pop (); - return; - } - /* Add the edge taken when the control variable has value ARG. */ jump_thread_edge *x = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK); @@ -579,10 +570,19 @@ fsm_find_control_statement_thread_paths (tree name, else { + /* profitable_jump_thread_path is going to push the current + block onto the path. But the path will always have the current + block at this point. So we can just pop it. */ + path->pop (); + edge taken_edge = profitable_jump_thread_path (path, var_bb, name, arg); if (taken_edge) convert_and_register_jump_thread_path (path, taken_edge); + + /* And put the current block back onto the path so that the + state of the stack is unchanged when we leave. */ + vec_safe_push (path, var_bb); } } diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index e640bbda790..084469f2afe 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -2752,7 +2752,7 @@ vect_analyze_data_ref_accesses (vec_info *vinfo) /* Sorting has ensured that DR_INIT (dra) <= DR_INIT (drb). */ HOST_WIDE_INT init_a = TREE_INT_CST_LOW (DR_INIT (dra)); HOST_WIDE_INT init_b = TREE_INT_CST_LOW (DR_INIT (drb)); - gcc_assert (init_a < init_b); + gcc_assert (init_a <= init_b); /* If init_b == init_a + the size of the type * k, we have an interleaving, and DRA is accessed before DRB. */ diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 1f61c83deaf..91d0608e59c 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -6351,9 +6351,9 @@ vectorizable_live_operation (gimple *stmt, FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs) if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) worklist.safe_push (use_stmt); - gcc_assert (worklist.length () == 1); + gcc_assert (worklist.length () >= 1); - bitsize = TYPE_SIZE (lhs_type); + bitsize = TYPE_SIZE (TREE_TYPE (vectype)); vec_bitsize = TYPE_SIZE (vectype); /* Get the vectorized lhs of STMT and the lane to use (counted in bits). */ @@ -6399,16 +6399,22 @@ vectorizable_live_operation (gimple *stmt, /* Create a new vectorized stmt for the uses of STMT and insert outside the loop. */ - tree new_name = make_ssa_name (lhs_type); - tree new_tree = build3 (BIT_FIELD_REF, lhs_type, vec_lhs, bitsize, bitstart); - gimple *new_stmt = gimple_build_assign (new_name, new_tree); - gsi_insert_on_edge_immediate (single_exit (loop), new_stmt); + gimple_seq stmts = NULL; + tree new_tree = build3 (BIT_FIELD_REF, TREE_TYPE (vectype), vec_lhs, bitsize, + bitstart); + new_tree = force_gimple_operand (fold_convert (lhs_type, new_tree), &stmts, + true, NULL_TREE); + if (stmts) + gsi_insert_seq_on_edge_immediate (single_exit (loop), stmts); /* Replace all uses of the USE_STMT in the worklist with the newly inserted statement. */ - use_stmt = worklist.pop (); - replace_uses_by (gimple_phi_result (use_stmt), new_name); - update_stmt (use_stmt); + while (!worklist.is_empty ()) + { + use_stmt = worklist.pop (); + replace_uses_by (gimple_phi_result (use_stmt), new_tree); + update_stmt (use_stmt); + } return true; } diff --git a/gcc/tree.def b/gcc/tree.def index d16575aee62..2c355400609 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -949,7 +949,7 @@ DEFTREECODE (SWITCH_EXPR, "switch_expr", tcc_statement, 3) Operand 1 is CASE_HIGH. If it is NULL_TREE, the label is a simple (one-value) case label. If it is non-NULL_TREE, the case is a range. Operand 2 is CASE_LABEL, which is is the corresponding LABEL_DECL. - Operand 4 is CASE_CHAIN. This operand is only used in tree-cfg.c to + Operand 3 is CASE_CHAIN. This operand is only used in tree-cfg.c to speed up the lookup of case labels which use a particular edge in the control flow graph. */ DEFTREECODE (CASE_LABEL_EXPR, "case_label_expr", tcc_statement, 4) diff --git a/gcc/varasm.c b/gcc/varasm.c index 4a7124e73be..de8bcd6f20c 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -7201,7 +7201,11 @@ place_block_symbol (rtx symbol) if ((flag_sanitize & SANITIZE_ADDRESS) && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST && asan_protect_global (DECL_INITIAL (decl))) - size += asan_red_zone_size (size); + { + size += asan_red_zone_size (size); + alignment = MAX (alignment, + ASAN_RED_ZONE_SIZE * BITS_PER_UNIT); + } } else { diff --git a/libgcc/ChangeLog.meissner b/libgcc/ChangeLog.meissner index 4faedcd1b37..feca26a122d 100644 --- a/libgcc/ChangeLog.meissner +++ b/libgcc/ChangeLog.meissner @@ -1,3 +1,7 @@ +2016-06-13 Michael Meissner <meissner@linux.vnet.ibm.com> + + Merge up to 237393. + 2016-06-08 Michael Meissner <meissner@linux.vnet.ibm.com> Clone branch subversion id 237222 diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index f6d7dd2a808..cf551f49384 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,20 @@ +2016-06-10 Thomas Schwinge <thomas@codesourcery.com> + Cesar Philippidis <cesar@codesourcery.com> + + PR middle-end/71373 + * libgomp.oacc-c/nested-function-1.c: New file. + * libgomp.oacc-c/nested-function-2.c: Likewise. + * libgomp.oacc-fortran/nested-function-1.f90: Likewise. + * libgomp.oacc-fortran/nested-function-2.f90: Likewise. + * libgomp.oacc-fortran/nested-function-3.f90: Likewise. + +2016-06-10 Thomas Schwinge <thomas@codesourcery.com> + + PR c/71381 + * testsuite/libgomp.oacc-c-c++-common/cache-1.c: #include + "../../../gcc/testsuite/c-c++-common/goacc/cache-1.c". + * testsuite/libgomp.oacc-fortran/cache-1.f95: New file. + 2016-06-03 Chung-Lin Tang <cltang@codesourcery.com> * testsuite/libgomp.oacc-fortran/reduction-8.f90: New testcase. diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c index 3f1f0bb3764..16aaed5df70 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c @@ -1,48 +1,3 @@ -int -main (int argc, char **argv) -{ -#define N 2 - int a[N], b[N]; - int i; +/* OpenACC cache directive. */ - for (i = 0; i < N; i++) - { - a[i] = 3; - b[i] = 0; - } - -#pragma acc parallel copyin (a[0:N]) copyout (b[0:N]) -{ - int ii; - - for (ii = 0; ii < N; ii++) - { - const int idx = ii; - int n = 1; - const int len = n; - -#pragma acc cache (a[0:N]) - -#pragma acc cache (a[0:N], b[0:N]) - -#pragma acc cache (a[0]) - -#pragma acc cache (a[0], a[1], b[0:N]) - -#pragma acc cache (a[idx]) - -#pragma acc cache (a[idx:len]) - - b[ii] = a[ii]; - } -} - - - for (i = 0; i < N; i++) - { - if (a[i] != b[i]) - __builtin_abort (); - } - - return 0; -} +#include "../../../gcc/testsuite/c-c++-common/goacc/cache-1.c" diff --git a/libgomp/testsuite/libgomp.oacc-c/nested-function-1.c b/libgomp/testsuite/libgomp.oacc-c/nested-function-1.c new file mode 100644 index 00000000000..fb2a3acdfa9 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-c/nested-function-1.c @@ -0,0 +1,52 @@ +/* Exercise nested function decomposition, gcc/tree-nested.c. */ + +int +main (void) +{ + void test1 () + { + int i, j, k; + int a[4][7][8]; + + __builtin_memset (a, 0, sizeof (a)); + +#pragma acc parallel +#pragma acc loop collapse(4 - 1) + for (i = 1; i <= 3; i++) + for (j = 4; j <= 6; j++) + for (k = 5; k <= 7; k++) + a[i][j][k] = i + j + k; + + for (i = 1; i <= 3; i++) + for (j = 4; j <= 6; j++) + for (k = 5; k <= 7; k++) + if (a[i][j][k] != i + j + k) + __builtin_abort(); + } + + void test2 () + { + int i, j, k; + int a[4][4][4]; + + __builtin_memset (a, 0, sizeof (a)); + +#pragma acc parallel +#pragma acc loop collapse(3) + for (i = 1; i <= 3; i++) + for (j = 1; j <= 3; j++) + for (k = 1; k <= 3; k++) + a[i][j][k] = 1; + + for (i = 1; i <= 3; i++) + for (j = 1; j <= 3; j++) + for (k = 1; k <= 3; k++) + if (a[i][j][k] != 1) + __builtin_abort (); + } + + test1 (); + test2 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.oacc-c/nested-function-2.c b/libgomp/testsuite/libgomp.oacc-c/nested-function-2.c new file mode 100644 index 00000000000..2c3f3feb7f8 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-c/nested-function-2.c @@ -0,0 +1,155 @@ +/* Exercise nested function decomposition, gcc/tree-nested.c. */ + +int +main (void) +{ + int p1 = 2, p2 = 6, p3 = 0, p4 = 4, p5 = 13, p6 = 18, p7 = 1, p8 = 1, p9 = 1; + + void test1 () + { + int i, j, k; + int a[4][4][4]; + + __builtin_memset (a, '\0', sizeof (a)); + +#pragma acc parallel +#pragma acc loop collapse(3) + for (i = 1; i <= 3; i++) + for (j = 1; j <= 3; j++) + for (k = 2; k <= 3; k++) + a[i][j][k] = 1; + + for (i = 1; i <= 3; i++) + for (j = 1; j <= 3; j++) + for (k = 2; k <= 3; k++) + if (a[i][j][k] != 1) + __builtin_abort(); + } + + void test2 (int v1, int v2, int v3, int v4, int v5, int v6) + { + int i, j, k, l = 0, r = 0; + int a[7][5][19]; + int b[7][5][19]; + + __builtin_memset (a, '\0', sizeof (a)); + __builtin_memset (b, '\0', sizeof (b)); + +#pragma acc parallel reduction (||:l) +#pragma acc loop reduction (||:l) collapse(3) + for (i = v1; i <= v2; i++) + for (j = v3; j <= v4; j++) + for (k = v5; k <= v6; k++) + { + l = l || i < 2 || i > 6 || j < 0 || j > 4 || k < 13 || k > 18; + if (!l) + a[i][j][k] += 1; + } + + for (i = v1; i <= v2; i++) + for (j = v3; j <= v4; j++) + for (k = v5; k <= v6; k++) + { + r = r || i < 2 || i > 6 || j < 0 || j > 4 || k < 13 || k > 18; + if (!r) + b[i][j][k] += 1; + } + + if (l != r) + __builtin_abort (); + + for (i = v1; i <= v2; i++) + for (j = v3; j <= v4; j++) + for (k = v5; k <= v6; k++) + if (b[i][j][k] != a[i][j][k]) + __builtin_abort (); + } + + void test3 (int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, + int v9) + { + int i, j, k, l = 0, r = 0; + int a[7][5][19]; + int b[7][5][19]; + + __builtin_memset (a, '\0', sizeof (a)); + __builtin_memset (b, '\0', sizeof (b)); + +#pragma acc parallel reduction (||:l) +#pragma acc loop reduction (||:l) collapse(3) + for (i = v1; i <= v2; i += v7) + for (j = v3; j <= v4; j += v8) + for (k = v5; k <= v6; k += v9) + { + l = l || i < 2 || i > 6 || j < 0 || j > 4 || k < 13 || k > 18; + if (!l) + a[i][j][k] += 1; + } + + for (i = v1; i <= v2; i += v7) + for (j = v3; j <= v4; j += v8) + for (k = v5; k <= v6; k += v9) + { + r = r || i < 2 || i > 6 || j < 0 || j > 4 || k < 13 || k > 18; + if (!r) + b[i][j][k] += 1; + } + + if (l != r) + __builtin_abort (); + + for (i = v1; i <= v2; i++) + for (j = v3; j <= v4; j++) + for (k = v5; k <= v6; k++) + if (b[i][j][k] != a[i][j][k]) + __builtin_abort (); + } + + void test4 () + { + int i, j, k, l = 0, r = 0; + int a[7][5][19]; + int b[7][5][19]; + int v1 = p1, v2 = p2, v3 = p3, v4 = p4, v5 = p5, v6 = p6, v7 = p7, v8 = p8, + v9 = p9; + + __builtin_memset (a, '\0', sizeof (a)); + __builtin_memset (b, '\0', sizeof (b)); + +#pragma acc parallel reduction (||:l) +#pragma acc loop reduction (||:l) collapse(3) + for (i = v1; i <= v2; i += v7) + for (j = v3; j <= v4; j += v8) + for (k = v5; k <= v6; k += v9) + { + l = l || i < 2 || i > 6 || j < 0 || j > 4 || k < 13 || k > 18; + if (!l) + a[i][j][k] += 1; + } + + for (i = v1; i <= v2; i += v7) + for (j = v3; j <= v4; j += v8) + for (k = v5; k <= v6; k += v9) + { + r = r || i < 2 || i > 6 || j < 0 || j > 4 || k < 13 || k > 18; + if (!r) + b[i][j][k] += 1; + } + + if (l != r) + __builtin_abort (); + + for (i = v1; i <= v2; i++) + for (j = v3; j <= v4; j++) + for (k = v5; k <= v6; k++) + if (b[i][j][k] != a[i][j][k]) + __builtin_abort (); + } + + test1 (); + test2 (p1, p2, p3, p4, p5, p6); + test3 (p1, p2, p3, p4, p5, p6, p7, p8, p9); + test4 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.oacc-fortran/cache-1.f95 b/libgomp/testsuite/libgomp.oacc-fortran/cache-1.f95 new file mode 100644 index 00000000000..37313d8c44a --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/cache-1.f95 @@ -0,0 +1,6 @@ +! OpenACC cache directive. +! { dg-do run } +! { dg-additional-options "-std=f2008" } +! { dg-additional-options "-cpp" } + +#include "../../../gcc/testsuite/gfortran.dg/goacc/cache-1.f95" diff --git a/libgomp/testsuite/libgomp.oacc-fortran/nested-function-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/nested-function-1.f90 new file mode 100644 index 00000000000..fdbca4481f8 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/nested-function-1.f90 @@ -0,0 +1,70 @@ +! Exercise nested function decomposition, gcc/tree-nested.c. + +! { dg-do run } + +program collapse2 + call test1 + call test2 +contains + subroutine test1 + integer :: i, j, k, a(1:3, 4:6, 5:7) + logical :: l + l = .false. + a(:, :, :) = 0 + !$acc parallel reduction (.or.:l) + !$acc loop worker vector collapse(4 - 1) + do 164 i = 1, 3 + do 164 j = 4, 6 + do 164 k = 5, 7 + a(i, j, k) = i + j + k +164 end do + !$acc loop worker vector reduction(.or.:l) collapse(2) +firstdo: do i = 1, 3 + do j = 4, 6 + do k = 5, 7 + if (a(i, j, k) .ne. (i + j + k)) l = .true. + end do + end do + end do firstdo + !$acc end parallel + if (l) call abort + end subroutine test1 + + subroutine test2 + integer :: a(3,3,3), k, kk, kkk, l, ll, lll + a = 0 + !$acc parallel + ! Use "gang(static:1)" here and below to effectively turn gang-redundant + ! execution mode into something like gang-single. + !$acc loop gang(static:1) collapse(1) + do 115 k=1,3 + !$acc loop collapse(2) + dokk: do kk=1,3 + do kkk=1,3 + a(k,kk,kkk) = 1 + enddo + enddo dokk +115 continue + !$acc loop gang(static:1) collapse(1) + do k=1,3 + if (any(a(k,1:3,1:3).ne.1)) call abort + enddo + ! Use "gang(static:1)" here and below to effectively turn gang-redundant + ! execution mode into something like gang-single. + !$acc loop gang(static:1) collapse(1) + dol: do 120 l=1,3 + !$acc loop collapse(2) + doll: do ll=1,3 + do lll=1,3 + a(l,ll,lll) = 2 + enddo + enddo doll +120 end do dol + !$acc loop gang(static:1) collapse(1) + do l=1,3 + if (any(a(l,1:3,1:3).ne.2)) call abort + enddo + !$acc end parallel + end subroutine test2 + +end program collapse2 diff --git a/libgomp/testsuite/libgomp.oacc-fortran/nested-function-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/nested-function-2.f90 new file mode 100644 index 00000000000..4e2819641ea --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/nested-function-2.f90 @@ -0,0 +1,173 @@ +! Exercise nested function decomposition, gcc/tree-nested.c. + +! { dg-do run } + +program collapse3 + integer :: p1, p2, p3, p4, p5, p6, p7, p8, p9 + p1 = 2 + p2 = 6 + p3 = -2 + p4 = 4 + p5 = 13 + p6 = 18 + p7 = 1 + p8 = 1 + p9 = 1 + call test1 + call test2 (p1, p2, p3, p4, p5, p6) + call test3 (p1, p2, p3, p4, p5, p6, p7, p8, p9) + call test4 +contains + subroutine test1 + integer :: a(3,3,3), k, kk, kkk, l, ll, lll + !$acc parallel + !$acc loop collapse(3) + do 115 k=1,3 +dokk: do kk=1,3 + do kkk=1,3 + a(k,kk,kkk) = 1 + enddo + enddo dokk +115 continue + !$acc end parallel + if (any(a(1:3,1:3,1:3).ne.1)) call abort + !$acc parallel + !$acc loop collapse(3) +dol: do 120 l=1,3 +doll: do ll=1,3 + do lll=1,3 + a(l,ll,lll) = 2 + enddo + enddo doll +120 end do dol + !$acc end parallel + if (any(a(1:3,1:3,1:3).ne.2)) call abort + end subroutine test1 + + subroutine test2(v1, v2, v3, v4, v5, v6) + integer :: i, j, k, a(1:7, -3:5, 12:19), b(1:7, -3:5, 12:19) + integer :: v1, v2, v3, v4, v5, v6 + logical :: l, r + l = .false. + r = .false. + a(:, :, :) = 0 + b(:, :, :) = 0 + !$acc parallel reduction (.or.:l) + !$acc loop reduction (.or.:l) collapse (3) + do i = v1, v2 + do j = v3, v4 + do k = v5, v6 + l = l.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + l = l.or.k.lt.13.or.k.gt.18 + if (.not.l) a(i, j, k) = a(i, j, k) + 1 + end do + end do + end do + !$acc end parallel + do i = v1, v2 + do j = v3, v4 + do k = v5, v6 + r = r.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + r = r.or.k.lt.13.or.k.gt.18 + if (.not.l) b(i, j, k) = b(i, j, k) + 1 + end do + end do + end do + if (l .neqv. r) call abort + do i = v1, v2 + do j = v3, v4 + do k = v5, v6 + if (a(i, j, k) .ne. b(i, j, k)) call abort + end do + end do + end do + end subroutine test2 + + subroutine test3(v1, v2, v3, v4, v5, v6, v7, v8, v9) + integer :: i, j, k, a(1:7, -3:5, 12:19), b(1:7, -3:5, 12:19) + integer :: v1, v2, v3, v4, v5, v6, v7, v8, v9 + logical :: l, r + l = .false. + r = .false. + a(:, :, :) = 0 + b(:, :, :) = 0 + !$acc parallel reduction (.or.:l) + !$acc loop reduction (.or.:l) collapse (3) + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + l = l.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + l = l.or.k.lt.13.or.k.gt.18 + if (.not.l) a(i, j, k) = a(i, j, k) + 1 + end do + end do + end do + !$acc end parallel + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + r = r.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + r = r.or.k.lt.13.or.k.gt.18 + if (.not.l) b(i, j, k) = b(i, j, k) + 1 + end do + end do + end do + if (l .neqv. r) call abort + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + if (a(i, j, k) .ne. b(i, j, k)) call abort + end do + end do + end do + end subroutine test3 + + subroutine test4 + integer :: i, j, k, a(1:7, -3:5, 12:19), b(1:7, -3:5, 12:19) + integer :: v1, v2, v3, v4, v5, v6, v7, v8, v9 + logical :: l, r + l = .false. + r = .false. + a(:, :, :) = 0 + b(:, :, :) = 0 + v1 = p1 + v2 = p2 + v3 = p3 + v4 = p4 + v5 = p5 + v6 = p6 + v7 = p7 + v8 = p8 + v9 = p9 + !$acc parallel reduction (.or.:l) + !$acc loop reduction (.or.:l) collapse (3) + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + l = l.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + l = l.or.k.lt.13.or.k.gt.18 + if (.not.l) a(i, j, k) = a(i, j, k) + 1 + end do + end do + end do + !$acc end parallel + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + r = r.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + r = r.or.k.lt.13.or.k.gt.18 + if (.not.r) b(i, j, k) = b(i, j, k) + 1 + end do + end do + end do + if (l .neqv. r) call abort + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + if (a(i, j, k) .ne. b(i, j, k)) call abort + end do + end do + end do + end subroutine test4 + +end program collapse3 diff --git a/libgomp/testsuite/libgomp.oacc-fortran/nested-function-3.f90 b/libgomp/testsuite/libgomp.oacc-fortran/nested-function-3.f90 new file mode 100644 index 00000000000..2f6485ef8cf --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/nested-function-3.f90 @@ -0,0 +1,244 @@ +! Exercise nested function decomposition, gcc/tree-nested.c. + +! { dg-do run } + +program sub_collapse_3 + call test1 + call test2 (2, 6, -2, 4, 13, 18) + call test3 (2, 6, -2, 4, 13, 18, 1, 1, 1) + call test4 + call test5 (2, 6, -2, 4, 13, 18) + call test6 (2, 6, -2, 4, 13, 18, 1, 1, 1) +contains + subroutine test1 + integer :: a(3,3,3), k, kk, kkk, l, ll, lll + !$acc parallel + !$acc loop collapse(3) + do 115 k=1,3 +dokk: do kk=1,3 + do kkk=1,3 + a(k,kk,kkk) = 1 + enddo + enddo dokk +115 continue + !$acc end parallel + if (any(a(1:3,1:3,1:3).ne.1)) call abort + !$acc parallel + !$acc loop collapse(3) +dol: do 120 l=1,3 +doll: do ll=1,3 + do lll=1,3 + a(l,ll,lll) = 2 + enddo + enddo doll +120 end do dol + !$acc end parallel + if (any(a(1:3,1:3,1:3).ne.2)) call abort + end subroutine test1 + + subroutine test2(v1, v2, v3, v4, v5, v6) + integer :: i, j, k, a(1:7, -3:5, 12:19), b(1:7, -3:5, 12:19) + integer :: v1, v2, v3, v4, v5, v6 + logical :: l, r + l = .false. + r = .false. + a(:, :, :) = 0 + b(:, :, :) = 0 + !$acc parallel pcopyin (v1, v2, v3, v4, v5, v6) reduction (.or.:l) + !$acc loop reduction (.or.:l) collapse (3) + do i = v1, v2 + do j = v3, v4 + do k = v5, v6 + l = l.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + l = l.or.k.lt.13.or.k.gt.18 + if (.not.l) a(i, j, k) = a(i, j, k) + 1 + end do + end do + end do + !$acc end parallel + do i = v1, v2 + do j = v3, v4 + do k = v5, v6 + r = r.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + r = r.or.k.lt.13.or.k.gt.18 + if (.not.l) b(i, j, k) = b(i, j, k) + 1 + end do + end do + end do + if (l .neqv. r) call abort + do i = v1, v2 + do j = v3, v4 + do k = v5, v6 + if (a(i, j, k) .ne. b(i, j, k)) call abort + end do + end do + end do + end subroutine test2 + + subroutine test3(v1, v2, v3, v4, v5, v6, v7, v8, v9) + integer :: i, j, k, a(1:7, -3:5, 12:19), b(1:7, -3:5, 12:19) + integer :: v1, v2, v3, v4, v5, v6, v7, v8, v9 + logical :: l, r + l = .false. + r = .false. + a(:, :, :) = 0 + b(:, :, :) = 0 + !$acc parallel pcopyin (v1, v2, v3, v4, v5, v6, v7, v8, v9) reduction (.or.:l) + !$acc loop reduction (.or.:l) collapse (3) + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + l = l.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + l = l.or.k.lt.13.or.k.gt.18 + if (.not.l) a(i, j, k) = a(i, j, k) + 1 + end do + end do + end do + !$acc end parallel + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + r = r.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + r = r.or.k.lt.13.or.k.gt.18 + if (.not.l) b(i, j, k) = b(i, j, k) + 1 + end do + end do + end do + if (l .neqv. r) call abort + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + if (a(i, j, k) .ne. b(i, j, k)) call abort + end do + end do + end do + end subroutine test3 + + subroutine test4 + integer :: i, j, k, a(1:7, -3:5, 12:19), b(1:7, -3:5, 12:19) + integer :: v1, v2, v3, v4, v5, v6, v7, v8, v9 + logical :: l, r + l = .false. + r = .false. + a(:, :, :) = 0 + b(:, :, :) = 0 + v1 = 2 + v2 = 6 + v3 = -2 + v4 = 4 + v5 = 13 + v6 = 18 + v7 = 1 + v8 = 1 + v9 = 1 + !$acc parallel pcopyin (v1, v2, v3, v4, v5, v6, v7, v8, v9) reduction (.or.:l) + !$acc loop reduction (.or.:l) collapse (3) + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + l = l.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + l = l.or.k.lt.13.or.k.gt.18 + if (.not.l) a(i, j, k) = a(i, j, k) + 1 + end do + end do + end do + !$acc end parallel + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + r = r.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + r = r.or.k.lt.13.or.k.gt.18 + if (.not.r) b(i, j, k) = b(i, j, k) + 1 + end do + end do + end do + if (l .neqv. r) call abort + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + if (a(i, j, k) .ne. b(i, j, k)) call abort + end do + end do + end do + end subroutine test4 + + subroutine test5(v1, v2, v3, v4, v5, v6) + integer :: i, j, k, a(1:7, -3:5, 12:19), b(1:7, -3:5, 12:19) + integer :: v1, v2, v3, v4, v5, v6 + logical :: l, r + l = .false. + r = .false. + a(:, :, :) = 0 + b(:, :, :) = 0 + !$acc parallel pcopyin (v1, v2, v3, v4, v5, v6) reduction (.or.:l) + !$acc loop reduction (.or.:l) collapse (3) + do i = v1, v2 + do j = v3, v4 + do k = v5, v6 + l = l.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + l = l.or.k.lt.13.or.k.gt.18 + if (.not.l) a(i, j, k) = a(i, j, k) + 1 + end do + end do + end do + !$acc end parallel + do i = v1, v2 + do j = v3, v4 + do k = v5, v6 + r = r.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + r = r.or.k.lt.13.or.k.gt.18 + if (.not.r) b(i, j, k) = b(i, j, k) + 1 + end do + end do + end do + if (l .neqv. r) call abort + do i = v1, v2 + do j = v3, v4 + do k = v5, v6 + if (a(i, j, k) .ne. b(i, j, k)) call abort + end do + end do + end do + end subroutine test5 + + subroutine test6(v1, v2, v3, v4, v5, v6, v7, v8, v9) + integer :: i, j, k, a(1:7, -3:5, 12:19), b(1:7, -3:5, 12:19) + integer :: v1, v2, v3, v4, v5, v6, v7, v8, v9 + logical :: l, r + l = .false. + r = .false. + a(:, :, :) = 0 + b(:, :, :) = 0 + !$acc parallel pcopyin (v1, v2, v3, v4, v5, v6, v7, v8, v9) reduction (.or.:l) + !$acc loop reduction (.or.:l) collapse (3) + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + l = l.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + l = l.or.k.lt.13.or.k.gt.18 + if (.not.l) a(i, j, k) = a(i, j, k) + 1 + m = i * 100 + j * 10 + k + end do + end do + end do + !$acc end parallel + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + r = r.or.i.lt.2.or.i.gt.6.or.j.lt.-2.or.j.gt.4 + r = r.or.k.lt.13.or.k.gt.18 + if (.not.r) b(i, j, k) = b(i, j, k) + 1 + end do + end do + end do + if (l .neqv. r) call abort + do i = v1, v2, v7 + do j = v3, v4, v8 + do k = v5, v6, v9 + if (a(i, j, k) .ne. b(i, j, k)) call abort + end do + end do + end do + end subroutine test6 + +end program sub_collapse_3 diff --git a/libmpx/ChangeLog b/libmpx/ChangeLog index 4d5858122dc..636e9651364 100644 --- a/libmpx/ChangeLog +++ b/libmpx/ChangeLog @@ -1,3 +1,7 @@ +2016-06-10 Ilya Enkovich <ilya.enkovich@intel.com> + + * mpxwrap/mpx_wrappers.c (move_bounds): Fix overflow bug. + 2016-01-20 Matthias Klose <doko@ubuntu.com> * libtool-version: Remove. diff --git a/libmpx/mpxwrap/mpx_wrappers.c b/libmpx/mpxwrap/mpx_wrappers.c index d4c83ef484c..171a780311d 100644 --- a/libmpx/mpxwrap/mpx_wrappers.c +++ b/libmpx/mpxwrap/mpx_wrappers.c @@ -27,6 +27,7 @@ #include "string.h" #include <sys/mman.h> #include <stdint.h> +#include <assert.h> #include "mpxrt/mpxrt.h" void * @@ -418,7 +419,16 @@ move_bounds (void *dst, const void *src, size_t n) else elems_to_copy -= src_bt_index_end + 1; } - src_bd_index_end--; + /* Go to previous table but beware of overflow. + We should have copied all required element + in case src_bd_index_end is 0. */ + if (src_bd_index_end) + src_bd_index_end--; + else + { + assert (!elems_to_copy); + return; + } /* For each bounds table we check if there are valid pointers inside. If there are some, we copy table in pre-counted portions. */ for (; src_bd_index_end > src_bd_index; src_bd_index_end--) diff --git a/maintainer-scripts/ChangeLog b/maintainer-scripts/ChangeLog index 9c50902504c..18513fbe56d 100644 --- a/maintainer-scripts/ChangeLog +++ b/maintainer-scripts/ChangeLog @@ -1,3 +1,8 @@ +2016-06-13 Jonathan Wakely <jwakely@redhat.com> + + * generate_libstdcxx_web_docs: Use realpath to get absolute path. + Add comment about LaTeX errors. + 2016-04-15 Jakub Jelinek <jakub@redhat.com> * crontab: Enable snapshots from gcc-6-branch. diff --git a/maintainer-scripts/generate_libstdcxx_web_docs b/maintainer-scripts/generate_libstdcxx_web_docs index 700e522e25c..00ebcbf7f67 100755 --- a/maintainer-scripts/generate_libstdcxx_web_docs +++ b/maintainer-scripts/generate_libstdcxx_web_docs @@ -3,7 +3,7 @@ # i.e. http://gcc.gnu.org/onlinedocs/gcc-x.y.z/libstdc++* SRCDIR=${1} -DOCSDIR=${2} +DOCSDIR=$(realpath ${2}) if ! [ $# -eq 2 -a -x "${SRCDIR}/configure" -a -d "${DOCSDIR}" ] then @@ -34,6 +34,9 @@ set -x ${SRCDIR}/configure --enable-languages=c,c++ --disable-gcc $disabled_libs --docdir=/docs eval `grep '^target=' config.log` make configure-target +# If the following step fails with an error like +# ! LaTeX Error: File `xtab.sty' not found. +# then you need to install the relevant TeX package e.g. texlive-xtab make -C $target/libstdc++-v3 doc-install-html doc-install-xml doc-install-pdf DESTDIR=$DESTDIR cd $DESTDIR/docs mkdir libstdc++ |