Index: libgomp/ChangeLog =================================================================== diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog --- a/libgomp/ChangeLog (revision 257042) +++ b/libgomp/ChangeLog (revision 259627) @@ -1,3 +1,26 @@ +2018-03-03 Jakub Jelinek + + Backported from mainline + 2018-02-16 Jakub Jelinek + + PR fortran/84418 + * libgomp.fortran/pr84418-1.f90: New test. + * libgomp.fortran/pr84418-2.f90: New test. + + 2018-01-29 Christoph Spiel + Jakub Jelinek + + PR libgomp/84096 + * omp.h.in (omp_init_nest_lock_with_hint): Use omp_nest_lock_t + instead of omp_lock_t. + +2018-02-09 Martin Jambor + + Backport from mainline + 2018-02-08 Martin Jambor + + * testsuite/libgomp.hsa.c/staticvar.c: New test. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: libgomp/testsuite/libgomp.fortran/pr84418-2.f90 =================================================================== diff --git a/libgomp/testsuite/libgomp.fortran/pr84418-2.f90 b/libgomp/testsuite/libgomp.fortran/pr84418-2.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/libgomp/testsuite/libgomp.fortran/pr84418-2.f90 (revision 259627) @@ -0,0 +1,35 @@ +! PR fortran/84418 +! { dg-do run { target vect_simd_clones } } +! { dg-options "-fno-inline" } +! { dg-additional-options "-msse2" { target sse2_runtime } } +! { dg-additional-options "-mavx" { target avx_runtime } } + + type p + integer :: i, j + end type + type(p) :: a(1024) + integer :: b(4,1024), c(1024) + integer :: i + do i = 1, 1024 + a(i)%i = 2 * i + a(i)%j = 3 * i + b(1,i) = 4 * i + b(2,i) = 5 * i + b(3,i) = 6 * i + b(4,i) = 7 * i + end do + !$omp simd + do i = 1, 1024 + c(i) = foo (a(i), b(:,i)) + end do + do i = 1, 1024 + if (c(i).ne.(6 * i)) call abort + end do +contains + function foo (x, y) + type (p) :: x + integer :: y(4), foo + !$omp declare simd linear (ref (x, y)) + foo = x%i + y(1) + end function +end Index: libgomp/testsuite/libgomp.fortran/pr84418-1.f90 =================================================================== diff --git a/libgomp/testsuite/libgomp.fortran/pr84418-1.f90 b/libgomp/testsuite/libgomp.fortran/pr84418-1.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/libgomp/testsuite/libgomp.fortran/pr84418-1.f90 (revision 259627) @@ -0,0 +1,26 @@ +! PR fortran/84418 +! { dg-do run { target vect_simd_clones } } +! { dg-options "-fno-inline" } +! { dg-additional-options "-msse2" { target sse2_runtime } } +! { dg-additional-options "-mavx" { target avx_runtime } } + + real :: a(1024), b(1024), c(1024) + integer :: i + do i = 1, 1024 + a(i) = 0.5 * i + b(i) = 1.5 * i + end do + !$omp simd + do i = 1, 1024 + c(i) = foo (a(i), b(i)) + end do + do i = 1, 1024 + if (c(i).ne.(2 * i)) call abort + end do +contains + real function foo (x, y) + real :: x, y + !$omp declare simd linear (ref (x, y)) + foo = x + y + end function +end Index: libgomp/testsuite/libgomp.hsa.c/staticvar.c =================================================================== diff --git a/libgomp/testsuite/libgomp.hsa.c/staticvar.c b/libgomp/testsuite/libgomp.hsa.c/staticvar.c new file mode 10644 --- /dev/null (nonexistent) +++ b/libgomp/testsuite/libgomp.hsa.c/staticvar.c (revision 259627) @@ -0,0 +1,23 @@ +extern void abort (void); + +#pragma omp declare target +int +foo (void) +{ + static int s; + return ++s; +} +#pragma omp end declare target + +int +main () +{ + int r; + #pragma omp target map(from:r) + { + r = foo (); + } + if (r != 1) + abort (); + return 0; +} Index: libgomp/omp.h.in =================================================================== diff --git a/libgomp/omp.h.in b/libgomp/omp.h.in --- a/libgomp/omp.h.in (revision 257042) +++ b/libgomp/omp.h.in (revision 259627) @@ -101,7 +101,7 @@ extern int omp_test_lock (omp_lock_t *) __GOMP_NOTHROW; extern void omp_init_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW; -extern void omp_init_nest_lock_with_hint (omp_lock_t *, omp_lock_hint_t) +extern void omp_init_nest_lock_with_hint (omp_nest_lock_t *, omp_lock_hint_t) __GOMP_NOTHROW; extern void omp_destroy_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW; extern void omp_set_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW; Index: libsanitizer/asan/asan_allocator.h =================================================================== diff --git a/libsanitizer/asan/asan_allocator.h b/libsanitizer/asan/asan_allocator.h --- a/libsanitizer/asan/asan_allocator.h (revision 257042) +++ b/libsanitizer/asan/asan_allocator.h (revision 259627) @@ -115,7 +115,7 @@ #if SANITIZER_CAN_USE_ALLOCATOR64 # if defined(__powerpc64__) -const uptr kAllocatorSpace = 0xa0000000000ULL; +const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x20000000000ULL; // 2T. typedef DefaultSizeClassMap SizeClassMap; # elif defined(__aarch64__) && SANITIZER_ANDROID Index: libsanitizer/ChangeLog =================================================================== diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog --- a/libsanitizer/ChangeLog (revision 257042) +++ b/libsanitizer/ChangeLog (revision 259627) @@ -1,3 +1,12 @@ +2018-04-24 Martin Liska + + Backport from mainline + 2018-04-18 Bill Seurer + + PR sanitizer/85389 + * asan/asan_allocator.h (kAllocatorSpace): For __powerpc64__ change + from 0xa0000000000ULL to ~(uptr)0. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: libstdc++-v3/configure =================================================================== diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure --- a/libstdc++-v3/configure (revision 257042) +++ b/libstdc++-v3/configure (revision 259627) @@ -620,6 +620,8 @@ ATOMIC_FLAGS ATOMIC_WORD_SRCDIR ATOMICITY_SRCDIR +INCLUDE_DIR_NOTPARALLEL_FALSE +INCLUDE_DIR_NOTPARALLEL_TRUE BUILD_PDF_FALSE BUILD_PDF_TRUE PDFLATEX @@ -11601,7 +11603,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11604 "configure" +#line 11606 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11707,7 +11709,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11710 "configure" +#line 11712 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15393,7 +15395,7 @@ # Fake what AC_TRY_COMPILE does. cat > conftest.$ac_ext << EOF -#line 15396 "configure" +#line 15398 "configure" int main() { typedef bool atomic_type; @@ -15428,7 +15430,7 @@ rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15431 "configure" +#line 15433 "configure" int main() { typedef short atomic_type; @@ -15463,7 +15465,7 @@ rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15466 "configure" +#line 15468 "configure" int main() { // NB: _Atomic_word not necessarily int. @@ -15499,7 +15501,7 @@ rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15502 "configure" +#line 15504 "configure" int main() { typedef long long atomic_type; @@ -15580,7 +15582,7 @@ # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15583 "configure" +#line 15585 "configure" int main() { _Decimal32 d1; @@ -15622,7 +15624,7 @@ # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15625 "configure" +#line 15627 "configure" template struct same { typedef T2 type; }; @@ -15656,7 +15658,7 @@ rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15659 "configure" +#line 15661 "configure" template struct same { typedef T2 type; }; @@ -53327,6 +53329,19 @@ fi done + for ac_func in aligned_alloc posix_memalign memalign _aligned_malloc +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + ;; *-fuchsia*) @@ -66077,6 +66092,19 @@ CXXFLAGS="$ac_save_CXXFLAGS" + for ac_func in aligned_alloc posix_memalign memalign _aligned_malloc +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + ;; *-netbsd*) SECTION_FLAGS='-ffunction-sections -fdata-sections' @@ -81219,7 +81247,19 @@ fi +case "$build" in + *-*-darwin* ) glibcxx_include_dir_notparallel=yes ;; + * ) glibcxx_include_dir_notparallel=no ;; +esac + if test $glibcxx_include_dir_notparallel = "yes"; then + INCLUDE_DIR_NOTPARALLEL_TRUE= + INCLUDE_DIR_NOTPARALLEL_FALSE='#' +else + INCLUDE_DIR_NOTPARALLEL_TRUE='#' + INCLUDE_DIR_NOTPARALLEL_FALSE= +fi + # Propagate the target-specific source directories through the build chain. ATOMICITY_SRCDIR=config/${atomicity_dir} ATOMIC_WORD_SRCDIR=config/${atomic_word_dir} @@ -81913,6 +81953,10 @@ as_fn_error "conditional \"BUILD_PDF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${INCLUDE_DIR_NOTPARALLEL_TRUE}" && test -z "${INCLUDE_DIR_NOTPARALLEL_FALSE}"; then + as_fn_error "conditional \"INCLUDE_DIR_NOTPARALLEL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 Index: libstdc++-v3/src/c++98/ios_failure.cc =================================================================== diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc --- a/libstdc++-v3/src/c++98/ios_failure.cc (revision 257042) +++ b/libstdc++-v3/src/c++98/ios_failure.cc (revision 259627) @@ -29,6 +29,18 @@ #define _GLIBCXX_USE_CXX11_ABI 0 #include +#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti +#include +#include +#endif + +#ifdef _GLIBCXX_USE_NLS +# include +# define _(msgid) gettext (msgid) +#else +# define _(msgid) (msgid) +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -43,5 +55,40 @@ ios_base::failure::what() const throw() { return _M_msg.c_str(); } +#if _GLIBCXX_USE_DUAL_ABI + // When the dual ABI is enabled __throw_ios_failure() is defined in + // src/c++11/cxx11-ios_failure.cc +#if __cpp_rtti + // If RTTI is enabled the exception type thrown will use these functions to + // construct/destroy a gcc4-compatible ios::failure object in a buffer, + // and to catch that object via a handler of the gcc4-compatible type. + void + __construct_ios_failure(void* buf, const char* msg) + { ::new(buf) ios_base::failure(msg); } + + void + __destroy_ios_failure(void* buf) + { static_cast(buf)->~failure(); } + + bool + __is_ios_failure_handler(const __cxxabiv1::__class_type_info* type) + { return *type == typeid(ios::failure); } + + namespace { + // C++98-style static assertions to ensure ios::failure fits in a buffer + // with the same size and alignment as runtime_error: + typedef char S[1 / (sizeof(ios::failure) <= sizeof(runtime_error))]; + typedef char A[1 / (__alignof(ios::failure) <= __alignof(runtime_error))]; + } +#endif // __cpp_rtti + +#else // ! _GLIBCXX_USE_DUAL_ABI + + void + __throw_ios_failure(const char* __s __attribute__((unused))) + { _GLIBCXX_THROW_OR_ABORT(ios::failure(_(__s))); } + +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace Index: libstdc++-v3/src/c++11/Makefile.in =================================================================== diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in --- a/libstdc++-v3/src/c++11/Makefile.in (revision 257042) +++ b/libstdc++-v3/src/c++11/Makefile.in (revision 259627) @@ -433,6 +433,9 @@ libc__11convenience_la_SOURCES = $(sources) $(inst_sources) +# Rewrite the type info for __ios_failure. +@ENABLE_DUAL_ABI_TRUE@rewrite_ios_failure_typeinfo = sed -e '/^_*_ZTISt13__ios_failure:/,/_ZTVN10__cxxabiv120__si_class_type_infoE/s/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt19__iosfail_type_info/' + # AM_CXXFLAGS needs to be in each subdirectory so that it can be # modified in a per-library or per-sub-library way. Need to manually # set this option because CONFIG_CXXFLAGS has to be after @@ -748,6 +751,21 @@ hashtable_c++0x.o: hashtable_c++0x.cc $(CXXCOMPILE) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure-lt.s: cxx11-ios_failure.cc +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) -S $< -o tmp-cxx11-ios_failure-lt.s +@ENABLE_DUAL_ABI_TRUE@ -test -f tmp-cxx11-ios_failure-lt.o && mv -f tmp-cxx11-ios_failure-lt.o tmp-cxx11-ios_failure-lt.s +@ENABLE_DUAL_ABI_TRUE@ $(rewrite_ios_failure_typeinfo) tmp-$@ > $@ +@ENABLE_DUAL_ABI_TRUE@ -rm -f tmp-$@ +@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure.s: cxx11-ios_failure.cc +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) -S $< -o tmp-$@ +@ENABLE_DUAL_ABI_TRUE@ $(rewrite_ios_failure_typeinfo) tmp-$@ > $@ +@ENABLE_DUAL_ABI_TRUE@ -rm -f tmp-$@ + +@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure.lo: cxx11-ios_failure-lt.s +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) -g0 -c $< -o $@ +@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure.o: cxx11-ios_failure.s +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) -g0 -c $< + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: Index: libstdc++-v3/src/c++11/ios.cc =================================================================== diff --git a/libstdc++-v3/src/c++11/ios.cc b/libstdc++-v3/src/c++11/ios.cc --- a/libstdc++-v3/src/c++11/ios.cc (revision 257042) +++ b/libstdc++-v3/src/c++11/ios.cc (revision 259627) @@ -26,29 +26,13 @@ // ISO C++ 14882: 27.4 Iostreams base classes // -// Determines the version of ios_base::failure thrown by __throw_ios_failure. -// If !_GLIBCXX_USE_DUAL_ABI this will get undefined automatically. -#define _GLIBCXX_USE_CXX11_ABI 1 - #include #include -#include -#ifdef _GLIBCXX_USE_NLS -# include -# define _(msgid) gettext (msgid) -#else -# define _(msgid) (msgid) -#endif - namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - void - __throw_ios_failure(const char* __s __attribute__((unused))) - { _GLIBCXX_THROW_OR_ABORT(ios_base::failure(_(__s))); } - // Definitions for static const members of ios_base. const ios_base::fmtflags ios_base::boolalpha; const ios_base::fmtflags ios_base::dec; Index: libstdc++-v3/src/c++11/cxx11-ios_failure.cc =================================================================== diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc --- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc (revision 257042) +++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc (revision 259627) @@ -28,7 +28,16 @@ #define _GLIBCXX_USE_CXX11_ABI 1 #include +#include +#include +#ifdef _GLIBCXX_USE_NLS +# include +# define _(msgid) gettext (msgid) +#else +# define _(msgid) (msgid) +#endif + #if ! _GLIBCXX_USE_DUAL_ABI # error This file should not be compiled for this configuration. #endif @@ -91,5 +100,66 @@ ios_base::failure::what() const throw() { return runtime_error::what(); } +#if __cpp_rtti + // These functions are defined in src/c++98/ios_failure.cc + extern void __construct_ios_failure(void*, const char*); + extern void __destroy_ios_failure(void*); + extern bool __is_ios_failure_handler(const __cxxabiv1::__class_type_info*); + + // The type thrown to report errors during stream buffer operations. + // In addition to the ios::failure[abi:cxx11] base class it also has a + // member of the gcc4-compatible ios::failure type (in an opaque buffer). + struct __ios_failure : std::ios::failure + { + __ios_failure(const char* s) : failure(s) + { __construct_ios_failure(buf, runtime_error::what()); } + + ~__ios_failure() + { __destroy_ios_failure(buf); } + + // Use std::runtime_error as a proxy for the gcc4-compatible ios::failure + // (which can't be declared here because _GLIBCXX_USE_CXX11_ABI == 1). + // There are assertions in src/c++98/ios_failure.cc to ensure the size + // and alignment assumptions are valid. + alignas(runtime_error) unsigned char buf[sizeof(runtime_error)]; + }; + + // Custom type info for __ios_failure. + class __iosfail_type_info : __cxxabiv1::__si_class_type_info + { + ~__iosfail_type_info(); + + bool + __do_upcast (const __class_type_info *dst_type, + void **obj_ptr) const override; + }; + + __iosfail_type_info::~__iosfail_type_info() = default; + + // This function gets called to see if an exception of type + // __ios_failure can be upcast to the type in a catch handler. + bool + __iosfail_type_info::__do_upcast(const __class_type_info *dst_type, + void **obj_ptr) const + { + // If the handler is for the gcc4-compatible ios::failure type then + // catch the object stored in __ios_failure::buf instead of + // the __ios_failure exception object itself. + if (__is_ios_failure_handler(dst_type)) + { + *obj_ptr = static_cast<__ios_failure*>(*obj_ptr)->buf; + return true; + } + // Otherwise proceed as normal to see if the handler matches. + return __class_type_info::__do_upcast(dst_type, obj_ptr); + } +#else // ! __cpp_rtti + using __ios_failure = ios::failure; +#endif + + void + __throw_ios_failure(const char* __s __attribute__((unused))) + { _GLIBCXX_THROW_OR_ABORT(__ios_failure(_(__s))); } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace Index: libstdc++-v3/src/c++11/Makefile.am =================================================================== diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am --- a/libstdc++-v3/src/c++11/Makefile.am (revision 257042) +++ b/libstdc++-v3/src/c++11/Makefile.am (revision 259627) @@ -126,6 +126,26 @@ hashtable_c++0x.o: hashtable_c++0x.cc $(CXXCOMPILE) -fimplicit-templates -c $< +if ENABLE_DUAL_ABI +# Rewrite the type info for __ios_failure. +rewrite_ios_failure_typeinfo = sed -e '/^_*_ZTISt13__ios_failure:/,/_ZTVN10__cxxabiv120__si_class_type_infoE/s/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt19__iosfail_type_info/' + +cxx11-ios_failure-lt.s: cxx11-ios_failure.cc + $(LTCXXCOMPILE) -S $< -o tmp-cxx11-ios_failure-lt.s + -test -f tmp-cxx11-ios_failure-lt.o && mv -f tmp-cxx11-ios_failure-lt.o tmp-cxx11-ios_failure-lt.s + $(rewrite_ios_failure_typeinfo) tmp-$@ > $@ + -rm -f tmp-$@ +cxx11-ios_failure.s: cxx11-ios_failure.cc + $(CXXCOMPILE) -S $< -o tmp-$@ + $(rewrite_ios_failure_typeinfo) tmp-$@ > $@ + -rm -f tmp-$@ + +cxx11-ios_failure.lo: cxx11-ios_failure-lt.s + $(LTCXXCOMPILE) -g0 -c $< -o $@ +cxx11-ios_failure.o: cxx11-ios_failure.s + $(CXXCOMPILE) -g0 -c $< +endif + # AM_CXXFLAGS needs to be in each subdirectory so that it can be # modified in a per-library or per-sub-library way. Need to manually # set this option because CONFIG_CXXFLAGS has to be after Index: libstdc++-v3/configure.ac =================================================================== diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac --- a/libstdc++-v3/configure.ac (revision 257042) +++ b/libstdc++-v3/configure.ac (revision 259627) @@ -467,6 +467,12 @@ test $ac_cv_prog_DBLATEX = "yes" && test $ac_cv_prog_PDFLATEX = "yes") +case "$build" in + *-*-darwin* ) glibcxx_include_dir_notparallel=yes ;; + * ) glibcxx_include_dir_notparallel=no ;; +esac +AM_CONDITIONAL(INCLUDE_DIR_NOTPARALLEL, + test $glibcxx_include_dir_notparallel = "yes") # Propagate the target-specific source directories through the build chain. ATOMICITY_SRCDIR=config/${atomicity_dir} Index: libstdc++-v3/include/Makefile.in =================================================================== diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in --- a/libstdc++-v3/include/Makefile.in (revision 257042) +++ b/libstdc++-v3/include/Makefile.in (revision 259627) @@ -1897,6 +1897,9 @@ $(experimental_headers): ; @: $(experimental_bits_headers): ; @: +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81797 +@INCLUDE_DIR_NOTPARALLEL_TRUE@.NOTPARALLEL: + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: Index: libstdc++-v3/include/std/any =================================================================== diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any --- a/libstdc++-v3/include/std/any (revision 257042) +++ b/libstdc++-v3/include/std/any (revision 259627) @@ -70,7 +70,7 @@ /** * @brief A type-safe container of any type. - * + * * An @c any object's state is either empty or it stores a contained object * of CopyConstructible type. */ @@ -114,8 +114,8 @@ void __do_emplace(_Args&&... __args) { reset(); + _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...); _M_manager = &_Mgr::_S_manage; - _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...); } /// Emplace with an object created from @p __il and @p __args as @@ -125,8 +125,8 @@ void __do_emplace(initializer_list<_Up> __il, _Args&&... __args) { reset(); + _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...); _M_manager = &_Mgr::_S_manage; - _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...); } public: @@ -272,8 +272,7 @@ _Decay<_ValueType>, _Args&&...>::type emplace(_Args&&... __args) { - __do_emplace<_Decay<_ValueType>> - (std::forward<_Args>(__args)...); + __do_emplace<_Decay<_ValueType>>(std::forward<_Args>(__args)...); any::_Arg __arg; this->_M_manager(any::_Op_access, this, &__arg); return *static_cast<_Decay<_ValueType>*>(__arg._M_obj); @@ -288,8 +287,8 @@ _Args&&...>::type emplace(initializer_list<_Up> __il, _Args&&... __args) { - __do_emplace<_Decay<_ValueType>, _Up> - (__il, std::forward<_Args>(__args)...); + __do_emplace<_Decay<_ValueType>, _Up>(__il, + std::forward<_Args>(__args)...); any::_Arg __arg; this->_M_manager(any::_Op_access, this, &__arg); return *static_cast<_Decay<_ValueType>*>(__arg._M_obj); @@ -624,7 +623,7 @@ } /// @} - + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std Index: libstdc++-v3/include/std/type_traits =================================================================== diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits --- a/libstdc++-v3/include/std/type_traits (revision 257042) +++ b/libstdc++-v3/include/std/type_traits (revision 259627) @@ -3069,6 +3069,10 @@ remove_cv_t> )> { }; + + template + inline constexpr bool has_unique_object_representations_v + = has_unique_object_representations<_Tp>::value; #endif #undef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP Index: libstdc++-v3/include/std/thread =================================================================== diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread --- a/libstdc++-v3/include/std/thread (revision 257042) +++ b/libstdc++-v3/include/std/thread (revision 259627) @@ -243,21 +243,18 @@ { return _M_invoke(_Indices()); } }; - // Alias for _Invoker> template - using __invoker_type - = _Invoker()...))>; + using __decayed_tuple = tuple::type...>; public: - // Returns a call wrapper that does - // INVOKE(DECAY_COPY(__callable), DECAY_COPY(__args)). + // Returns a call wrapper that stores + // tuple{DECAY_COPY(__callable), DECAY_COPY(__args)...}. template - static __invoker_type<_Callable, _Args...> + static _Invoker<__decayed_tuple<_Callable, _Args...>> __make_invoker(_Callable&& __callable, _Args&&... __args) { - return { { - std::make_tuple(std::forward<_Callable>(__callable), - std::forward<_Args>(__args)...) + return { __decayed_tuple<_Callable, _Args...>{ + std::forward<_Callable>(__callable), std::forward<_Args>(__args)... } }; } }; Index: libstdc++-v3/include/std/variant =================================================================== diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant --- a/libstdc++-v3/include/std/variant (revision 257042) +++ b/libstdc++-v3/include/std/variant (revision 259627) @@ -741,7 +741,7 @@ static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); - return get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v); + return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v); } template @@ -750,7 +750,7 @@ static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); - return get<__detail::__variant::__index_of_v<_Tp, _Types...>>( + return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>( std::move(__v)); } @@ -760,7 +760,7 @@ static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); - return get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v); + return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v); } template @@ -769,7 +769,7 @@ static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); - return get<__detail::__variant::__index_of_v<_Tp, _Types...>>( + return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>( std::move(__v)); } @@ -808,7 +808,8 @@ static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); - return get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(__ptr); + return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>( + __ptr); } template @@ -819,7 +820,8 @@ static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); - return get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(__ptr); + return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>( + __ptr); } struct monostate { }; Index: libstdc++-v3/include/bits/parse_numbers.h =================================================================== diff --git a/libstdc++-v3/include/bits/parse_numbers.h b/libstdc++-v3/include/bits/parse_numbers.h --- a/libstdc++-v3/include/bits/parse_numbers.h (revision 257042) +++ b/libstdc++-v3/include/bits/parse_numbers.h (revision 259627) @@ -197,6 +197,13 @@ "integer literal does not fit in unsigned long long"); }; + // Skip past digit separators: + template + struct _Number_help<_Base, _Pow, '\'', _Dig, _Digs...> + : _Number_help<_Base, _Pow, _Dig, _Digs...> + { }; + + // Terminating case for recursion: template struct _Number_help<_Base, _Pow, _Dig> { Index: libstdc++-v3/include/bits/random.h =================================================================== diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h --- a/libstdc++-v3/include/bits/random.h (revision 257042) +++ b/libstdc++-v3/include/bits/random.h (revision 259627) @@ -2643,7 +2643,12 @@ */ void param(const param_type& __param) - { _M_param = __param; } + { + _M_param = __param; + typedef typename std::gamma_distribution::param_type + param_type; + _M_gd.param(param_type{__param.n() / 2}); + } /** * @brief Returns the greatest lower bound value of the distribution. Index: libstdc++-v3/include/c_global/cstdlib =================================================================== diff --git a/libstdc++-v3/include/c_global/cstdlib b/libstdc++-v3/include/c_global/cstdlib --- a/libstdc++-v3/include/c_global/cstdlib (revision 257042) +++ b/libstdc++-v3/include/c_global/cstdlib (revision 259627) @@ -78,6 +78,9 @@ // Get rid of those macros defined in in lieu of real functions. #undef abort +#if __cplusplus >= 201703L && defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) +# undef aligned_alloc +#endif #undef atexit #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT @@ -125,6 +128,9 @@ using ::ldiv_t; using ::abort; +#if __cplusplus >= 201703L && defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) + using ::aligned_alloc; +#endif using ::atexit; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT Index: libstdc++-v3/include/c_global/cstddef =================================================================== diff --git a/libstdc++-v3/include/c_global/cstddef b/libstdc++-v3/include/c_global/cstddef --- a/libstdc++-v3/include/c_global/cstddef (revision 257042) +++ b/libstdc++-v3/include/c_global/cstddef (revision 259627) @@ -65,7 +65,7 @@ /// std::byte enum class byte : unsigned char {}; - template struct __byte_operand; + template struct __byte_operand { }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; Index: libstdc++-v3/include/Makefile.am =================================================================== diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am --- a/libstdc++-v3/include/Makefile.am (revision 257042) +++ b/libstdc++-v3/include/Makefile.am (revision 259627) @@ -1474,3 +1474,8 @@ $(ext_headers): ; @: $(experimental_headers): ; @: $(experimental_bits_headers): ; @: + +if INCLUDE_DIR_NOTPARALLEL +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81797 +.NOTPARALLEL: +endif Index: libstdc++-v3/ChangeLog =================================================================== diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog --- a/libstdc++-v3/ChangeLog (revision 257042) +++ b/libstdc++-v3/ChangeLog (revision 259627) @@ -1,3 +1,157 @@ +2018-04-18 Jonathan Wakely + Jakub Jelinek + + PR libstdc++/85442 + * src/c++11/Makefile.am: Don't generate debuginfo again for + cxx11-ios_failure-lt.s and cxx11-ios_failure.s files. + * src/c++11/Makefile.in: Regenerate. + +2018-04-13 Jonathan Wakely + + * src/c++11/Makefile.am: Fix sed command. + * src/c++11/Makefile.in: Regenerate. + + * src/c++11/Makefile.am: Rewrite sed rule to be less fragile and to + handle mangled names starting with double underscores on darwin. + * src/c++11/Makefile.in: Regenerate. + +2018-04-12 Jonathan Wakely + + * src/c++11/Makefile.am: Fix comment. + * src/c++11/Makefile.in: Regenerate. + * src/c++11/cxx11-ios_failure.cc: Fix comment. + * src/c++98/ios_failure.cc: Likewise. + + Backport from mainline + 2018-04-10 Jonathan Wakely + + PR libstdc++/85222 + * src/c++11/Makefile.am [ENABLE_DUAL_ABI]: Add special rules for + cxx11-ios_failure.cc to rewrite type info for __ios_failure. + * src/c++11/Makefile.in: Regenerate. + * src/c++11/cxx11-ios_failure.cc (__ios_failure, __iosfail_type_info): + New types. + [_GLIBCXX_USE_DUAL_ABI] (__throw_ios_failure): Define here. + * src/c++11/ios.cc (__throw_ios_failure): Remove definition. + (_GLIBCXX_USE_CXX11_ABI): Don't define here. + * src/c++98/ios_failure.cc (__construct_ios_failure) + (__destroy_ios_failure, is_ios_failure_handler): New functions. + [!_GLIBCXX_USE_DUAL_ABI] (__throw_ios_failure): Define here. + * testsuite/27_io/ios_base/failure/dual_abi.cc: New. + * testsuite/27_io/basic_ios/copyfmt/char/1.cc: Revert changes to + handler types, to always catch std::ios_base::failure. + * testsuite/27_io/basic_ios/exceptions/char/1.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_arithmetic/char/ + exceptions_failbit.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/ + exceptions_failbit.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_other/char/ + exceptions_null.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_other/wchar_t/ + exceptions_null.cc: Likewise. + * testsuite/27_io/basic_istream/sentry/char/12297.cc: Likewise. + * testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc: Likewise. + * testsuite/27_io/basic_ostream/inserters_other/char/ + exceptions_null.cc: Likewise. + * testsuite/27_io/basic_ostream/inserters_other/wchar_t/ + exceptions_null.cc: Likewise. + * testsuite/27_io/ios_base/storage/2.cc: Likewise. + +2018-03-22 Rainer Orth + + PR libstdc++/77691 + * testsuite/experimental/memory_resource/resource_adaptor.cc: + xfail execution on 32-bit Solaris/x86. + +2018-03-13 Jonathan Wakely + + Backport from mainline + 2018-03-09 Jonathan Wakely + + PR libstdc++/84769 + * include/std/variant (get<_Tp, _Types...>, get_if<_Tp, _Types...>): + Qualify calls to get<_Np, Types...> and get_if<_Np, _Types...>. + +2018-03-12 Jonathan Wakely + + PR libstdc++/84773 + PR libstdc++/83662 + * crossconfig.m4: Check for aligned_alloc etc. on freebsd and mingw32. + * configure: Regenerate. + * include/c_global/cstdlib [_GLIBCXX_HAVE_ALIGNED_ALLOC] + (aligned_alloc): Add using-declaration. + * testsuite/18_support/aligned_alloc/aligned_alloc.cc: New test. + +2018-03-02 Jonathan Wakely + + Backport from mainline + 2018-03-02 Jonathan Wakely + + PR libstdc++/84671 + * include/bits/parse_numbers.h (_Number_help): Add partial + specialization to handle digit separators. Adjust partial + specialization for recursion temrination to require _Pow == 1ULL. + * testsuite/20_util/duration/literals/84671.cc: New + +2018-02-26 Jonathan Wakely + + Backport from mainline + 2018-02-23 Jonathan Wakely + + PR libstdc++/84532 + * include/std/thread (thread::__make_invoker): Construct tuple + directly instead of using make_tuple. + * testsuite/30_threads/async/84532.cc: New. + * testsuite/30_threads/thread/84532.cc: New. + +2018-02-19 Jonathan Wakely + + Backport from mainline + 2018-02-15 Jonathan Wakely + + PR libstdc++/81797 + * configure.ac (INCLUDE_DIR_NOTPARALLEL): Define. + * configure: Regenerate. + * include/Makefile.am (INCLUDE_DIR_NOTPARALLEL): Add .NOTPARALLEL when + defined. + * include/Makefile.in: Regenerate. + +2018-01-29 Jonathan Wakely + + PR libstdc++/83833 + * testsuite/26_numerics/random/chi_squared_distribution/83833.cc: + Add -ffloat-store to options for m68k and ia32. + + PR libstdc++/83658 + * include/std/any (any::__do_emplace): Only set _M_manager after + constructing the contained object. + * testsuite/20_util/any/misc/any_cast_neg.cc: Adjust dg-error line. + * testsuite/20_util/any/modifiers/83658.cc: New test. + + Backport from mainline + 2018-01-15 Jonathan Wakely + + PR libstdc++/83833 + * include/bits/random.h (chi_squared_distribution::param): Update + gamma distribution parameter. + * testsuite/26_numerics/random/chi_squared_distribution/83833.cc: New + test. + +2018-01-25 Jonathan Wakely + + PR libstdc++/81076 + * include/c_global/cstddef (__byte_operand): Define primary template. + * testsuite/18_support/byte/81076.cc: New test. + + Backport from mainline + 2018-01-15 Jonathan Wakely + + PR libstdc++/83830 + * include/std/type_traits (has_unique_object_representations_v): Add + variable template. + * testsuite/20_util/has_unique_object_representations/value.cc: Check + variable template. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: libstdc++-v3/testsuite/18_support/byte/81076.cc =================================================================== diff --git a/libstdc++-v3/testsuite/18_support/byte/81076.cc b/libstdc++-v3/testsuite/18_support/byte/81076.cc new file mode 10644 --- /dev/null (nonexistent) +++ b/libstdc++-v3/testsuite/18_support/byte/81076.cc (revision 259627) @@ -0,0 +1,26 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++1z } } + +#include + +template void to_integer(...); + +using T = decltype(to_integer(std::byte{})); +using T = void; Index: libstdc++-v3/testsuite/18_support/aligned_alloc/aligned_alloc.cc =================================================================== diff --git a/libstdc++-v3/testsuite/18_support/aligned_alloc/aligned_alloc.cc b/libstdc++-v3/testsuite/18_support/aligned_alloc/aligned_alloc.cc new file mode 10644 --- /dev/null (nonexistent) +++ b/libstdc++-v3/testsuite/18_support/aligned_alloc/aligned_alloc.cc (revision 259627) @@ -0,0 +1,42 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++17" } +// { dg-do run { target c++1z } } + +#include +#include +#include + +void +test01() +{ +#ifdef _GLIBCXX_HAVE_ALIGNED_ALLOC + void* p = std::aligned_alloc(256, 1); + if (p) + { + VERIFY( (reinterpret_cast(p) % 256) == 0 ); + std::free(p); + } +#endif +} + +int +main() +{ + test01(); +} Index: libstdc++-v3/testsuite/30_threads/thread/84532.cc =================================================================== diff --git a/libstdc++-v3/testsuite/30_threads/thread/84532.cc b/libstdc++-v3/testsuite/30_threads/thread/84532.cc new file mode 10644 --- /dev/null (nonexistent) +++ b/libstdc++-v3/testsuite/30_threads/thread/84532.cc (revision 259627) @@ -0,0 +1,38 @@ +// { dg-do compile { target c++11 } } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } + +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + +// PR libstdc++/84532 + +struct F +{ + template + void operator()(T, U, int&) + { + using std::is_same; + using std::reference_wrapper; + static_assert(is_same>::value, ""); + static_assert(is_same>::value, ""); + } +}; +int i = 0; +std::thread t(F{}, std::ref(i), std::cref(i), std::ref(i)); Index: libstdc++-v3/testsuite/30_threads/async/84532.cc =================================================================== diff --git a/libstdc++-v3/testsuite/30_threads/async/84532.cc b/libstdc++-v3/testsuite/30_threads/async/84532.cc new file mode 10644 --- /dev/null (nonexistent) +++ b/libstdc++-v3/testsuite/30_threads/async/84532.cc (revision 259627) @@ -0,0 +1,38 @@ +// { dg-do compile { target c++11 } } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } + +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + +// PR libstdc++/84532 + +struct F +{ + template + void operator()(T, U, int&) + { + using std::is_same; + using std::reference_wrapper; + static_assert(is_same>::value, ""); + static_assert(is_same>::value, ""); + } +}; +int i = 0; +auto fut = std::async(F{}, std::ref(i), std::cref(i), std::ref(i)); Index: libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc b/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc --- a/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc (revision 259627) @@ -50,18 +50,11 @@ ios.pword(1) = v; VERIFY( ios.pword(1) == v ); - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - try { v = ios.pword(max); } - catch(exception_type&) + catch(std::ios_base::failure&) { // Ok. VERIFY( ios.bad() ); @@ -80,7 +73,7 @@ { v = ios.pword(std::numeric_limits::max()); } - catch(exception_type&) + catch(std::ios_base::failure&) { // Ok. VERIFY( ios.bad() ); @@ -99,7 +92,7 @@ { l = ios.iword(max); } - catch(exception_type&) + catch(std::ios_base::failure&) { // Ok. VERIFY( ios.bad() ); @@ -118,7 +111,7 @@ { l = ios.iword(std::numeric_limits::max()); } - catch(exception_type&) + catch(std::ios_base::failure&) { // Ok. VERIFY( ios.bad() ); Index: libstdc++-v3/testsuite/27_io/ios_base/failure/dual_abi.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/dual_abi.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/dual_abi.cc new file mode 10644 --- /dev/null (nonexistent) +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/dual_abi.cc (revision 259627) @@ -0,0 +1,99 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } +// { dg-do run { target c++11 } } + +#include +#include +#include + +void +test01() +{ + using std::ios; + bool caught_ios_failure = false; + bool rethrown = false; + bool caught_system_error = false; + try { + std::ifstream f; + f.exceptions(ios::failbit | ios::badbit | ios::eofbit); + try { + f.get(); + } + catch (const ios::failure&) // catch as old ABI type + { + caught_ios_failure = true; +#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI == 1 + rethrown = true; + throw; // re-throw, to catch as new ABI type +#endif + } + } + catch (const std::system_error& e) + { + caught_system_error = true; + } + + VERIFY( caught_ios_failure ); + if (rethrown) + VERIFY( caught_system_error ); +} + +void +test02() +{ + using std::ios; + const std::exception* p = nullptr; + bool caught_ios_failure = false; + bool caught_exception = false; + try { + std::ifstream f; + f.exceptions(ios::failbit | ios::badbit | ios::eofbit); + try { + f.get(); + } + catch (const std::exception& e1) + { + caught_exception = true; + p = &e1; + throw; + } + } + catch (const ios::failure& e2) + { + caught_ios_failure = true; +#if _GLIBCXX_USE_DUAL_ABI + // If the Dual ABI is active the library throws the new type, + // so e1 was an object of that new type and so &e1 != &e2. + VERIFY( p != &e2 ); +#else + // Otherwise there's only one type of ios::failure, so &e1 == &e2. + VERIFY( p == &e2 ); +#endif + } + + VERIFY( caught_exception ); + VERIFY( caught_ios_failure ); +} + +int +main() +{ + test01(); + test02(); +} Index: libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc --- a/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc (revision 259627) @@ -46,13 +46,6 @@ } { - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - std::ios ios_01(0); std::ios ios_02(0); ios_01.clear(std::ios_base::eofbit); @@ -62,7 +55,7 @@ ios_01.copyfmt(ios_02); VERIFY( false ); } - catch(exception_type&) { + catch(std::ios_base::failure&) { VERIFY( true ); } catch(...) { Index: libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc --- a/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc (revision 259627) @@ -50,13 +50,6 @@ } { - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - std::ios ios_01(0); ios_01.clear(std::ios_base::eofbit); try { @@ -63,7 +56,7 @@ ios_01.exceptions(std::ios_base::eofbit); VERIFY( false ); } - catch(exception_type&) { + catch(std::ios_base::failure&) { iostate02 = ios_01.exceptions(); VERIFY( static_cast(iostate02 & std::ios_base::eofbit) ); } Index: libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc --- a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc (revision 259627) @@ -26,19 +26,12 @@ wistringstream stream; stream.exceptions(ios_base::eofbit); - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - try { wistream::sentry sentry(stream, false); VERIFY( false ); } - catch (exception_type&) + catch (std::ios_base::failure&) { VERIFY( stream.rdstate() == (ios_base::eofbit | ios_base::failbit) ); } Index: libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc --- a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc (revision 259627) @@ -26,19 +26,12 @@ istringstream stream; stream.exceptions(ios_base::eofbit); - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - try { istream::sentry sentry(stream, false); VERIFY( false ); } - catch (exception_type&) + catch (std::ios_base::failure&) { VERIFY( stream.rdstate() == (ios_base::eofbit | ios_base::failbit) ); } Index: libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc (revision 259627) @@ -35,19 +35,12 @@ wistringstream stream; stream.exceptions(ios_base::failbit); - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - try { stream >> static_cast(0); VERIFY( false ); } - catch (exception_type&) + catch (std::ios_base::failure&) { } Index: libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc (revision 259627) @@ -35,19 +35,12 @@ istringstream stream; stream.exceptions(ios_base::failbit); - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - try { stream >> static_cast(0); VERIFY(false); } - catch (exception_type&) + catch (std::ios_base::failure&) { } Index: libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc (revision 259627) @@ -27,13 +27,6 @@ wistringstream stream(L"jaylib - champion sound"); stream.exceptions(ios_base::failbit); - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - try { T i; @@ -40,7 +33,7 @@ stream >> i; VERIFY( false ); } - catch (const exception_type&) + catch (const std::ios_base::failure&) { // stream should set failbit and throw ios_base::failure. VERIFY( stream.fail() ); Index: libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc (revision 259627) @@ -27,13 +27,6 @@ istringstream stream("jaylib - champion sound"); stream.exceptions(ios_base::failbit); - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - try { T i; @@ -40,7 +33,7 @@ stream >> i; VERIFY( false ); } - catch (const exception_type&) + catch (const std::ios_base::failure&) { // stream should set failbit and throw ios_base::failure. VERIFY( stream.fail() ); Index: libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc --- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc (revision 259627) @@ -37,19 +37,12 @@ wostringstream stream; stream.exceptions(ios_base::badbit); - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - try { stream << static_cast(0); VERIFY( false ); } - catch (exception_type&) + catch (std::ios_base::failure&) { } Index: libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc =================================================================== diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc --- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc (revision 257042) +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc (revision 259627) @@ -37,19 +37,12 @@ ostringstream stream; stream.exceptions(ios_base::badbit); - // The library throws the new definition of std::ios::failure -#if _GLIBCXX_USE_CXX11_ABI - typedef std::ios_base::failure exception_type; -#else - typedef std::exception exception_type; -#endif - try { stream << static_cast(0); VERIFY( false ); } - catch (exception_type&) + catch (std::ios_base::failure&) { } Index: libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/83833.cc =================================================================== diff --git a/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/83833.cc b/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/83833.cc new file mode 10644 --- /dev/null (nonexistent) +++ b/libstdc++-v3/testsuite/26_numerics/random/chi_squared_distribution/83833.cc (revision 259627) @@ -0,0 +1,40 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++11 } } +// { dg-additional-options "-ffloat-store" { target { m68*-*-* || ia32 } } } + +#include +#include + +void +test01() +{ + std::default_random_engine r1, r2; + using chi = std::chi_squared_distribution; + chi::param_type p(5); + chi d1(p); + chi d2; + d2.param(p); + VERIFY( d1(r1) == d2(r2) ); // PR libstdc++/83833 +} + +int +main() +{ + test01(); +} Index: libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc =================================================================== diff --git a/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc b/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc --- a/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc (revision 257042) +++ b/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc (revision 259627) @@ -1,4 +1,5 @@ // { dg-do run { target c++14 } } +// { dg-xfail-run-if "PR libstdc++/77691" { { i?86-*-solaris2.* x86_64-*-solaris2.* } && ilp32 } } // Copyright (C) 2016-2017 Free Software Foundation, Inc. // Index: libstdc++-v3/testsuite/20_util/duration/literals/84671.cc =================================================================== diff --git a/libstdc++-v3/testsuite/20_util/duration/literals/84671.cc b/libstdc++-v3/testsuite/20_util/duration/literals/84671.cc new file mode 10644 --- /dev/null (nonexistent) +++ b/libstdc++-v3/testsuite/20_util/duration/literals/84671.cc (revision 259627) @@ -0,0 +1,26 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target c++14 } } + +#include + +// PR libstdc++/84671 +using namespace std::literals::chrono_literals; +constexpr auto ns_ok = 12113ns; +constexpr auto ns_fail = 12'11'3ns; +static_assert(ns_ok == ns_fail, "digit separators work in duration literals"); Index: libstdc++-v3/testsuite/20_util/any/modifiers/83658.cc =================================================================== diff --git a/libstdc++-v3/testsuite/20_util/any/modifiers/83658.cc b/libstdc++-v3/testsuite/20_util/any/modifiers/83658.cc new file mode 10644 --- /dev/null (nonexistent) +++ b/libstdc++-v3/testsuite/20_util/any/modifiers/83658.cc (revision 259627) @@ -0,0 +1,74 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++17" } +// { dg-do run { target c++1z } } + +#include +#include +#include + +struct E : std::bad_alloc { }; + +struct X +{ + X() = default; + X(std::initializer_list) { } + + // Prevents small-object optimization: + X(const X&) noexcept(false) { } + + static void* operator new(std::size_t) { throw E{}; } + static void operator delete(void*, std::size_t) noexcept { } +}; + +void +test01() +{ + std::any a; + try + { + a.emplace(); + VERIFY(false); + } + catch (const E&) + { + VERIFY( !a.has_value() ); + } +} + +void +test02() +{ + std::any a; + try + { + a.emplace(std::initializer_list{}); + VERIFY(false); + } + catch (const E&) + { + VERIFY( !a.has_value() ); + } +} + +int +main() +{ + test01(); + test02(); +} Index: libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc =================================================================== diff --git a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc --- a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc (revision 257042) +++ b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc (revision 259627) @@ -26,5 +26,5 @@ using std::any_cast; const any y(1); - any_cast(y); // { dg-error "invalid static_cast" "" { target { *-*-* } } 461 } + any_cast(y); // { dg-error "invalid static_cast" "" { target { *-*-* } } 460 } } Index: libstdc++-v3/testsuite/20_util/has_unique_object_representations/value.cc =================================================================== diff --git a/libstdc++-v3/testsuite/20_util/has_unique_object_representations/value.cc b/libstdc++-v3/testsuite/20_util/has_unique_object_representations/value.cc --- a/libstdc++-v3/testsuite/20_util/has_unique_object_representations/value.cc (revision 257042) +++ b/libstdc++-v3/testsuite/20_util/has_unique_object_representations/value.cc (revision 259627) @@ -108,3 +108,17 @@ static_assert(test_category(false), ""); } + +void +test02() +{ + using std::has_unique_object_representations; + using std::has_unique_object_representations_v; + + static_assert(has_unique_object_representations_v + == has_unique_object_representations::value); + static_assert(has_unique_object_representations_v + == has_unique_object_representations::value); + static_assert(has_unique_object_representations_v + == has_unique_object_representations::value); +} Index: libstdc++-v3/crossconfig.m4 =================================================================== diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4 --- a/libstdc++-v3/crossconfig.m4 (revision 257042) +++ b/libstdc++-v3/crossconfig.m4 (revision 259627) @@ -133,6 +133,7 @@ AC_DEFINE(HAVE_ISNANL) fi AC_CHECK_FUNCS(__cxa_thread_atexit) + AC_CHECK_FUNCS(aligned_alloc posix_memalign memalign _aligned_malloc) ;; *-fuchsia*) @@ -197,6 +198,7 @@ GLIBCXX_CHECK_LINKER_FEATURES GLIBCXX_CHECK_MATH_SUPPORT GLIBCXX_CHECK_STDLIB_SUPPORT + AC_CHECK_FUNCS(aligned_alloc posix_memalign memalign _aligned_malloc) ;; *-netbsd*) SECTION_FLAGS='-ffunction-sections -fdata-sections' Index: libatomic/configure.tgt =================================================================== diff --git a/libatomic/configure.tgt b/libatomic/configure.tgt --- a/libatomic/configure.tgt (revision 257042) +++ b/libatomic/configure.tgt (revision 259627) @@ -114,6 +114,11 @@ config_path="${config_path} linux/arm posix" ;; + s390*-*-linux*) + # OS support for atomic primitives. + config_path="${config_path} s390 posix" + ;; + *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu \ | *-*-netbsd* | *-*-freebsd* | *-*-openbsd* | *-*-dragonfly* \ | *-*-solaris2* | *-*-sysv4* | *-*-irix6* | *-*-osf* | *-*-hpux11* \ Index: libatomic/ChangeLog =================================================================== diff --git a/libatomic/ChangeLog b/libatomic/ChangeLog --- a/libatomic/ChangeLog (revision 257042) +++ b/libatomic/ChangeLog (revision 259627) @@ -1,3 +1,11 @@ +2018-03-09 Andreas Krebbel + + Backport from mainline + 2018-03-09 Andreas Krebbel + + * config/s390/exch_n.c: New file. + * configure.tgt: Add the config directory for s390. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: libatomic/config/s390/exch_n.c =================================================================== diff --git a/libatomic/config/s390/exch_n.c b/libatomic/config/s390/exch_n.c new file mode 10644 --- /dev/null (nonexistent) +++ b/libatomic/config/s390/exch_n.c (revision 259627) @@ -0,0 +1,69 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + Contributed by Andreas Krebbel + + This file is part of the GNU Atomic Library (libatomic). + + Libatomic 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 of the License, or + (at your option) any later version. + + Libatomic 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. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#include + + +/* The compiler builtin will use the hardware instruction cdsg if the + memory operand is properly aligned and will fall back to the + library call otherwise. + + In case the compiler for one part is able to detect that the + location is aligned and fails to do so for another usage of the hw + instruction and the sw fall back would be mixed on the same memory + location. To avoid this the library fall back also has to use the + hardware instruction if possible. */ + +#if !DONE && N == 16 +UTYPE +SIZE(libat_exchange) (UTYPE *mptr, UTYPE newval, int smodel UNUSED) +{ + if (!((uintptr_t)mptr & 0xf)) + { + /* Use the builtin only if the memory operand is 16 byte + aligned. */ + return __atomic_exchange_n ((UTYPE *)__builtin_assume_aligned (mptr, 16), + newval, __ATOMIC_SEQ_CST); + } + else + { + UTYPE oldval; + UWORD magic; + + pre_seq_barrier (smodel); + magic = protect_start (mptr); + + oldval = *mptr; + *mptr = newval; + + protect_end (mptr, magic); + post_seq_barrier (smodel); + + return oldval; + } +} +#define DONE 1 +#endif /* N == 16 */ + +#include "../../exch_n.c" Index: libgcc/ChangeLog =================================================================== diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog --- a/libgcc/ChangeLog (revision 257042) +++ b/libgcc/ChangeLog (revision 259627) @@ -1,3 +1,38 @@ +2018-04-02 H.J. Lu + + Backport from mainline + 2018-03-29 H.J. Lu + + PR target/85100 + * config/i386/cpuinfo.c (XCR_XFEATURE_ENABLED_MASK): New. + (XSTATE_FP): Likewise. + (XSTATE_SSE): Likewise. + (XSTATE_YMM): Likewise. + (XSTATE_OPMASK): Likewise. + (XSTATE_ZMM): Likewise. + (XSTATE_HI_ZMM): Likewise. + (XCR_AVX_ENABLED_MASK): Likewise. + (XCR_AVX512F_ENABLED_MASK): Likewise. + (get_available_features): Enable AVX and AVX512 features only + if their states are supported by OSXSAVE. + +2018-03-11 John David Anglin + + Backport from mainline + 2018-03-06 John David Anglin + + * config/pa/fptr.c (_dl_read_access_allowed): New. + (__canonicalize_funcptr_for_compare): Use it. + +2018-02-20 Max Filippov + + Backport from mainline + 2018-02-20 Max Filippov + + * config/xtensa/ieee754-df.S (__adddf3_aux): Add + .literal_position directive. + * config/xtensa/ieee754-sf.S (__addsf3_aux): Likewise. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: libgcc/config/i386/cpuinfo.c =================================================================== diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c --- a/libgcc/config/i386/cpuinfo.c (revision 257042) +++ b/libgcc/config/i386/cpuinfo.c (revision 259627) @@ -220,6 +220,40 @@ unsigned int features = 0; + /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */ +#define XCR_XFEATURE_ENABLED_MASK 0x0 +#define XSTATE_FP 0x1 +#define XSTATE_SSE 0x2 +#define XSTATE_YMM 0x4 +#define XSTATE_OPMASK 0x20 +#define XSTATE_ZMM 0x40 +#define XSTATE_HI_ZMM 0x80 + +#define XCR_AVX_ENABLED_MASK \ + (XSTATE_SSE | XSTATE_YMM) +#define XCR_AVX512F_ENABLED_MASK \ + (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM) + + /* Check if AVX and AVX512 are usable. */ + int avx_usable = 0; + int avx512_usable = 0; + if ((ecx & bit_OSXSAVE)) + { + /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and + ZMM16-ZMM31 states are supported by OSXSAVE. */ + unsigned int xcrlow; + unsigned int xcrhigh; + asm (".byte 0x0f, 0x01, 0xd0" + : "=a" (xcrlow), "=d" (xcrhigh) + : "c" (XCR_XFEATURE_ENABLED_MASK)); + if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK) + { + avx_usable = 1; + avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK) + == XCR_AVX512F_ENABLED_MASK); + } + } + if (edx & bit_CMOV) features |= (1 << FEATURE_CMOV); if (edx & bit_MMX) @@ -242,10 +276,13 @@ features |= (1 << FEATURE_SSE4_1); if (ecx & bit_SSE4_2) features |= (1 << FEATURE_SSE4_2); - if (ecx & bit_AVX) - features |= (1 << FEATURE_AVX); - if (ecx & bit_FMA) - features |= (1 << FEATURE_FMA); + if (avx_usable) + { + if (ecx & bit_AVX) + features |= (1 << FEATURE_AVX); + if (ecx & bit_FMA) + features |= (1 << FEATURE_FMA); + } /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */ if (max_cpuid_level >= 7) @@ -253,34 +290,40 @@ __cpuid_count (7, 0, eax, ebx, ecx, edx); if (ebx & bit_BMI) features |= (1 << FEATURE_BMI); - if (ebx & bit_AVX2) - features |= (1 << FEATURE_AVX2); + if (avx_usable) + { + if (ebx & bit_AVX2) + features |= (1 << FEATURE_AVX2); + } if (ebx & bit_BMI2) features |= (1 << FEATURE_BMI2); - if (ebx & bit_AVX512F) - features |= (1 << FEATURE_AVX512F); - if (ebx & bit_AVX512VL) - features |= (1 << FEATURE_AVX512VL); - if (ebx & bit_AVX512BW) - features |= (1 << FEATURE_AVX512BW); - if (ebx & bit_AVX512DQ) - features |= (1 << FEATURE_AVX512DQ); - if (ebx & bit_AVX512CD) - features |= (1 << FEATURE_AVX512CD); - if (ebx & bit_AVX512PF) - features |= (1 << FEATURE_AVX512PF); - if (ebx & bit_AVX512ER) - features |= (1 << FEATURE_AVX512ER); - if (ebx & bit_AVX512IFMA) - features |= (1 << FEATURE_AVX512IFMA); - if (ecx & bit_AVX512VBMI) - features |= (1 << FEATURE_AVX512VBMI); - if (ecx & bit_AVX512VPOPCNTDQ) - features |= (1 << FEATURE_AVX512VPOPCNTDQ); - if (edx & bit_AVX5124VNNIW) - features |= (1 << FEATURE_AVX5124VNNIW); - if (edx & bit_AVX5124FMAPS) - features |= (1 << FEATURE_AVX5124FMAPS); + if (avx512_usable) + { + if (ebx & bit_AVX512F) + features |= (1 << FEATURE_AVX512F); + if (ebx & bit_AVX512VL) + features |= (1 << FEATURE_AVX512VL); + if (ebx & bit_AVX512BW) + features |= (1 << FEATURE_AVX512BW); + if (ebx & bit_AVX512DQ) + features |= (1 << FEATURE_AVX512DQ); + if (ebx & bit_AVX512CD) + features |= (1 << FEATURE_AVX512CD); + if (ebx & bit_AVX512PF) + features |= (1 << FEATURE_AVX512PF); + if (ebx & bit_AVX512ER) + features |= (1 << FEATURE_AVX512ER); + if (ebx & bit_AVX512IFMA) + features |= (1 << FEATURE_AVX512IFMA); + if (ecx & bit_AVX512VBMI) + features |= (1 << FEATURE_AVX512VBMI); + if (ecx & bit_AVX512VPOPCNTDQ) + features |= (1 << FEATURE_AVX512VPOPCNTDQ); + if (edx & bit_AVX5124VNNIW) + features |= (1 << FEATURE_AVX5124VNNIW); + if (edx & bit_AVX5124FMAPS) + features |= (1 << FEATURE_AVX5124FMAPS); + } } /* Check cpuid level of extended features. */ @@ -292,10 +335,13 @@ if (ecx & bit_SSE4a) features |= (1 << FEATURE_SSE4_A); - if (ecx & bit_FMA4) - features |= (1 << FEATURE_FMA4); - if (ecx & bit_XOP) - features |= (1 << FEATURE_XOP); + if (avx_usable) + { + if (ecx & bit_FMA4) + features |= (1 << FEATURE_FMA4); + if (ecx & bit_XOP) + features |= (1 << FEATURE_XOP); + } } __cpu_model.__cpu_features[0] = features; Index: libgcc/config/pa/fptr.c =================================================================== diff --git a/libgcc/config/pa/fptr.c b/libgcc/config/pa/fptr.c --- a/libgcc/config/pa/fptr.c (revision 257042) +++ b/libgcc/config/pa/fptr.c (revision 259627) @@ -52,6 +52,16 @@ typedef int (*fixup_t) (struct link_map *, unsigned int); extern unsigned int _GLOBAL_OFFSET_TABLE_; +static inline int +_dl_read_access_allowed (unsigned int *addr) +{ + int result; + + asm ("proberi (%1),3,%0" : "=r" (result) : "r" (addr) : ); + + return result; +} + /* __canonicalize_funcptr_for_compare must be hidden so that it is not placed in the dynamic symbol table. Like millicode functions, it must be linked into all binaries in order access the got table of @@ -82,6 +92,16 @@ The second word in the plabel contains the relocation offset for the function. */ plabel = (unsigned int *) ((unsigned int) fptr & ~3); + if (!_dl_read_access_allowed (plabel)) + return (unsigned int) fptr; + + /* Load first word of candidate descriptor. It should be a pointer + with word alignment and point to memory that can be read. */ + got = (unsigned int *) plabel[0]; + if (((unsigned int) got & 3) != 0 + || !_dl_read_access_allowed (got)) + return (unsigned int) fptr; + got = (unsigned int *) (plabel[0] + GOT_FROM_PLT_STUB); /* Return the address of the function if the plabel has been resolved. */ Index: libgcc/config/xtensa/ieee754-df.S =================================================================== diff --git a/libgcc/config/xtensa/ieee754-df.S b/libgcc/config/xtensa/ieee754-df.S --- a/libgcc/config/xtensa/ieee754-df.S (revision 257042) +++ b/libgcc/config/xtensa/ieee754-df.S (revision 259627) @@ -55,6 +55,7 @@ #ifdef L_addsubdf3 + .literal_position /* Addition */ __adddf3_aux: Index: libgcc/config/xtensa/ieee754-sf.S =================================================================== diff --git a/libgcc/config/xtensa/ieee754-sf.S b/libgcc/config/xtensa/ieee754-sf.S --- a/libgcc/config/xtensa/ieee754-sf.S (revision 257042) +++ b/libgcc/config/xtensa/ieee754-sf.S (revision 259627) @@ -55,6 +55,7 @@ #ifdef L_addsubsf3 + .literal_position /* Addition */ __addsf3_aux: Index: gcc/shrink-wrap.c =================================================================== diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c --- a/gcc/shrink-wrap.c (revision 257042) +++ b/gcc/shrink-wrap.c (revision 259627) @@ -1374,6 +1374,8 @@ bitmap_clear_bit (seen, bb->index); } + todo.release (); + /* Finally, mark everything not not needed both forwards and backwards. */ FOR_EACH_BB_FN (bb, cfun) Index: gcc/doc/extend.texi =================================================================== diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi --- a/gcc/doc/extend.texi (revision 257042) +++ b/gcc/doc/extend.texi (revision 259627) @@ -1,4 +1,4 @@ -@c Copyright (C) 1988-2017 Free Software Foundation, Inc. +@c Copyright (C) 1988-2018 Free Software Foundation, Inc. @c This is part of the GCC manual. @c For copying conditions, see the file gcc.texi. @@ -15165,21 +15165,16 @@ @smallexample long __builtin_bpermd (long, long); int __builtin_divwe (int, int); -int __builtin_divweo (int, int); unsigned int __builtin_divweu (unsigned int, unsigned int); -unsigned int __builtin_divweuo (unsigned int, unsigned int); long __builtin_divde (long, long); -long __builtin_divdeo (long, long); unsigned long __builtin_divdeu (unsigned long, unsigned long); -unsigned long __builtin_divdeuo (unsigned long, unsigned long); unsigned int cdtbcd (unsigned int); unsigned int cbcdtd (unsigned int); unsigned int addg6s (unsigned int, unsigned int); @end smallexample -The @code{__builtin_divde}, @code{__builtin_divdeo}, -@code{__builtin_divdeu}, @code{__builtin_divdeou} functions require a -64-bit environment support ISA 2.06 or later. +The @code{__builtin_divde} and @code{__builtin_divdeu} functions +require a 64-bit environment supporting ISA 2.06 or later. The following built-in functions are available for the PowerPC family of processors, starting with ISA 3.0 or later (@option{-mcpu=power9}): @@ -18124,14 +18119,11 @@ vector int vec_vctzw (vector int); vector unsigned int vec_vctzw (vector int); -long long vec_vextract4b (const vector signed char, const int); -long long vec_vextract4b (const vector unsigned char, const int); - -vector signed char vec_insert4b (vector int, vector signed char, const int); +long long vec_extract4b (const vector unsigned char, const int); +vector unsigned char vec_insert4b (vector signed int, vector unsigned char, + const int); vector unsigned char vec_insert4b (vector unsigned int, vector unsigned char, const int); -vector signed char vec_insert4b (long long, vector signed char, const int); -vector unsigned char vec_insert4b (long long, vector unsigned char, const int); vector int vec_vprtyb (vector int); vector unsigned int vec_vprtyb (vector unsigned int); Index: gcc/doc/tm.texi =================================================================== diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi --- a/gcc/doc/tm.texi (revision 257042) +++ b/gcc/doc/tm.texi (revision 259627) @@ -10645,8 +10645,12 @@ @defmac WORD_REGISTER_OPERATIONS Define this macro to 1 if operations between registers with integral mode -smaller than a word are always performed on the entire register. -Most RISC machines have this property and most CISC machines do not. +smaller than a word are always performed on the entire register. To be +more explicit, if you start with a pair of @code{word_mode} registers with +known values and you do a subword, for example @code{QImode}, addition on +the low part of the registers, then the compiler may consider that the +result has a known value in @code{word_mode} too if the macro is defined +to 1. Most RISC machines have this property and most CISC machines do not. @end defmac @deftypefn {Target Hook} {unsigned int} TARGET_MIN_ARITHMETIC_PRECISION (void) Index: gcc/doc/tm.texi.in =================================================================== diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in --- a/gcc/doc/tm.texi.in (revision 257042) +++ b/gcc/doc/tm.texi.in (revision 259627) @@ -7581,8 +7581,12 @@ @defmac WORD_REGISTER_OPERATIONS Define this macro to 1 if operations between registers with integral mode -smaller than a word are always performed on the entire register. -Most RISC machines have this property and most CISC machines do not. +smaller than a word are always performed on the entire register. To be +more explicit, if you start with a pair of @code{word_mode} registers with +known values and you do a subword, for example @code{QImode}, addition on +the low part of the registers, then the compiler may consider that the +result has a known value in @code{word_mode} too if the macro is defined +to 1. Most RISC machines have this property and most CISC machines do not. @end defmac @hook TARGET_MIN_ARITHMETIC_PRECISION Index: gcc/doc/invoke.texi =================================================================== diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi --- a/gcc/doc/invoke.texi (revision 257042) +++ b/gcc/doc/invoke.texi (revision 259627) @@ -1025,7 +1025,7 @@ -mfloat-gprs=yes -mfloat-gprs=no -mfloat-gprs=single -mfloat-gprs=double @gol -mprototype -mno-prototype @gol -msim -mmvme -mads -myellowknife -memb -msdata @gol --msdata=@var{opt} -mvxworks -G @var{num} @gol +-msdata=@var{opt} -mreadonly-in-sdata -mvxworks -G @var{num} @gol -mrecip -mrecip=@var{opt} -mno-recip -mrecip-precision @gol -mno-recip-precision @gol -mveclibabi=@var{type} -mfriz -mno-friz @gol @@ -1211,7 +1211,7 @@ -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol -mmitigate-rop -mgeneral-regs-only @gol --mindirect-branch=@var{choice} -mfunction-return==@var{choice} @gol +-mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol -mindirect-branch-register} @emph{x86 Windows Options} @@ -8132,7 +8132,7 @@ @item -fisolate-erroneous-paths-attribute @opindex fisolate-erroneous-paths-attribute -Detect paths that trigger erroneous or undefined behavior due a null value +Detect paths that trigger erroneous or undefined behavior due to a null value being used in a way forbidden by a @code{returns_nonnull} or @code{nonnull} attribute. Isolate those paths from the main control flow and turn the statement with erroneous or undefined behavior into a trap. This is not @@ -8690,6 +8690,7 @@ in that case, it is rounded up. If @var{n} is not specified or is zero, use a machine-dependent default. +The maximum allowed @var{n} option value is 65536. Enabled at levels @option{-O2}, @option{-O3}. @@ -8715,6 +8716,7 @@ If @var{n} is not specified or is zero, use a machine-dependent default which is very likely to be @samp{1}, meaning no alignment. +The maximum allowed @var{n} option value is 65536. Enabled at levels @option{-O2}, @option{-O3}. @@ -8728,6 +8730,7 @@ @option{-fno-align-loops} and @option{-falign-loops=1} are equivalent and mean that loops are not aligned. +The maximum allowed @var{n} option value is 65536. If @var{n} is not specified or is zero, use a machine-dependent default. @@ -8745,6 +8748,7 @@ equivalent and mean that loops are not aligned. If @var{n} is not specified or is zero, use a machine-dependent default. +The maximum allowed @var{n} option value is 65536. Enabled at levels @option{-O2}, @option{-O3}. @@ -22070,6 +22074,13 @@ in the @code{.data} section, and all uninitialized data in the @code{.bss} section. +@item -mreadonly-in-sdata +@itemx -mreadonly-in-sdata +@opindex mreadonly-in-sdata +@opindex mno-readonly-in-sdata +Put read-only objects in the @code{.sdata} section as well. This is the +default. + @item -mblock-move-inline-limit=@var{num} @opindex mblock-move-inline-limit Inline all block moves (such as calls to @code{memcpy} or structure @@ -25091,8 +25102,8 @@ @itemx -mpclmul @opindex mpclmul @need 200 -@itemx -mclfushopt -@opindex mclfushopt +@itemx -mclflushopt +@opindex mclflushopt @need 200 @itemx -mfsgsbase @opindex mfsgsbase Index: gcc/doc/gcov.texi =================================================================== diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi --- a/gcc/doc/gcov.texi (revision 257042) +++ b/gcc/doc/gcov.texi (revision 259627) @@ -322,7 +322,7 @@ Additional block information may succeed each line, when requested by command line option. The @var{execution_count} is @samp{-} for lines containing no code. Unexecuted lines are marked @samp{#####} or -@samp{====}, depending on whether they are reachable by +@samp{=====}, depending on whether they are reachable by non-exceptional paths or only exceptional paths such as C++ exception handlers, respectively. Given @samp{-a} option, unexecuted blocks are marked @samp{$$$$$} or @samp{%%%%%}, depending on whether a basic block @@ -618,6 +618,8 @@ to invoke the @code{__gcov_dump} function. Thus @code{__gcov_dump} is executed after all user defined static destructors, as well as handlers registered with @code{atexit}. +If an executable loads a dynamic shared object via dlopen functionality, +@option{-Wl,--dynamic-list-data} is needed to dump all profile data. @c man end Index: gcc/doc/rtl.texi =================================================================== diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi --- a/gcc/doc/rtl.texi (revision 257042) +++ b/gcc/doc/rtl.texi (revision 259627) @@ -1291,10 +1291,11 @@ @findex CDImode @findex CTImode @findex COImode -@item CQImode, CHImode, CSImode, CDImode, CTImode, COImode +@findex CPSImode +@item CQImode, CHImode, CSImode, CDImode, CTImode, COImode, CPSImode These modes stand for a complex number represented as a pair of integer values. The integer values are in @code{QImode}, @code{HImode}, -@code{SImode}, @code{DImode}, @code{TImode}, and @code{OImode}, +@code{SImode}, @code{DImode}, @code{TImode}, @code{OImode}, and @code{PSImode}, respectively. @findex BND32mode Index: gcc/tree-ssa-tail-merge.c =================================================================== diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c --- a/gcc/tree-ssa-tail-merge.c (revision 257042) +++ b/gcc/tree-ssa-tail-merge.c (revision 259627) @@ -1454,7 +1454,8 @@ /* TODO: handle blocks with phi-nodes. We'll have to find corresponding phi-nodes in bb1 and bb2, with the same alternatives for the same preds. */ - if (bb_has_non_vop_phi (bb1) || bb_has_eh_pred (bb1)) + if (bb_has_non_vop_phi (bb1) || bb_has_eh_pred (bb1) + || bb_has_abnormal_pred (bb1)) continue; nr_comparisons = 0; @@ -1462,7 +1463,8 @@ { bb2 = BASIC_BLOCK_FOR_FN (cfun, j); - if (bb_has_non_vop_phi (bb2) || bb_has_eh_pred (bb2)) + if (bb_has_non_vop_phi (bb2) || bb_has_eh_pred (bb2) + || bb_has_abnormal_pred (bb2)) continue; if (BB_CLUSTER (bb1) != NULL && BB_CLUSTER (bb1) == BB_CLUSTER (bb2)) Index: gcc/c-family/c-cppbuiltin.c =================================================================== diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c --- a/gcc/c-family/c-cppbuiltin.c (revision 257042) +++ b/gcc/c-family/c-cppbuiltin.c (revision 259627) @@ -1119,7 +1119,7 @@ floatn_nx_types[i].extended ? "X" : ""); sprintf (csuffix, "F%d%s", floatn_nx_types[i].n, floatn_nx_types[i].extended ? "x" : ""); - builtin_define_float_constants (prefix, csuffix, "%s", NULL, + builtin_define_float_constants (prefix, ggc_strdup (csuffix), "%s", NULL, FLOATN_NX_TYPE_NODE (i)); } @@ -1566,7 +1566,14 @@ int digits; const char *fp_suffix; }; -static GTY(()) struct lazy_hex_fp_value_struct lazy_hex_fp_values[12]; +/* Number of the expensive to compute macros we should evaluate lazily. + Each builtin_define_float_constants invocation calls + builtin_define_with_hex_fp_value 4 times and builtin_define_float_constants + is called for FLT, DBL, LDBL and up to NUM_FLOATN_NX_TYPES times for + FLTNN*. */ +#define LAZY_HEX_FP_VALUES_CNT (4 * (3 + NUM_FLOATN_NX_TYPES)) +static GTY(()) struct lazy_hex_fp_value_struct + lazy_hex_fp_values[LAZY_HEX_FP_VALUES_CNT]; static GTY(()) int lazy_hex_fp_value_count; static bool @@ -1611,7 +1618,7 @@ char dec_str[64], buf1[256], buf2[256]; /* This is very expensive, so if possible expand them lazily. */ - if (lazy_hex_fp_value_count < 12 + if (lazy_hex_fp_value_count < LAZY_HEX_FP_VALUES_CNT && flag_dump_macros == 0 && !cpp_get_options (parse_in)->traditional) { Index: gcc/c-family/ChangeLog =================================================================== diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog --- a/gcc/c-family/ChangeLog (revision 257042) +++ b/gcc/c-family/ChangeLog (revision 259627) @@ -1,3 +1,15 @@ +2018-03-03 Jakub Jelinek + + Backported from mainline + 2018-01-27 Jakub Jelinek + + * c-cppbuiltin.c (c_cpp_builtins): Use ggc_strdup for the fp_suffix + argument. + (LAZY_HEX_FP_VALUES_CNT): Define. + (lazy_hex_fp_values): Allow up to LAZY_HEX_FP_VALUES_CNT lazy hex fp + values rather than just 12. + (builtin_define_with_hex_fp_value): Likewise. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: gcc/cgraph.h =================================================================== diff --git a/gcc/cgraph.h b/gcc/cgraph.h --- a/gcc/cgraph.h (revision 257042) +++ b/gcc/cgraph.h (revision 259627) @@ -321,6 +321,9 @@ or abstract function kept for debug info purposes only. */ bool real_symbol_p (void); + /* Return true when the symbol needs to be output to the LTO symbol table. */ + bool output_to_lto_symbol_table_p (void); + /* Determine if symbol declaration is needed. That is, visible to something either outside this translation unit, something magic in the system configury. This function is used just during symbol creation. */ Index: gcc/lra-int.h =================================================================== diff --git a/gcc/lra-int.h b/gcc/lra-int.h --- a/gcc/lra-int.h (revision 257042) +++ b/gcc/lra-int.h (revision 259627) @@ -202,6 +202,10 @@ const struct operand_alternative *operand_alternative; }; +/* Negative insn alternative numbers used for special cases. */ +#define LRA_UNKNOWN_ALT -1 +#define LRA_NON_CLOBBERED_ALT -2 + /* LRA internal info about an insn (LRA internal insn representation). */ struct lra_insn_recog_data @@ -208,9 +212,10 @@ { /* The insn code. */ int icode; - /* The alternative should be used for the insn, -1 if invalid, or we - should try to use any alternative, or the insn is a debug - insn. */ + /* The alternative should be used for the insn, LRA_UNKNOWN_ALT if + unknown, or we should assume any alternative, or the insn is a + debug insn. LRA_NON_CLOBBERED_ALT means ignoring any earlier + clobbers for the insn. */ int used_insn_alternative; /* SP offset before the insn relative to one at the func start. */ HOST_WIDE_INT sp_offset; Index: gcc/DATESTAMP =================================================================== diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP --- a/gcc/DATESTAMP (revision 257042) +++ b/gcc/DATESTAMP (revision 259627) @@ -1 +1 @@ -20180125 +20180425 Index: gcc/lra.c =================================================================== diff --git a/gcc/lra.c b/gcc/lra.c --- a/gcc/lra.c (revision 257042) +++ b/gcc/lra.c (revision 259627) @@ -946,7 +946,7 @@ data = XNEW (struct lra_insn_recog_data); lra_insn_recog_data[uid] = data; data->insn = insn; - data->used_insn_alternative = -1; + data->used_insn_alternative = LRA_UNKNOWN_ALT; data->icode = icode; data->regs = NULL; if (DEBUG_INSN_P (insn)) @@ -1187,7 +1187,7 @@ return data; } insn_static_data = data->insn_static_data; - data->used_insn_alternative = -1; + data->used_insn_alternative = LRA_UNKNOWN_ALT; if (DEBUG_INSN_P (insn)) return data; if (data->icode < 0) Index: gcc/tree.c =================================================================== diff --git a/gcc/tree.c b/gcc/tree.c --- a/gcc/tree.c (revision 257042) +++ b/gcc/tree.c (revision 259627) @@ -5454,9 +5454,10 @@ At this point, it is not needed anymore. */ DECL_SAVED_TREE (decl) = NULL_TREE; - /* Clear the abstract origin if it refers to a method. Otherwise - dwarf2out.c will ICE as we clear TYPE_METHODS and thus the - origin will not be output correctly. */ + /* Clear the abstract origin if it refers to a method. + Otherwise dwarf2out.c will ICE as we splice functions out of + TYPE_FIELDS and thus the origin will not be output + correctly. */ if (DECL_ABSTRACT_ORIGIN (decl) && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl)) && RECORD_OR_UNION_TYPE_P Index: gcc/ipa-cp.c =================================================================== diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c --- a/gcc/ipa-cp.c (revision 257042) +++ b/gcc/ipa-cp.c (revision 259627) @@ -621,6 +621,24 @@ reason = "calls comdat-local function"; } + /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN + works only when inlined. Cloning them may still lead to better code + becuase ipa-cp will not give up on cloning further. If the function is + external this however leads to wrong code becuase we may end up producing + offline copy of the function. */ + if (DECL_EXTERNAL (node->decl)) + for (cgraph_edge *edge = node->callees; !reason && edge; + edge = edge->next_callee) + if (DECL_BUILT_IN (edge->callee->decl) + && DECL_BUILT_IN_CLASS (edge->callee->decl) == BUILT_IN_NORMAL) + { + if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK) + reason = "external function which calls va_arg_pack"; + if (DECL_FUNCTION_CODE (edge->callee->decl) + == BUILT_IN_VA_ARG_PACK_LEN) + reason = "external function which calls va_arg_pack_len"; + } + if (reason && dump_file && !node->alias && !node->thunk.thunk_p) fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n", node->name (), node->order, reason); Index: gcc/ddg.c =================================================================== diff --git a/gcc/ddg.c b/gcc/ddg.c --- a/gcc/ddg.c (revision 257042) +++ b/gcc/ddg.c (revision 259627) @@ -295,11 +295,14 @@ /* Create inter-loop true dependences and anti dependences. */ for (r_use = DF_REF_CHAIN (last_def); r_use != NULL; r_use = r_use->next) { + if (DF_REF_BB (r_use->ref) != g->bb) + continue; + + gcc_assert (!DF_REF_IS_ARTIFICIAL (r_use->ref) + && DF_REF_INSN_INFO (r_use->ref) != NULL); + rtx_insn *use_insn = DF_REF_INSN (r_use->ref); - if (BLOCK_FOR_INSN (use_insn) != g->bb) - continue; - /* ??? Do not handle uses with DF_REF_IN_NOTE notes. */ use_node = get_node_of_insn (g, use_insn); gcc_assert (use_node); Index: gcc/configure =================================================================== diff --git a/gcc/configure b/gcc/configure --- a/gcc/configure (revision 257042) +++ b/gcc/configure (revision 259627) @@ -23571,6 +23571,14 @@ fi +case "$target" in + i?86-*-solaris2.10* | x86_64-*-solaris2.10*) + # SHF_MERGE support in Solaris 10/x86 ld is broken. + if test x"$gnu_ld" = xno; then + gcc_cv_as_shf_merge=no + fi + ;; +esac cat >>confdefs.h <<_ACEOF #define HAVE_GAS_SHF_MERGE `if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi` Index: gcc/lra-eliminations.c =================================================================== diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c --- a/gcc/lra-eliminations.c (revision 257042) +++ b/gcc/lra-eliminations.c (revision 259627) @@ -1178,7 +1178,7 @@ if (bitmap_bit_p (&to_process, INSN_UID (insn))) { lra_push_insn (insn); - lra_set_used_insn_alternative (insn, -1); + lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT); } bitmap_clear (&to_process); } @@ -1409,7 +1409,7 @@ } lra_update_insn_regno_info (insn); lra_push_insn (insn); - lra_set_used_insn_alternative (insn, -1); + lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT); } } Index: gcc/builtins.c =================================================================== diff --git a/gcc/builtins.c b/gcc/builtins.c --- a/gcc/builtins.c (revision 257042) +++ b/gcc/builtins.c (revision 259627) @@ -7538,8 +7538,7 @@ const_tree argtype, parmtype; const_call_expr_arg_iterator iter; - if (TREE_CODE (t) != CALL_EXPR - || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR) + if (TREE_CODE (t) != CALL_EXPR) return END_BUILTINS; fndecl = get_callee_fndecl (t); Index: gcc/final.c =================================================================== diff --git a/gcc/final.c b/gcc/final.c --- a/gcc/final.c (revision 257042) +++ b/gcc/final.c (revision 259627) @@ -906,7 +906,7 @@ char *varying_length; rtx body; int uid; - rtx align_tab[MAX_CODE_ALIGN]; + rtx align_tab[MAX_CODE_ALIGN + 1]; /* Compute maximum UID and allocate label_align / uid_shuid. */ max_uid = get_max_uid (); @@ -1015,7 +1015,7 @@ alignment of n. */ uid_align = XCNEWVEC (rtx, max_uid); - for (i = MAX_CODE_ALIGN; --i >= 0;) + for (i = MAX_CODE_ALIGN + 1; --i >= 0;) align_tab[i] = NULL_RTX; seq = get_last_insn (); for (; seq; seq = PREV_INSN (seq)) Index: gcc/gcc.c =================================================================== diff --git a/gcc/gcc.c b/gcc/gcc.c --- a/gcc/gcc.c (revision 257042) +++ b/gcc/gcc.c (revision 259627) @@ -677,7 +677,7 @@ #ifndef LIBASAN_SPEC #define STATIC_LIBASAN_LIBS \ - " %{static-libasan:%:include(libsanitizer.spec)%(link_libasan)}" + " %{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)}" #ifdef LIBASAN_EARLY_SPEC #define LIBASAN_SPEC STATIC_LIBASAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) @@ -695,7 +695,7 @@ #ifndef LIBTSAN_SPEC #define STATIC_LIBTSAN_LIBS \ - " %{static-libtsan:%:include(libsanitizer.spec)%(link_libtsan)}" + " %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}" #ifdef LIBTSAN_EARLY_SPEC #define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) @@ -713,7 +713,7 @@ #ifndef LIBLSAN_SPEC #define STATIC_LIBLSAN_LIBS \ - " %{static-liblsan:%:include(libsanitizer.spec)%(link_liblsan)}" + " %{static-liblsan|static:%:include(libsanitizer.spec)%(link_liblsan)}" #ifdef LIBLSAN_EARLY_SPEC #define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) @@ -731,7 +731,7 @@ #ifndef LIBUBSAN_SPEC #define STATIC_LIBUBSAN_LIBS \ - " %{static-libubsan:%:include(libsanitizer.spec)%(link_libubsan)}" + " %{static-libubsan|static:%:include(libsanitizer.spec)%(link_libubsan)}" #ifdef HAVE_LD_STATIC_DYNAMIC #define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \ "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \ @@ -6970,8 +6970,8 @@ /* In final attempt we append compiler options and preprocesssed code to last generated .out file with configuration and backtrace. */ - char **output = &temp_stdout_files[RETRY_ICE_ATTEMPTS - 1]; - do_report_bug (new_argv, nargs, stderr_commented, output); + char **err = &temp_stderr_files[RETRY_ICE_ATTEMPTS - 1]; + do_report_bug (new_argv, nargs, stderr_commented, err); } out: Index: gcc/tree-emutls.c =================================================================== diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c --- a/gcc/tree-emutls.c (revision 257042) +++ b/gcc/tree-emutls.c (revision 259627) @@ -34,6 +34,7 @@ #include "gimple-walk.h" #include "langhooks.h" #include "tree-iterator.h" +#include "gimplify.h" /* Whenever a target does not support thread-local storage (TLS) natively, we can emulate it with some run-time support in libgcc. This will in @@ -430,6 +431,20 @@ return addr; } +/* Callback for lower_emutls_1, return non-NULL if there is any TLS + VAR_DECL in the subexpressions. */ + +static tree +lower_emutls_2 (tree *ptr, int *walk_subtrees, void *) +{ + tree t = *ptr; + if (TREE_CODE (t) == VAR_DECL) + return DECL_THREAD_LOCAL_P (t) ? t : NULL_TREE; + else if (!EXPR_P (t)) + *walk_subtrees = 0; + return NULL_TREE; +} + /* Callback for walk_gimple_op. D = WI->INFO is a struct lower_emutls_data. Given an operand *PTR within D->STMT, if the operand references a TLS variable, then lower the reference to a call to the runtime. Insert @@ -456,6 +471,13 @@ { bool save_changed; + /* Gimple invariants are shareable trees, so before changing + anything in them if we will need to change anything, unshare + them. */ + if (is_gimple_min_invariant (t) + && walk_tree (&TREE_OPERAND (t, 0), lower_emutls_2, NULL, NULL)) + *ptr = t = unshare_expr (t); + /* If we're allowed more than just is_gimple_val, continue. */ if (!wi->val_only) { Index: gcc/fold-const.c =================================================================== diff --git a/gcc/fold-const.c b/gcc/fold-const.c --- a/gcc/fold-const.c (revision 257042) +++ b/gcc/fold-const.c (revision 259627) @@ -14082,6 +14082,7 @@ { tree op = TREE_OPERAND (sub, 0); tree optype = TREE_TYPE (op); + /* *&CONST_DECL -> to the value of the const decl. */ if (TREE_CODE (op) == CONST_DECL) return DECL_INITIAL (op); @@ -14115,12 +14116,13 @@ && type == TREE_TYPE (optype)) return fold_build1_loc (loc, REALPART_EXPR, type, op); /* *(foo *)&vectorfoo => BIT_FIELD_REF */ - else if (TREE_CODE (optype) == VECTOR_TYPE + else if (VECTOR_TYPE_P (optype) && type == TREE_TYPE (optype)) { tree part_width = TYPE_SIZE (type); tree index = bitsize_int (0); - return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index); + return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, + index); } } @@ -14138,8 +14140,17 @@ op00type = TREE_TYPE (op00); /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF */ - if (TREE_CODE (op00type) == VECTOR_TYPE - && type == TREE_TYPE (op00type)) + if (VECTOR_TYPE_P (op00type) + && type == TREE_TYPE (op00type) + /* POINTER_PLUS_EXPR second operand is sizetype, unsigned, + but we want to treat offsets with MSB set as negative. + For the code below negative offsets are invalid and + TYPE_SIZE of the element is something unsigned, so + check whether op01 fits into HOST_WIDE_INT, which + implies it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and + then just use unsigned HOST_WIDE_INT because we want to treat + the value as unsigned. */ + && tree_fits_shwi_p (op01)) { tree part_width = TYPE_SIZE (type); unsigned HOST_WIDE_INT max_offset Index: gcc/lra-spills.c =================================================================== diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c --- a/gcc/lra-spills.c (revision 257042) +++ b/gcc/lra-spills.c (revision 259627) @@ -503,7 +503,7 @@ INSN_UID (insn)); lra_push_insn (insn); if (lra_reg_spill_p || targetm.different_addr_displacement_p ()) - lra_set_used_insn_alternative (insn, -1); + lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT); } else if (CALL_P (insn) /* Presence of any pseudo in CALL_INSN_FUNCTION_USAGE Index: gcc/omp-low.c =================================================================== diff --git a/gcc/omp-low.c b/gcc/omp-low.c --- a/gcc/omp-low.c (revision 257042) +++ b/gcc/omp-low.c (revision 259627) @@ -3261,6 +3261,43 @@ /* Re-gimplification and code generation routines. */ +/* Remove omp_member_access_dummy_var variables from gimple_bind_vars + of BIND if in a method. */ + +static void +maybe_remove_omp_member_access_dummy_vars (gbind *bind) +{ + if (DECL_ARGUMENTS (current_function_decl) + && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl)) + && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl))) + == POINTER_TYPE)) + { + tree vars = gimple_bind_vars (bind); + for (tree *pvar = &vars; *pvar; ) + if (omp_member_access_dummy_var (*pvar)) + *pvar = DECL_CHAIN (*pvar); + else + pvar = &DECL_CHAIN (*pvar); + gimple_bind_set_vars (bind, vars); + } +} + +/* Remove omp_member_access_dummy_var variables from BLOCK_VARS of + block and its subblocks. */ + +static void +remove_member_access_dummy_vars (tree block) +{ + for (tree *pvar = &BLOCK_VARS (block); *pvar; ) + if (omp_member_access_dummy_var (*pvar)) + *pvar = DECL_CHAIN (*pvar); + else + pvar = &DECL_CHAIN (*pvar); + + for (block = BLOCK_SUBBLOCKS (block); block; block = BLOCK_CHAIN (block)) + remove_member_access_dummy_vars (block); +} + /* If a context was created for STMT when it was scanned, return it. */ static omp_context * @@ -7002,6 +7039,7 @@ pop_gimplify_context (new_stmt); gimple_bind_append_vars (new_stmt, ctx->block_vars); + maybe_remove_omp_member_access_dummy_vars (new_stmt); BLOCK_VARS (block) = gimple_bind_vars (new_stmt); if (BLOCK_VARS (block)) TREE_USED (block) = 1; @@ -7452,6 +7490,7 @@ /* Declare all the variables created by mapping and the variables declared in the scope of the parallel body. */ record_vars_into (ctx->block_vars, child_fn); + maybe_remove_omp_member_access_dummy_vars (par_bind); record_vars_into (gimple_bind_vars (par_bind), child_fn); if (ctx->record_type) @@ -7820,6 +7859,7 @@ /* Declare all the variables created by mapping and the variables declared in the scope of the target body. */ record_vars_into (ctx->block_vars, child_fn); + maybe_remove_omp_member_access_dummy_vars (tgt_bind); record_vars_into (gimple_bind_vars (tgt_bind), child_fn); } @@ -8811,6 +8851,7 @@ break; case GIMPLE_BIND: lower_omp (gimple_bind_body_ptr (as_a (stmt)), ctx); + maybe_remove_omp_member_access_dummy_vars (as_a (stmt)); break; case GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: @@ -9015,6 +9056,16 @@ all_contexts = NULL; } BITMAP_FREE (task_shared_vars); + + /* If current function is a method, remove artificial dummy VAR_DECL created + for non-static data member privatization, they aren't needed for + debuginfo nor anything else, have been already replaced everywhere in the + IL and cause problems with LTO. */ + if (DECL_ARGUMENTS (current_function_decl) + && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl)) + && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl))) + == POINTER_TYPE)) + remove_member_access_dummy_vars (DECL_INITIAL (current_function_decl)); return 0; } Index: gcc/reorg.c =================================================================== diff --git a/gcc/reorg.c b/gcc/reorg.c --- a/gcc/reorg.c (revision 257042) +++ b/gcc/reorg.c (revision 259627) @@ -1035,7 +1035,8 @@ static void steal_delay_list_from_target (rtx_insn *insn, rtx condition, rtx_sequence *seq, - vec *delay_list, resources *sets, + vec *delay_list, + struct resources *sets, struct resources *needed, struct resources *other_needed, int slots_to_fill, int *pslots_filled, @@ -1048,7 +1049,7 @@ int used_annul = 0; int i; struct resources cc_set; - bool *redundant; + rtx_insn **redundant; /* We can't do anything if there are more delay slots in SEQ than we can handle, or if we don't know that it will be a taken branch. @@ -1087,7 +1088,7 @@ if (! targetm.can_follow_jump (insn, seq->insn (0))) return; - redundant = XALLOCAVEC (bool, XVECLEN (seq, 0)); + redundant = XALLOCAVEC (rtx_insn *, XVECLEN (seq, 0)); for (i = 1; i < seq->len (); i++) { rtx_insn *trial = seq->insn (i); @@ -1151,7 +1152,10 @@ we therefore decided not to copy. */ for (i = 1; i < seq->len (); i++) if (redundant[i]) - update_block (seq->insn (i), insn); + { + fix_reg_dead_note (redundant[i], insn); + update_block (seq->insn (i), insn); + } /* Show the place to which we will be branching. */ *pnew_thread = first_active_target_insn (JUMP_LABEL (seq->insn (0))); @@ -1198,6 +1202,7 @@ for (i = 1; i < seq->len (); i++) { rtx_insn *trial = seq->insn (i); + rtx_insn *prior_insn; /* If TRIAL sets CC0, stealing it will move it too far from the use of CC0. */ @@ -1209,8 +1214,9 @@ break; /* If this insn was already done, we don't need it. */ - if (redundant_insn (trial, insn, *delay_list)) + if ((prior_insn = redundant_insn (trial, insn, *delay_list))) { + fix_reg_dead_note (prior_insn, insn); update_block (trial, insn); delete_from_delay_slot (trial); continue; @@ -1790,15 +1796,14 @@ } } -/* Delete any REG_UNUSED notes that exist on INSN but not on REDUNDANT_INSN. +/* Delete any REG_UNUSED notes that exist on INSN but not on OTHER_INSN. This handles the case of udivmodXi4 instructions which optimize their - output depending on whether any REG_UNUSED notes are present. - we must make sure that INSN calculates as many results as REDUNDANT_INSN - does. */ + output depending on whether any REG_UNUSED notes are present. We must + make sure that INSN calculates as many results as OTHER_INSN does. */ static void -update_reg_unused_notes (rtx_insn *insn, rtx redundant_insn) +update_reg_unused_notes (rtx_insn *insn, rtx other_insn) { rtx link, next; @@ -1810,8 +1815,7 @@ || !REG_P (XEXP (link, 0))) continue; - if (! find_regno_note (redundant_insn, REG_UNUSED, - REGNO (XEXP (link, 0)))) + if (!find_regno_note (other_insn, REG_UNUSED, REGNO (XEXP (link, 0)))) remove_note (insn, link); } } @@ -2324,9 +2328,8 @@ taken and THREAD_IF_TRUE is set. This is used for the branch at the end of a loop back up to the top. - OWN_THREAD and OWN_OPPOSITE_THREAD are true if we are the only user of the - thread. I.e., it is the fallthrough code of our jump or the target of the - jump when we are the only jump going there. + OWN_THREAD is true if we are the only user of the thread, i.e. it is + the target of the jump when we are the only jump going there. If OWN_THREAD is false, it must be the "true" thread of a jump. In that case, we can only take insns from the head of the thread for our delay @@ -3117,7 +3120,7 @@ /* Look at every JUMP_INSN and see if we can improve it. */ for (insn = first; insn; insn = next) { - rtx_insn *other; + rtx_insn *other, *prior_insn; bool crossing; next = next_active_insn (insn); @@ -3223,8 +3226,9 @@ /* See if the first insn in the delay slot is redundant with some previous insn. Remove it from the delay slot if so; then set up to reprocess this insn. */ - if (redundant_insn (pat->insn (1), delay_insn, vNULL)) + if ((prior_insn = redundant_insn (pat->insn (1), delay_insn, vNULL))) { + fix_reg_dead_note (prior_insn, insn); update_block (pat->insn (1), insn); delete_from_delay_slot (pat->insn (1)); next = prev_active_insn (next); Index: gcc/ChangeLog =================================================================== diff --git a/gcc/ChangeLog b/gcc/ChangeLog --- a/gcc/ChangeLog (revision 257042) +++ b/gcc/ChangeLog (revision 259627) @@ -1,3 +1,1217 @@ +2018-04-24 Martin Liska + + Backport from mainline + 2018-04-17 Martin Liska + + PR lto/85405 + * ipa-devirt.c (odr_types_equivalent_p): Remove trailing + in message, remote space in between '_G' and '('. + +2018-04-24 Martin Liska + + Backport from mainline + 2018-04-17 Jan Hubicka + + PR lto/85405 + * ipa-devirt.c (odr_types_equivalent_p): Handle bit fields. + +2018-04-24 Martin Liska + + Backport from mainline + 2018-03-28 Jakub Jelinek + Martin Liska + + PR sanitizer/85081 + * gimplify.c (asan_poison_variable): Don't do the check for + gimplify_omp_ctxp here. + (gimplify_decl_expr): Do it here. + (gimplify_target_expr): Likewise. + +2018-04-24 Martin Liska + + Backport from mainline + 2018-03-21 Martin Liska + + PR ipa/84963 + * ipa-icf.c (sem_item_optimizer::fixup_points_to_sets): Remove + not intended return statement. + +2018-04-24 Martin Liska + + Backport from mainline + 2018-03-13 Martin Liska + + PR ipa/84658. + * (sem_item_optimizer::sem_item_optimizer): Initialize new + vector. + (sem_item_optimizer::~sem_item_optimizer): Release it. + (sem_item_optimizer::merge_classes): Register variable aliases. + (sem_item_optimizer::fixup_pt_set): New function. + (sem_item_optimizer::fixup_points_to_sets): Likewise. + * ipa-icf.h: Declare new variables and functions. + +2018-04-23 Aaron Sawdey + + Backport from mainline + 2018-04-16 Aaron Sawdey + + PR target/83660 + * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Mark + vec_extract expression as having side effects to make sure it gets + a cleanup point. + +2018-04-23 Eric Botcazou + + PR middle-end/85496 + * expr.c (store_field): In the bitfield case, if the value comes from + a function call and is returned in registers by means of a PARALLEL, + do not change the mode of the temporary unless BLKmode and VOIDmode. + +2018-04-20 Peter Bergner + + Backport from mainline + 2018-03-09 Peter Bergner + + PR target/83969 + * config/rs6000/rs6000.c (rs6000_offsettable_memref_p): New prototype. + Add strict argument and use it. + (rs6000_split_multireg_move): Update for new strict argument. + (mem_operand_gpr): Disallow all non-offsettable addresses. + * config/rs6000/rs6000.md (*movdi_internal64): Use YZ constraint. + +2018-04-18 Thomas Preud'homme + + Backport from mainline + 2018-04-11 Thomas Preud'homme + + PR target/85261 + * config/arm/arm-builtins.c (arm_expand_builtin): Force input operand + into register. + +2018-04-12 Andreas Krebbel + + Backport from mainline + 2018-04-12 Andreas Krebbel + + * config/s390/s390.c (s390_output_indirect_thunk_function): Check + also for flag_dwarf2_cfi_asm. + +2018-04-11 Uros Bizjak + + * config/alpha/alpha.md (stack_probe_internal): Rename + from "probe_stack". Update all callers. + +2018-04-11 Thomas Preud'homme + + Backport from mainline + 2018-04-04 Thomas Preud'homme + + PR target/85203 + * config/arm/arm-builtins.c (arm_expand_builtin): Change + expansion to perform a bitwise AND of the argument followed by a + boolean negation of the result. + +2018-04-10 Kyrylo Tkachov + + Backport from mainline + 2018-03-08 Kyrylo Tkachov + + PR target/84748 + * config/aarch64/aarch64.md (*compare_cstore_insn): Mark pattern + as clobbering CC_REGNUM. + +2018-04-06 Eric Botcazou + + PR target/85196 + * config/sparc/sparc.c (sparc_expand_move): Deal with symbolic operands + based on LABEL_REF. Remove useless assertion. + (pic_address_needs_scratch): Fix formatting. + (sparc_legitimize_pic_address): Minor tweaks. + (sparc_delegitimize_address): Adjust assertion accordingly. + * config/sparc/sparc.md (movsi_pic_label_ref): Change label_ref_operand + into symbolic_operand. + (movsi_high_pic_label_ref): Likewise. + (movsi_lo_sum_pic_label_ref): Likewise. + (movdi_pic_label_ref): Likewise. + (movdi_high_pic_label_ref): Likewise. + (movdi_lo_sum_pic_label_ref): Likewise. + +2018-04-06 Amaan Cheval + + * config.gcc (x86_64-*-rtems*): Add rtems.h to tm_file for + custom LIB_SPEC setup. + +2018-04-05 Uros Bizjak + + PR target/85193 + * config/i386/i386.md (define_attr "memory"): Handle rotate1 type. + +2018-04-04 Peter Bergner + + Backport from mainline + 2018-04-04 Peter Bergner + + PR rtl-optimization/84878 + * ddg.c (add_cross_iteration_register_deps): Use DF_REF_BB to determine + the basic block. Assert the use reference is not artificial and that + it has an associated insn. + +2018-04-03 Uros Bizjak + + * config/i386/i386.c (emit_i387_cw_initialization): Always use logic + instructions when changing rounding bits to preserve precision bits + in the x87 control word. + +2018-04-03 Cesar Philippidis + + Backport from mainline + 2018-03-27 Cesar Philippidis + + PR target/85056 + * config/nvptx/nvptx.c (nvptx_assemble_decl_begin): Add '[]' to + extern array declarations. + +2018-04-02 Peter Bergner + + Backport from mainline + 2018-03-28 Peter Bergner + + PR target/84912 + * config/rs6000/rs6000.h: Update copyright date. + (RS6000_BTM_POWERPC64): New define. + (RS6000_BTM_COMMON): Add RS6000_BTM_POWERPC64. + * config/rs6000/rs6000.c: Update copyright date. + (rs6000_builtin_mask_calculate): Add support for RS6000_BTM_POWERPC64. + (rs6000_invalid_builtin): Add handling for RS6000_BTM_POWERPC64 + (rs6000_builtin_mask_names): Add RS6000_BTM_POWERPC64. + * config/rs6000/rs6000-builtin.def: Update copyright date. + (BU_P7_POWERPC64_MISC_2): New macro definition. + (DIVDE): Use it. + (DIVDEU): Likewise. + + Backport from mainline + 2018-03-28 Peter Bergner + + PR target/84912 + * config/rs6000/rs6000-builtin.def (DIVWEO): Delete macro expansion. + (DIVWEUO): Likewise. + (DIVDEO): Likewise. + (DIVDEUO): Likewise. + * config/rs6000/rs6000.c (builtin_function_type): Remove support for + DIVWEUO and DIVDEUO. + * config/rs6000/rs6000.md: Update copyright date. + (UNSPEC_DIVEO, UNSPEC_DIVEUO): Delete unspecs. + (UNSPEC_DIV_EXTEND): Remove deleted unspecs. + (div_extend): Likewise. + * doc/extend.texi: Update copyright date. + (__builtin_divweo): Remove documentation for deleted builtin function. + (__builtin_divweuo): Likewise. + (__builtin_divdeo): Likewise. + (__builtin_divdeuo): Likewise. + +2018-04-02 Peter Bergner + + Backport from mainline + 2018-03-30 Peter Bergner + + PR target/80546 + * config/rs6000/vsx.md (??r): New mode attribute. + (*vsx_mov_64bit): Use it. + (*vsx_mov_32bit): Likewise. + +2018-03-29 Sebastian Peryt + + PR c++/84783 + * config/i386/avx512vlintrin.h (_mm256_permutexvar_epi64) + (_mm256_permutexvar_epi32, _mm256_permutex_epi64): New intrinsics. + +2018-03-29 Sudakshina Das + + Backport from mainline + 2018-03-22 Sudakshina Das + + PR target/84826 + * config/arm/arm.h (machine_function): Add static_chain_stack_bytes. + * config/arm/arm.c (arm_compute_static_chain_stack_bytes): Avoid + re-computing once computed. + (arm_expand_prologue): Compute machine->static_chain_stack_bytes. + (arm_init_machine_status): Initialize + machine->static_chain_stack_bytes. + +2018-03-28 Sudakshina Das + + 2018-03-19 Sudakshina Das + PR target/81647 + + * config/aarch64/aarch64-simd.md (vec_cmp): Modify + instructions for UNLT, UNLE, UNGT, UNGE, UNEQ, UNORDERED and ORDERED. + +2018-03-28 Kyrylo Tkachov + + Backport from mainline + 2018-03-23 Kyrylo Tkachov + + PR target/85026 + * config/arm/arm.md (unaligned_loadhis): Remove first alternative. + Clean up attributes. + +2018-03-28 Segher Boessenkool + + Backport from mainline + 2018-03-08 Segher Boessenkool + + PR target/82411 + * config/rs6000/rs6000.c (rs6000_elf_in_small_data_p): Don't put + readonly data in sdata, if that is disabled. + * config/rs6000/sysv4.opt (mreadonly-in-sdata): New option. + * doc/invoke.texi (RS/6000 and PowerPC Options): Document + -mreadonly-in-sdata option. + +2018-03-27 Sudakshina Das + + Backport from mainline: + 2018-03-20 Sudakshina Das + + PR target/82989 + * config/arm/neon.md (ashldi3_neon): Update ?s for constraints + to favor GPR over NEON registers. + (di3_neon): Likewise. + +2018-03-27 Kyrylo Tkachov + + Backport from mainline + 2018-03-20 Kyrylo Tkachov + + PR target/82518 + * config/arm/arm.c (arm_array_mode_supported_p): Return false for + BYTES_BIG_ENDIAN. + +2018-03-23 Peter Bergner + + Backport from mainline + 2018-03-20 Peter Bergner + + PR target/83789 + * config/rs6000/altivec.md (altivec_lvx__2op): Delete define_insn. + (altivec_lvx__1op): Likewise. + (altivec_stvx__2op): Likewise. + (altivec_stvx__1op): Likewise. + (altivec_lvx_): New define_expand. + (altivec_stvx_): Likewise. + (altivec_lvx__2op_): New define_insn. + (altivec_lvx__1op_): Likewise. + (altivec_stvx__2op_): Likewise. + (altivec_stvx__1op_): Likewise. + * config/rs6000/rs6000.c (altivec_expand_lv_builtin): Likewise. + (altivec_expand_stv_builtin): Likewise. + (altivec_expand_builtin): Likewise. + * config/rs6000/vector.md: Likewise. + +2018-03-23 Carl Love + + Backport from mainline: + 2018-03-14 Carl Love + + * config/rs6000/r6000.c (rtx_is_swappable_p): Add case UNSPEC_VPERMXOR. + +2018-03-22 Tom de Vries + + backport from trunk: + 2018-03-22 Tom de Vries + + PR tree-optimization/84956 + * tree-ssa-tail-merge.c (find_clusters_1): Skip bbs with + bb_has_abnormal_pred. + +2018-03-19 H.J. Lu + + Backport from mainline + 2018-03-15 H.J. Lu + + PR target/84574 + * config/i386/i386.c (indirect_thunk_needed): Update comments. + (indirect_thunk_bnd_needed): Likewise. + (indirect_thunks_used): Likewise. + (indirect_thunks_bnd_used): Likewise. + (indirect_return_needed): New. + (indirect_return_bnd_needed): Likewise. + (output_indirect_thunk_function): Add a bool argument for + function return. + (output_indirect_thunk_function): Don't generate alias for + function return thunk. + (ix86_code_end): Call output_indirect_thunk_function to generate + function return thunks. + (ix86_output_function_return): Set indirect_return_bnd_needed + and indirect_return_needed instead of indirect_thunk_bnd_needed + and indirect_thunk_needed. + +2018-03-14 John David Anglin + + PR target/83451 + * config/pa/pa.c (pa_emit_move_sequence): Always emit secondary reload + insn for floating-point loads and stores. + +2018-03-12 Jonathan Wakely + + * doc/invoke.texi (-mclflushopt): Fix spelling of option. + +2018-03-12 Richard Sandiford + + PR tree-optimization/84485 + * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Return + true for zero dependence distances if the step might be zero, + and if there is no metadata that guarantees correctness. + (vect_analyze_data_ref_access): Check safelen as well as + force_vectorize. + +2018-03-11 John David Anglin + + Backport from mainline + 2018-02-14 John David Anglin + + PR target/83984 + * config/pa/pa.md: Load address of PIC label using the linkage table + if the label is nonlocal. + + Backport from mainline + 2018-03-06 John David Anglin + + * config/pa/pa.h (ASM_GENERATE_INTERNAL_LABEL): Revise to use + sprint_ul. + (ASM_OUTPUT_ADDR_VEC_ELT): Revise for above change. + (ASM_OUTPUT_ADDR_DIFF_ELT): Likewise. + * config/pa/pa64-hpux.h (ASM_GENERATE_INTERNAL_LABEL): Revise as above. + +2018-03-09 Kugan Vivekanandarajah + + Backport from mainline + 2017-09-13 Kugan Vivekanandarajah + + * config/aarch64/aarch64.c (aarch64_override_options_after_change_1): + Disable pc relative literal load irrespective of TARGET_FIX_ERR_A53_84341 + for default. + +2018-03-06 Denis Chertykov + + Backport from mainline + 2018-02-07 Georg-Johann Lay + + PR target/84209 + * config/avr/avr.h (GENERAL_REGNO_P, GENERAL_REG_P): New macros. + * config/avr/avr.md: Only post-reload split REG-REG moves if + either register is GENERAL_REG_P. + +2018-03-06 Carl Love + + Backport from mainline + 2/16/18 commit 257748 Carl Love + + * config/rs6000/altivec.h: Remove vec_vextract4b and vec_vinsert4b. + * config/rs6000/rs6000-builtin.def: Remove macro expansion for + VINSERT4B_DI and VINSERT4B. + * config/rs6000/rs6000.c: Remove case statements for + P9V_BUILTIN_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, + and P9V_BUILTIN_VEC_VINSERT4B. + * config/rs6000/rs6000-c.c (altivec_expand_builtin): Remove entries for + P9V_BUILTIN_VEC_VEXTRACT4B and P9V_BUILTIN_VEC_VINSERT4B. + * config/rs6000/vsx.md: Remove define_expand vinsert4b, + define_insn *vinsert4b_internal, define_insn "*vinsert4b_di_internal. + * doc/extend.texi: Remove vec_vextract4b, non ABI definitions for + vec_insert4b. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-20 Martin Liska + + PR c/84310 + PR target/79747 + * final.c (shorten_branches): Build align_tab array with one + more element. + * opts.c (finish_options): Add alignment option limit check. + (MAX_CODE_ALIGN): Likewise. + (MAX_CODE_ALIGN_VALUE): Likewise. + * doc/invoke.texi: Document maximum allowed option value for + all -falign-* options. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-19 Martin Liska + + PR other/80589 + * doc/invoke.texi: Fix typo. + * params.def (PARAM_MAX_LOOP_HEADER_INSNS): Likewise. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-05 Martin Liska + + PR gcov-profile/84137 + * doc/gcov.texi: Fix typo in documentation. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-05 Martin Liska + + PR gcov-profile/83879 + * doc/gcov.texi: Document necessity of --dynamic-list-data when + using dlopen functionality. + +2018-03-06 Martin Liska + + Backport from mainline + 2017-12-19 Martin Liska + + PR rtl-optimization/82675 + * loop-unroll.c (unroll_loop_constant_iterations): Allocate one + more element in sbitmap. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-03-05 Martin Liska + + * ipa-utils.c (ipa_merge_profiles): Do not merge alias or + a function without profile. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-21 Jan Hubicka + + PR c/84229 + * ipa-cp.c (determine_versionability): Do not version functions caling + va_arg_pack. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-08 Jan Hubicka + + PR ipa/81360 + * cgraph.h (symtab_node::output_to_lto_symbol_table_p): Declare + * symtab.c: Include builtins.h + (symtab_node::output_to_lto_symbol_table_p): Move here + from lto-streamer-out.c:output_symbol_p. + * lto-streamer-out.c (write_symbol): Turn early exit to assert. + (output_symbol_p): Move all logic to symtab.c + (produce_symtab): Update. + +2018-03-06 Peter Bergner + + Backport from mainline + 2018-02-22 Vladimir Makarov + + PR target/81572 + * lra-int.h (LRA_UNKNOWN_ALT, LRA_NON_CLOBBERED_ALT): New macros. + * lra.c (lra_set_insn_recog_data, lra_update_insn_recog_data): Use + LRA_UNKNOWN_ALT. + * lra-constraints.c (curr_insn_transform): Set up + LRA_NON_CLOBBERED_ALT for moves processed on the fast path. Use + LRA_UNKNOWN_ALT. + (remove_inheritance_pseudos): Use LRA_UNKNOWN_ALT. + * lra-eliminations.c (spill_pseudos): Ditto. + (process_insn_for_elimination): Ditto. + * lra-lives.c (reg_early_clobber_p): Use the new macros. + * lra-spills.c (spill_pseudos): Use LRA_UNKNOWN_ALT and + LRA_NON_CLOBBERED_ALT. + +2018-03-06 Richard Biener + + Backport from mainline + 2018-03-05 Richard Biener + + PR tree-optimization/84486 + * tree-ssa-pre.c (create_expression_by_pieces): Remove dead code. + When inserting a __builtin_assume_aligned call set the LHS + SSA name alignment info accordingly. + + 2018-02-28 Richard Biener + + PR middle-end/84607 + * genmatch.c (capture_info::walk_match): Do not mark + captured expressions without operands as expr_p given + they act more like predicates and should be subject to + "lost tail" side-effect preserving. + +2018-03-05 Jakub Jelinek + + PR target/84524 + * config/i386/sse.md (*3): Replace with + orig,vex. + (*3): Likewise. Remove uses. + +2018-03-03 Jakub Jelinek + + Backported from mainline + 2018-03-02 Jakub Jelinek + Richard Biener + + PR ipa/84628 + * expr.c (expand_expr_real_1) : Don't emit diagnostics + for error or warning attributes if CALL_FROM_THUNK_P is set. + Formatting fixes. + + 2018-03-02 Jakub Jelinek + + PR inline-asm/84625 + * config/i386/i386.c (ix86_print_operand): Use conditional + output_operand_lossage instead of gcc_assert if CONST_VECTOR is not + zero vector. + + 2018-02-23 Jakub Jelinek + + * ipa-prop.c (ipa_vr_ggc_hash_traits::hash): Hash p->min and + p->max as pointers rather than using iterative_hash_expr. + + 2017-11-10 Jakub Jelinek + + PR bootstrap/82916 + * gimple-ssa-store-merging.c + (pass_store_merging::terminate_all_aliasing_chains): For + gimple_store_p stmts also call refs_output_dependent_p. + + 2018-02-19 Jakub Jelinek + + PR c++/84444 + * builtins.c (builtin_mathfn_code): Don't check if CALL_EXPR_FN (t) + is ADDR_EXPR. + + 2018-02-16 Jakub Jelinek + + PR ipa/84425 + * ipa-inline.c (inline_small_functions): Fix a typo. + + 2018-02-13 Jakub Jelinek + + PR c/82210 + * stor-layout.c (place_field): For variable length fields, adjust + offset_align afterwards not just based on the field's alignment, + but also on the size. + + 2018-02-10 Jakub Jelinek + + PR sanitizer/83987 + * omp-low.c (maybe_remove_omp_member_access_dummy_vars, + remove_member_access_dummy_vars): New functions. + (lower_omp_for, lower_omp_taskreg, lower_omp_target, + lower_omp_1, execute_lower_omp): Use them. + + PR rtl-optimization/84308 + * shrink-wrap.c (spread_components): Release todo vector. + + 2018-02-09 Jakub Jelinek + + PR sanitizer/84285 + * gcc.c (STATIC_LIBASAN_LIBS, STATIC_LIBTSAN_LIBS, + STATIC_LIBLSAN_LIBS, STATIC_LIBUBSAN_LIBS): Handle -static like + -static-lib*san. + + 2018-02-09 Marek Polacek + Jakub Jelinek + + PR c++/83659 + * fold-const.c (fold_indirect_ref_1): Use VECTOR_TYPE_P macro. + Formatting fixes. Verify first that tree_fits_shwi_p (op01). + Sync some changes from cxx_fold_indirect_ref. + + 2018-02-07 Jakub Jelinek + + * tree-eh.c (operation_could_trap_helper_p): Ignore honor_trapv for + *DIV_EXPR and *MOD_EXPR. + + 2018-02-01 Jakub Jelinek + + PR tree-optimization/81661 + PR tree-optimization/84117 + * tree-eh.h (rewrite_to_non_trapping_overflow): Declare. + * tree-eh.c: Include gimplify.h. + (find_trapping_overflow, replace_trapping_overflow, + rewrite_to_non_trapping_overflow): New functions. + * tree-vect-loop.c: Include tree-eh.h. + (vect_get_loop_niters): Use rewrite_to_non_trapping_overflow. + + 2018-01-30 Jakub Jelinek + + PR rtl-optimization/83986 + * sched-deps.c (sched_analyze_insn): For frame related insns, add anti + dependence against last_pending_memory_flush in addition to + pending_jump_insns. + + 2018-01-27 Jakub Jelinek + + PR middle-end/84040 + * sched-deps.c (sched_macro_fuse_insns): Return immediately if + !insn_set. + + 2018-01-24 Jakub Jelinek + + PR middle-end/83977 + * tree-inline.c (tree_function_versioning): Remove "omp declare simd" + attributes from DECL_ATTRIBUTES (new_decl) without affecting + DECL_ATTRIBUTES (old_decl). + + 2018-01-20 Jakub Jelinek + + PR middle-end/83945 + * tree-emutls.c: Include gimplify.h. + (lower_emutls_2): New function. + (lower_emutls_1): If ADDR_EXPR is a gimple invariant and walk_tree + with lower_emutls_2 callback finds some TLS decl in it, unshare_expr + it before further processing. + + PR target/83930 + * simplify-rtx.c (simplify_binary_operation_1) : Use + UINTVAL (trueop1) instead of INTVAL (op1). + + 2018-01-09 Jakub Jelinek + + PR preprocessor/83722 + * gcc.c (try_generate_repro): Pass + &temp_stderr_files[RETRY_ICE_ATTEMPTS - 1] rather than + &temp_stdout_files[RETRY_ICE_ATTEMPTS - 1] as last argument to + do_report_bug. + + 2018-01-05 Jakub Jelinek + + PR tree-optimization/83605 + * gimple-ssa-strength-reduction.c: Include tree-eh.h. + (find_candidates_dom_walker::before_dom_children): Ignore stmts that + can throw. + +2018-03-01 H.J. Lu + + Backport from mainline + 2018-02-26 H.J. Lu + + PR target/84039 + * config/i386/constraints.md (Bs): Replace + ix86_indirect_branch_register with + TARGET_INDIRECT_BRANCH_REGISTER. + (Bw): Likewise. + * config/i386/i386.md (indirect_jump): Likewise. + (tablejump): Likewise. + (*sibcall_memory): Likewise. + (*sibcall_value_memory): Likewise. + Peepholes of indirect call and jump via memory: Likewise. + (*sibcall_GOT_32): Disallowed for TARGET_INDIRECT_BRANCH_REGISTER. + (*sibcall_value_GOT_32): Likewise. + * config/i386/predicates.md (indirect_branch_operand): Likewise. + (GOT_memory_operand): Likewise. + (call_insn_operand): Likewise. + (sibcall_insn_operand): Likewise. + (GOT32_symbol_operand): Likewise. + * config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New. + +2018-03-01 H.J. Lu + + Backport from mainline + 2018-02-26 H.J. Lu + + * config/i386/i386.c (ix86_output_indirect_jmp): Update comments. + + 2018-02-26 H.J. Lu + + PR target/84530 + * config/i386/i386-protos.h (ix86_output_indirect_jmp): Remove + the bool argument. + (ix86_output_indirect_function_return): New prototype. + (ix86_split_simple_return_pop_internal): Likewise. + * config/i386/i386.c (indirect_return_via_cx): New. + (indirect_return_via_cx_bnd): Likewise. + (indirect_thunk_name): Handle return va CX_REG. + (output_indirect_thunk_function): Create alias for + __x86_return_thunk_[re]cx and __x86_return_thunk_[re]cx_bnd. + (ix86_output_indirect_jmp): Remove the bool argument. + (ix86_output_indirect_function_return): New function. + (ix86_split_simple_return_pop_internal): Likewise. + * config/i386/i386.md (*indirect_jump): Don't pass false + to ix86_output_indirect_jmp. + (*tablejump_1): Likewise. + (simple_return_pop_internal): Change it to define_insn_and_split. + Call ix86_split_simple_return_pop_internal to split it for + -mfunction-return=. + (simple_return_indirect_internal): Call + ix86_output_indirect_function_return instead of + ix86_output_indirect_jmp. + +2017-03-02 Thomas Schwinge + + Backport from trunk r256891: + 2018-01-19 Cesar Philippidis + + PR target/83790 + * config/nvptx/nvptx.c (output_init_frag): Don't use generic address + spaces for function labels. + +2018-02-26 Carl Love + + Backport from mainline: commit 257747 on 2018-02-16. + + * config/rs6000/altivec.h: Add builtin names vec_extract4b + vec_insert4b. + * config/rs6000/rs6000-builtin.def: Add INSERT4B and EXTRACT4B + definitions. + * config/rs6000/rs6000-c.c: Add the definitions for + P9V_BUILTIN_VEC_EXTRACT4B and P9V_BUILTIN_VEC_INSERT4B. + * config/rs6000/rs6000.c (altivec_expand_builtin): Add + P9V_BUILTIN_EXTRACT4B and P9V_BUILTIN_INSERT4B case statements. + * config/rs6000/vsx.md: Add define_insn extract4b. Add define_expand + definition for insert4b and define insn *insert3b_internal. + * doc/extend.texi: Add documentation for vec_extract4b. + +2018-02-26 Eric Botcazou + + PR rtl-optimization/83496 + * reorg.c (steal_delay_list_from_target): Change REDUNDANT array from + booleans to RTXes. Call fix_reg_dead_note on every non-null element. + (steal_delay_list_from_fallthrough): Call fix_reg_dead_note on a + redundant insn, if any. + (relax_delay_slots): Likewise. + (update_reg_unused_notes): Rename REDUNDANT_INSN to OTHER_INSN. + +2018-02-22 Sudakshina Das + Bin Cheng + + Backport from mainline: + 2017-12-14 Sudakshina Das + Bin Cheng + + PR target/81228 + * config/aarch64/aarch64.c (aarch64_select_cc_mode): Move LTGT to + CCFPEmode. + * config/aarch64/aarch64-simd.md (vec_cmp): Add + LTGT. + +2018-02-16 Jozef Lawrynowicz + + PR target/79242 + * machmode.def: Define a complex mode for PARTIAL_INT. + * genmodes.c (complex_class): Return MODE_COMPLEX_INT for + MODE_PARTIAL_INT. + * doc/rtl.texi: Document CSPImode. + * config/msp430/msp430.c (msp430_hard_regno_nregs): Add CPSImode + handling. + (msp430_hard_regno_nregs_with_padding): Likewise. + +2018-02-16 Sudakshina Das + + Backport from trunk + 2018-01-10 Sudakshina Das + + PR target/82096 + * expmed.c (emit_store_flag_force): Swap if const op0 + and change VOIDmode to mode of op0. + +2018-02-16 Richard Biener + + PR tree-optimization/84190 + * tree-ssa.c (non_rewritable_mem_ref_base): Do not touch + volatile accesses if the decl isn't volatile. + +2018-02-15 Michael Meissner + + Back port from trunk + 2018-02-07 Michael Meissner + + PR target/84154 + * config/rs6000/rs6000.md (fix_trunc2): + Convert from define_expand to be define_insn_and_split. Rework + float/double/_Float128 conversions to QI/HI/SImode to work with + both ISA 2.07 (power8) or ISA 3.0 (power9). Fix regression where + conversions to QI/HImode types did a store and then a load to + truncate the value. For conversions to VSX registers, don't split + the insn, instead emit the code directly. Use the code iterator + any_fix to combine signed and unsigned conversions. + (fix_truncsi2_p8): Likewise. + (fixuns_trunc2): Likewise. + (fix_trunc2): Likewise. + (fix_trunc2): Likewise. + (fix_di2_hw): Likewise. + (fixuns_di2_hw): Likewise. + (fix_si2_hw): Likewise. + (fixuns_si2_hw): Likewise. + (fix_2_hw): Likewise. + (fix_trunc2): Likewise. + (fctiwz__smallint): Rename fctiwz__smallint to + fix_truncsi2_p8. + (fix_trunc2_internal): Delete, no longer + used. + (fixuns_trunc2_internal): Likewise. + (fix__mem): Likewise. + (fctiwz__mem): Likewise. + (fix__mem): Likewise. + (fix_trunc2_mem): On ISA 3.0, prevent + the register allocator from doing a direct move to the GPRs to do + a store, and instead use the ISA 3.0 store byte/half-word from + vector register instruction. For IEEE 128-bit floating point, + also optimize stores of 32-bit ints. + (fix_trunc2_mem): Likewise. + +2018-02-15 Aaron Sawdey + + Back port from mainline + 2018-01-30 Aaron Sawdey + + PR target/83758 + * config/rs6000/rs6000.c (rs6000_internal_arg_pointer): Only return + a reg rtx. + +2018-02-14 Peter Bergner + + Back port from mainline + 2018-02-13 Peter Bergner + + PR target/84279 + * config/rs6000/rs6000.c (mem_operand_gpr): Disallow altivec addresses. + +2018-02-14 Martin Jambor + + PR c++/83990 + * ipa-prop.c (ipa_modify_call_arguments): Use location of call + statements, also set location of a load to a temporary. + +2018-02-10 John David Anglin + + * config/pa/pa.c (hppa_profile_hook): Mark SYMBOL_REF for _mcount as + function label. + + Backport from mainline + 2018-02-01 Aldy Hernandez + + PR target/84089 + * config/pa/predicates.md (base14_operand): Handle VOIDmode. + +2018-02-09 Martin Jambor + + Backport from mainline + 2018-02-08 Martin Jambor + + * hsa-gen.c (get_symbol_for_decl): Set program allocation for + static local variables. + +2018-02-09 Andreas Krebbel + + Backport from mainline + 2018-02-09 Andreas Krebbel + + PR target/PR84295 + * config/s390/s390.c (s390_set_current_function): Invoke + s390_indirect_branch_settings also if fndecl didn't change. + +2018-02-08 Iain Sandoe + + PR target/84113 + * config/rs6000/altivec.md (*restore_world): Remove LR use. + * config/rs6000/predicates.md (restore_world_operation): Adjust op + count, remove one USE. + +2018-02-08 Andreas Krebbel + + Backport from mainline + 2018-02-08 Andreas Krebbel + + * config/s390/s390-opts.h (enum indirect_branch): Define. + * config/s390/s390-protos.h (s390_return_addr_from_memory) + (s390_indirect_branch_via_thunk) + (s390_indirect_branch_via_inline_thunk): Add function prototypes. + (enum s390_indirect_branch_type): Define. + * config/s390/s390.c (struct s390_frame_layout, struct + machine_function): Remove. + (indirect_branch_prez10thunk_mask, indirect_branch_z10thunk_mask) + (indirect_branch_table_label_no, indirect_branch_table_name): + Define variables. + (INDIRECT_BRANCH_NUM_OPTIONS): Define macro. + (enum s390_indirect_branch_option): Define. + (s390_return_addr_from_memory): New function. + (s390_handle_string_attribute): New function. + (s390_attribute_table): Add new attribute handler. + (s390_execute_label): Handle UNSPEC_EXECUTE_JUMP patterns. + (s390_indirect_branch_via_thunk): New function. + (s390_indirect_branch_via_inline_thunk): New function. + (s390_function_ok_for_sibcall): When jumping via thunk disallow + sibling call optimization for non z10 compiles. + (s390_emit_call): Force indirect branch target to be a single + register. Add r1 clobber for non-z10 compiles. + (s390_emit_epilogue): Emit return jump via return_use expander. + (s390_reorg): Handle JUMP_INSNs as execute targets. + (s390_option_override_internal): Perform validity checks for the + new command line options. + (s390_indirect_branch_attrvalue): New function. + (s390_indirect_branch_settings): New function. + (s390_set_current_function): Invoke s390_indirect_branch_settings. + (s390_output_indirect_thunk_function): New function. + (s390_code_end): Implement target hook. + (s390_case_values_threshold): Implement target hook. + (TARGET_ASM_CODE_END, TARGET_CASE_VALUES_THRESHOLD): Define target + macros. + * config/s390/s390.h (struct s390_frame_layout) + (struct machine_function): Move here from s390.c. + (TARGET_INDIRECT_BRANCH_NOBP_RET) + (TARGET_INDIRECT_BRANCH_NOBP_JUMP) + (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK) + (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK) + (TARGET_INDIRECT_BRANCH_NOBP_CALL) + (TARGET_DEFAULT_INDIRECT_BRANCH_TABLE) + (TARGET_INDIRECT_BRANCH_THUNK_NAME_EXRL) + (TARGET_INDIRECT_BRANCH_THUNK_NAME_EX) + (TARGET_INDIRECT_BRANCH_TABLE): Define macros. + * config/s390/s390.md (UNSPEC_EXECUTE_JUMP) + (INDIRECT_BRANCH_THUNK_REGNUM): Define constants. + (mnemonic attribute): Add values which aren't recognized + automatically. + ("*cjump_long", "*icjump_long", "*basr", "*basr_r"): Disable + pattern for branch conversion. Fix mnemonic attribute. + ("*c", "*sibcall_br", "*sibcall_value_br", "*return"): Emit + indirect branch via thunk if requested. + ("indirect_jump", ""): Expand patterns for branch conversion. + ("*indirect_jump"): Disable for branch conversion using out of + line thunks. + ("indirect_jump_via_thunk_z10") + ("indirect_jump_via_thunk") + ("indirect_jump_via_inlinethunk_z10") + ("indirect_jump_via_inlinethunk", "*casesi_jump") + ("casesi_jump_via_thunk_z10", "casesi_jump_via_thunk") + ("casesi_jump_via_inlinethunk_z10") + ("casesi_jump_via_inlinethunk", "*basr_via_thunk_z10") + ("*basr_via_thunk", "*basr_r_via_thunk_z10") + ("*basr_r_via_thunk", "return_prez10"): New pattern. + ("*indirect2_jump"): Disable for branch conversion. + ("casesi_jump"): Turn into expander and expand patterns for branch + conversion. + ("return_use"): New expander. + ("*return"): Emit return via thunk and rename it to ... + ("*return"): ... this one. + * config/s390/s390.opt: Add new options and and enum for the + option values. + +2018-02-08 Richard Biener + + PR tree-optimization/84233 + * tree-ssa-phiprop.c (propagate_with_phi): Use separate + changed flag instead of boguously re-using phi_inserted. + +2018-02-07 Bill Schmidt + + Backport from mainline + 2018-02-06 Bill Schmidt + + * config/rs6000/rs6000.c (rs6000_option_override_internal): + Display warning message for -mno-speculate-indirect-jumps. + +2018-02-05 Rainer Orth + + Backport from mainline + 2018-01-30 Rainer Orth + + PR bootstrap/84017 + * configure.ac (gcc_cv_as_shf_merge): Disable on Solaris 10/x86. + * configure: Regenerate. + +2018-02-05 Peter Bergner + + Back port from mainline + 2018-02-01 Peter Bergner + + PR target/56010 + PR target/83743 + * config/rs6000/driver-rs6000.c: #include "diagnostic.h". + #include "opts.h". + (rs6000_supported_cpu_names): New static variable. + (linux_cpu_translation_table): Likewise. + (elf_platform) : Define new static variable and use it. + Translate kernel AT_PLATFORM name to canonical name if needed. + Error if platform name is unknown. + +2018-02-02 H.J. Lu + + Backport from mainline + 2018-02-02 H.J. Lu + + * config/i386/i386.c (ix86_output_function_return): Pass + INVALID_REGNUM, instead of -1, as invalid register number to + indirect_thunk_name and output_indirect_thunk. + +2018-02-01 Uros Bizjak + + Backport from mainline + 2018-01-31 Uros Bizjak + + PR rtl-optimization/84123 + * combine.c (change_zero_ext): Check if hard register satisfies + can_change_dest_mode before calling gen_lowpart_SUBREG. + +2018-02-01 Renlin Li + + Backport from mainline + 2018-02-01 Renlin Li + + PR target/83370 + * config/aarch64/aarch64.c (aarch64_class_max_nregs): Handle + TAILCALL_ADDR_REGS. + (aarch64_register_move_cost): Likewise. + * config/aarch64/aarch64.h (reg_class): Rename CALLER_SAVE_REGS to + TAILCALL_ADDR_REGS. + (REG_CLASS_NAMES): Likewise. + (REG_CLASS_CONTENTS): Rename CALLER_SAVE_REGS to + TAILCALL_ADDR_REGS. Remove IP registers. + * config/aarch64/aarch64.md (Ucs): Update register constraint. + +2018-02-01 Richard Biener + + Backport from mainline + 2017-11-02 Richard Biener + + PR tree-optimization/82795 + * tree-if-conv.c (predicate_mem_writes): Remove bogus assert. + +2018-01-31 Richard Biener + Kelvin Nilsen + + Backport from mainline + 2018-01-29 Richard Biener + Kelvin Nilsen + + PR bootstrap/80867 + * tree-vect-stmts.c (vectorizable_call): Don't call + targetm.vectorize_builtin_md_vectorized_function if callee is + NULL. + +2018-01-31 Eric Botcazou + + PR rtl-optimization/84071 + * doc/tm.texi.in (WORD_REGISTER_OPERATIONS): Add explicit case. + * doc/tm.texi: Regenerate. + +2018-01-31 Eric Botcazou + + PR rtl-optimization/84071 + * combine.c (record_dead_and_set_regs_1): Record the source unmodified + for a paradoxical SUBREG on a WORD_REGISTER_OPERATIONS target. + +2018-01-29 Joseph Myers + + Backport from mainline + 2018-01-24 Joseph Myers + + PR target/68467 + * config/m68k/m68k.c (m68k_promote_function_mode): New function. + (TARGET_PROMOTE_FUNCTION_MODE): New macro. + +2018-01-29 Uros Bizjak + + Backport from mainline + 2018-01-26 Uros Bizjak + + PR target/81763 + * config/i386/i386.md (*andndi3_doubleword): Add earlyclobber + to (=&r,r,rm) alternative. Add (=r,0,rm) and (=r,r,0) alternatives. + +2018-01-29 Alan Modra + + Backport from mainline + 2018-01-26 Alan Modra + PR target/84033 + * config/rs6000/rs6000.c (rtx_is_swappable_p): Exclude + UNSPEC_VBPERMQ. + +2018-01-27 H.J. Lu + + Backport from mainline + 2018-01-27 H.J. Lu + + * doc/invoke.texi: Replace -mfunction-return==@var{choice} with + -mfunction-return=@var{choice}. + +2018-01-27 H.J. Lu + + Backport from mainline + 2018-01-23 H.J. Lu + + PR target/83905 + * config/i386/i386.c (ix86_expand_prologue): Use cost reference + of struct ix86_frame. + (ix86_expand_epilogue): Likewise. Add a local variable for + the reg_save_offset field in struct ix86_frame. + +2018-01-26 Jakub Jelinek + + PR rtl-optimization/83985 + * dce.c (deletable_insn_p): Return false for separate shrink wrapping + REG_CFA_RESTORE insns. + (delete_unmarked_insns): Don't ignore separate shrink wrapping + REG_CFA_RESTORE insns here. + +2018-01-25 Uros Bizjak + + Backport from mainline + 2018-01-17 Uros Bizjak + + * config/i386/i386.c (indirect_thunk_name): Declare regno + as unsigned int. Compare regno with INVALID_REGNUM. + (output_indirect_thunk): Ditto. + (output_indirect_thunk_function): Ditto. + (ix86_code_end): Declare regno as unsigned int. Use INVALID_REGNUM + in the call to output_indirect_thunk_function. + +2018-01-25 Michael Meissner + + Back port from trunk + 2018-01-22 Michael Meissner + + PR target/83862 + * config/rs6000/rs6000-protos.h (rs6000_split_signbit): Delete, + no longer used. + * config/rs6000/rs6000.c (rs6000_split_signbit): Likewise. + * config/rs6000/rs6000.md (signbit2): Change code for IEEE + 128-bit to produce an UNSPEC move to get the double word with the + signbit and then a shift directly to do signbit. + (signbit2_dm): Replace old IEEE 128-bit signbit + implementation with a new version that just does either a direct + move or a regular move. Move memory interface to separate insns. + Move insns so they are next to the expander. + (signbit2_dm_mem_be): New combiner insns to combine load + with signbit move. Split big and little endian case. + (signbit2_dm_mem_le): Likewise. + (signbit2_dm_ext): Delete, no longer used. + (signbit2_dm2): Likewise. + +2018-01-25 Peter Bergner + + Back port from mainline + 2018-01-10 Peter Bergner + + PR target/83399 + * config/rs6000/rs6000.c (print_operand) <'y'>: Use + VECTOR_MEM_ALTIVEC_OR_VSX_P. + * config/rs6000/vsx.md (*vsx_le_perm_load_ for VSX_D): Use + indexed_or_indirect_operand predicate. + (*vsx_le_perm_load_ for VSX_W): Likewise. + (*vsx_le_perm_load_v8hi): Likewise. + (*vsx_le_perm_load_v16qi): Likewise. + (*vsx_le_perm_store_ for VSX_D): Likewise. + (*vsx_le_perm_store_ for VSX_W): Likewise. + (*vsx_le_perm_store_v8hi): Likewise. + (*vsx_le_perm_store_v16qi): Likewise. + (eight unnamed splitters): Likewise. + +2018-01-25 Bill Schmidt + + Backport from mainline + 2018-01-02 Bill Schmidt + + * config/rs6000/rs6000-p8swap.c (swap_feeds_both_load_and_store): + New function. + (rs6000_analyze_swaps): Mark a web unoptimizable if it contains a + swap associated with both a load and a store. + +2018-01-25 Richard Biener + + * BASE-VER: Increment to 7.3.1. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: gcc/testsuite/gcc.target/powerpc/p9-vinsert4b-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/p9-vinsert4b-1.c b/gcc/testsuite/gcc.target/powerpc/p9-vinsert4b-1.c deleted file mode 10644 --- a/gcc/testsuite/gcc.target/powerpc/p9-vinsert4b-1.c (revision 257042) +++ /dev/null (nonexistent) @@ -1,39 +0,0 @@ -/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ -/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ -/* { dg-require-effective-target powerpc_p9vector_ok } */ -/* { dg-options "-mcpu=power9 -O2" } */ - -#include - -vector signed char -vins_v4si (vector int *vi, vector signed char *vc) -{ - return vec_vinsert4b (*vi, *vc, 1); -} - -vector unsigned char -vins_di (long di, vector unsigned char *vc) -{ - return vec_vinsert4b (di, *vc, 2); -} - -vector char -vins_di2 (long *p_di, vector char *vc) -{ - return vec_vinsert4b (*p_di, *vc, 3); -} - -vector unsigned char -vins_di0 (vector unsigned char *vc) -{ - return vec_vinsert4b (0, *vc, 4); -} - -long -vext (vector signed char *vc) -{ - return vec_vextract4b (*vc, 5); -} - -/* { dg-final { scan-assembler "xxextractuw\|vextuw\[lr\]x" } } */ -/* { dg-final { scan-assembler "xxinsertw" } } */ Index: gcc/testsuite/gcc.target/powerpc/p9-vinsert4b-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/p9-vinsert4b-2.c b/gcc/testsuite/gcc.target/powerpc/p9-vinsert4b-2.c deleted file mode 10644 --- a/gcc/testsuite/gcc.target/powerpc/p9-vinsert4b-2.c (revision 257042) +++ /dev/null (nonexistent) @@ -1,30 +0,0 @@ -/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ -/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ -/* { dg-require-effective-target powerpc_p9vector_ok } */ -/* { dg-options "-mcpu=power9 -O2" } */ - -#include - -vector signed char -ins_v4si (vector int vi, vector signed char vc) -{ - return vec_vinsert4b (vi, vc, 13); /* { dg-error "vec_vinsert4b" } */ -} - -vector unsigned char -ins_di (long di, vector unsigned char vc, long n) -{ - return vec_vinsert4b (di, vc, n); /* { dg-error "vec_vinsert4b" } */ -} - -long -vext1 (vector signed char vc) -{ - return vec_vextract4b (vc, 13); /* { dg-error "vec_vextract4b" } */ -} - -long -vextn (vector unsigned char vc, long n) -{ - return vec_vextract4b (vc, n); /* { dg-error "vec_vextract4b" } */ -} Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-8.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-8.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-8.c deleted file mode 10644 --- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-8.c (revision 257042) +++ /dev/null (nonexistent) @@ -1,15 +0,0 @@ -/* { dg-do compile { target { ilp32 } } } */ -/* { dg-additional-options "-O2 -mno-speculate-indirect-jumps" } */ - -/* Test for deliberate misprediction of -m32 sibcalls. */ - -extern int (*f)(); - -int bar () -{ - return (*f) (); -} - -/* { dg-final { scan-assembler "crset 2" } } */ -/* { dg-final { scan-assembler "beqctr-" } } */ -/* { dg-final { scan-assembler {b \$} } } */ Index: gcc/testsuite/gcc.target/powerpc/ppc-sdata-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-sdata-2.c b/gcc/testsuite/gcc.target/powerpc/ppc-sdata-2.c --- a/gcc/testsuite/gcc.target/powerpc/ppc-sdata-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/ppc-sdata-2.c (revision 259627) @@ -5,6 +5,7 @@ /* { dg-final { scan-assembler-not "\\.section\[ \t\]\\.sdata2," } } */ /* { dg-final { scan-assembler "sdat@sdarel\\(13\\)" } } */ /* { dg-final { scan-assembler "sdat2@sdarel\\(13\\)" } } */ +/* { dg-skip-if "" { *-*-* } { "-mno-readonly-in-sdata" } { "" } } */ int sdat = 2; Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-2.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-2.c --- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-2.c (revision 259627) @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-mno-speculate-indirect-jumps" } */ +/* { dg-warning "'-mno-speculate-indirect-jumps' is deprecated" "" { target *-*-* } 0 } */ /* Test for deliberate misprediction of computed goto. */ Index: gcc/testsuite/gcc.target/powerpc/pr81572.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/pr81572.c b/gcc/testsuite/gcc.target/powerpc/pr81572.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/pr81572.c (revision 259627) @@ -0,0 +1,13 @@ +/* { dg-do compile { target powerpc64*-*-* } } */ +/* { dg-options "-O2 -mcpu=power7" } */ +/* { dg-final { scan-assembler-not "xxlor" } } */ + +#include + +typedef __vector unsigned char nvec_t; + +long testz_and(nvec_t a, nvec_t b) +{ + nvec_t c = vec_andc(a, b); + return vec_all_eq(a, c); +} Index: gcc/testsuite/gcc.target/powerpc/builtins-3-p8.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-3-p8.c b/gcc/testsuite/gcc.target/powerpc/builtins-3-p8.c --- a/gcc/testsuite/gcc.target/powerpc/builtins-3-p8.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/builtins-3-p8.c (revision 259627) @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-require-effective-target powerpc_p8vector_ok } */ /* { dg-options "-mcpu=power8" } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ #include Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c --- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c (revision 259627) @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-mno-speculate-indirect-jumps" } */ +/* { dg-warning "'-mno-speculate-indirect-jumps' is deprecated" "" { target *-*-* } 0 } */ /* Test for deliberate misprediction of jump tables. */ Index: gcc/testsuite/gcc.target/powerpc/pr79799-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/pr79799-2.c b/gcc/testsuite/gcc.target/powerpc/pr79799-2.c --- a/gcc/testsuite/gcc.target/powerpc/pr79799-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/pr79799-2.c (revision 259627) @@ -8,7 +8,7 @@ /* Optimize x = vec_insert (vec_extract (v2, N), v1, M) for SFmode if N is the default scalar position. */ -#if __ORDER_LITTLE_ENDIAN__ +#if __LITTLE_ENDIAN__ #define ELE 2 #else #define ELE 1 Index: gcc/testsuite/gcc.target/powerpc/fold-vec-mult-int128-p8.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-mult-int128-p8.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-mult-int128-p8.c --- a/gcc/testsuite/gcc.target/powerpc/fold-vec-mult-int128-p8.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-mult-int128-p8.c (revision 259627) @@ -4,7 +4,9 @@ /* { dg-do compile } */ /* { dg-require-effective-target powerpc_p8vector_ok } */ /* { dg-require-effective-target int128 } */ -/* { dg-options "-maltivec -mvsx -mpower8-vector" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mpower8-vector -mcpu=power8 -O2" } */ /* { dg-additional-options "-maix64" { target powerpc-ibm-aix* } } */ #include "altivec.h" @@ -21,5 +23,5 @@ return vec_mul (x, y); } -/* { dg-final { scan-assembler-times "\[ \t\]mulld " 6 } } */ -/* { dg-final { scan-assembler-times "\[ \t\]mulhdu" 2 } } */ +/* { dg-final { scan-assembler-times {\mmulld\M} 6 } } */ +/* { dg-final { scan-assembler-times {\mmulhdu\M} 2 } } */ Index: gcc/testsuite/gcc.target/powerpc/builtins-3-p9.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-3-p9.c b/gcc/testsuite/gcc.target/powerpc/builtins-3-p9.c --- a/gcc/testsuite/gcc.target/powerpc/builtins-3-p9.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/builtins-3-p9.c (revision 259627) @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-require-effective-target powerpc_p9vector_ok } */ /* { dg-options "-mcpu=power9" } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ #include Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-4.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-4.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-4.c --- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-4.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-4.c (revision 259627) @@ -1,5 +1,6 @@ /* { dg-do run } */ /* { dg-additional-options "-mno-speculate-indirect-jumps" } */ +/* { dg-warning "'-mno-speculate-indirect-jumps' is deprecated" "" { target *-*-* } 0 } */ /* Test for deliberate misprediction of indirect calls for ELFv2. */ Index: gcc/testsuite/gcc.target/powerpc/fold-vec-mult-int128-p9.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-mult-int128-p9.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-mult-int128-p9.c --- a/gcc/testsuite/gcc.target/powerpc/fold-vec-mult-int128-p9.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-mult-int128-p9.c (revision 259627) @@ -2,10 +2,10 @@ inputs produce the right results. */ /* { dg-do compile } */ -/* { dg-require-effective-target powerpc_float128_hw_ok } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ /* { dg-require-effective-target int128 } */ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ -/* { dg-options "-maltivec -mvsx -mcpu=power9 -O2" } */ +/* { dg-options "-mpower9-vector -mcpu=power9 -O2" } */ /* { dg-additional-options "-maix64" { target powerpc-ibm-aix* } } */ #include "altivec.h" @@ -22,4 +22,5 @@ return vec_mul (x, y); } -/* { dg-final { scan-assembler-times "\[ \t\]xsmulqp" 2 } } */ +/* { dg-final { scan-assembler-times {\mmulld\M} 4 } } */ +/* { dg-final { scan-assembler-times {\mmulhdu\M} 2 } } */ Index: gcc/testsuite/gcc.target/powerpc/pr83969.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/pr83969.c b/gcc/testsuite/gcc.target/powerpc/pr83969.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/pr83969.c (revision 259627) @@ -0,0 +1,14 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=G5" } } */ +/* { dg-options "-O1 -mcpu=G5 -fno-split-wide-types -ftree-loop-vectorize" } */ + +long long int +n7 (int po, long long int r4) +{ + while (po < 1) + { + r4 |= 1; + ++po; + } + return r4; +} Index: gcc/testsuite/gcc.target/powerpc/pr83660.C =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/pr83660.C b/gcc/testsuite/gcc.target/powerpc/pr83660.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/pr83660.C (revision 259627) @@ -0,0 +1,14 @@ +/* PR target/83660 */ +/* { dg-do compile } */ +/* { dg-options "-mcpu=power7" } */ + +#include + +typedef __vector unsigned int uvec32_t __attribute__((__aligned__(16))); + +unsigned get_word(uvec32_t v) +{ + return ({const unsigned _B1 = 32; + vec_extract((uvec32_t)v, 2);}); +} + Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-5.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-5.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-5.c --- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-5.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-5.c (revision 259627) @@ -1,5 +1,6 @@ /* { dg-do run } */ /* { dg-additional-options "-mno-speculate-indirect-jumps -Wno-pedantic" } */ +/* { dg-warning "'-mno-speculate-indirect-jumps' is deprecated" "" { target *-*-* } 0 } */ /* Test for deliberate misprediction of computed goto. */ Index: gcc/testsuite/gcc.target/powerpc/pr84878.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/pr84878.c b/gcc/testsuite/gcc.target/powerpc/pr84878.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/pr84878.c (revision 259627) @@ -0,0 +1,18 @@ +/* PR rtl-optimization/84878 */ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-O2 -maltivec -mno-vsx -fmodulo-sched -ftree-vectorize -funroll-loops -fassociative-math -fno-signed-zeros -fno-trapping-math" } */ + +int ek; +float zu; + +int +k5 (int ks) +{ + while (ek < 1) + { + ks += (int)(0x1000000 + zu + !ek); + ++ek; + } + return ks; +} Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-6.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-6.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-6.c --- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-6.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-6.c (revision 259627) @@ -1,5 +1,6 @@ /* { dg-do run } */ /* { dg-additional-options "-mno-speculate-indirect-jumps" } */ +/* { dg-warning "'-mno-speculate-indirect-jumps' is deprecated" "" { target *-*-* } 0 } */ /* Test for deliberate misprediction of jump tables. */ Index: gcc/testsuite/gcc.target/powerpc/builtins-3.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-3.c b/gcc/testsuite/gcc.target/powerpc/builtins-3.c --- a/gcc/testsuite/gcc.target/powerpc/builtins-3.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/builtins-3.c (revision 259627) @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-require-effective-target powerpc_vsx_ok } */ -/* { dg-options "-maltivec -mvsx" } */ +/* { dg-options "-O2 -mvsx -mcpu=power6" } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power6" } } */ #include Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c --- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c (revision 259627) @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-additional-options "-mno-speculate-indirect-jumps" } */ +/* { dg-warning "'-mno-speculate-indirect-jumps' is deprecated" "" { target *-*-* } 0 } */ /* Test for deliberate misprediction of indirect calls. */ Index: gcc/testsuite/gcc.target/powerpc/swaps-p8-46.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-46.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-46.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-46.c (revision 259627) @@ -0,0 +1,34 @@ +/* { dg-do run { target { powerpc64le-*-* } } } */ +/* { dg-require-effective-target powerpc_p8vector_ok } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O2 " } */ + +typedef __attribute__ ((__aligned__ (8))) unsigned long long __m64; +typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__)); + +/* PR84033. Extracted from xmmintrin.h but with a pointer param to + allow swaps to happen when not inline. */ +int __attribute__ ((__noinline__)) +_mm_movemask_ps (__m128 *__A) +{ + __vector __m64 result; + static const __vector unsigned int perm_mask = + { + 0x00204060, 0x80808080, 0x80808080, 0x80808080 + }; + + result = (__vector __m64) + __builtin_vec_vbpermq ((__vector unsigned char) (*__A), + (__vector unsigned char) perm_mask); + return result[1]; +} + +int +main (void) +{ + union { unsigned int i[4]; __m128 m; } x + = { 0x80000000, 0x80000000, 0x7fffffff, 0x7fffffff }; + if (_mm_movemask_ps (&x.m) != 3) + __builtin_abort (); + return 0; +} Index: gcc/testsuite/gcc.target/powerpc/extend-divide-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/extend-divide-1.c b/gcc/testsuite/gcc.target/powerpc/extend-divide-1.c --- a/gcc/testsuite/gcc.target/powerpc/extend-divide-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/extend-divide-1.c (revision 259627) @@ -5,9 +5,7 @@ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */ /* { dg-options "-mcpu=power7 -O2" } */ /* { dg-final { scan-assembler-times "divwe " 1 } } */ -/* { dg-final { scan-assembler-times "divweo " 1 } } */ /* { dg-final { scan-assembler-times "divweu " 1 } } */ -/* { dg-final { scan-assembler-times "divweuo " 1 } } */ /* { dg-final { scan-assembler-not "bl __builtin" } } */ int @@ -16,20 +14,8 @@ return __builtin_divwe (a, b); } -int -div_weo (int a, int b) -{ - return __builtin_divweo (a, b); -} - unsigned int div_weu (unsigned int a, unsigned int b) { return __builtin_divweu (a, b); } - -unsigned int -div_weuo (unsigned int a, unsigned int b) -{ - return __builtin_divweuo (a, b); -} Index: gcc/testsuite/gcc.target/powerpc/extend-divide-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/extend-divide-2.c b/gcc/testsuite/gcc.target/powerpc/extend-divide-2.c --- a/gcc/testsuite/gcc.target/powerpc/extend-divide-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/extend-divide-2.c (revision 259627) @@ -5,9 +5,7 @@ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */ /* { dg-options "-mcpu=power7 -O2" } */ /* { dg-final { scan-assembler-times "divde " 1 } } */ -/* { dg-final { scan-assembler-times "divdeo " 1 } } */ /* { dg-final { scan-assembler-times "divdeu " 1 } } */ -/* { dg-final { scan-assembler-times "divdeuo " 1 } } */ /* { dg-final { scan-assembler-not "bl __builtin" } } */ long @@ -16,20 +14,8 @@ return __builtin_divde (a, b); } -long -div_deo (long a, long b) -{ - return __builtin_divdeo (a, b); -} - unsigned long div_deu (unsigned long a, unsigned long b) { return __builtin_divdeu (a, b); } - -unsigned long -div_deuo (unsigned long a, unsigned long b) -{ - return __builtin_divdeuo (a, b); -} Index: gcc/testsuite/gcc.target/powerpc/pr83862.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/pr83862.c b/gcc/testsuite/gcc.target/powerpc/pr83862.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/pr83862.c (revision 259627) @@ -0,0 +1,34 @@ +/* PR target/83862.c */ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-require-effective-target ppc_float128_sw } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mpower9-vector -O2 -mfloat128" } */ + +/* On little endian systems, optimizing signbit of IEEE 128-bit values from + memory could abort if the memory address was indexed (reg+reg). The + optimization is only on 64-bit machines with direct move. + + Compile with -g -O2 -mabi=ieeelongdouble -Wno-psabi. */ + +#ifndef TYPE +#define TYPE __float128 +#endif + +int sbr (TYPE a) { return __builtin_signbit (a); } +int sbm (TYPE *a) { return __builtin_signbit (*a); } +int sbo (TYPE *a) { return __builtin_signbit (a[4]); } +int sbi (TYPE *a, unsigned long n) { return __builtin_signbit (a[n]); } +void sbs (int *p, TYPE a) { *p = __builtin_signbit (a); } + +/* On big endian systems, this will generate 2 LDs and 1 LDX, while on + little endian systems, this will generate 3 LDs and an ADD. */ + +/* { dg-final { scan-assembler-times {\mldx?\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mmfvsrd\M} 2 } } */ +/* { dg-final { scan-assembler-times {\msrdi\M} 5 } } */ +/* { dg-final { scan-assembler-not {\mmfvsrld\M} } } */ +/* { dg-final { scan-assembler-not {\mstxvx?\M} } } */ +/* { dg-final { scan-assembler-not {\mstxvw4x\M} } } */ +/* { dg-final { scan-assembler-not {\mstxvd2x\M} } } */ +/* { dg-final { scan-assembler-not {\mstvx\M} } } */ + Index: gcc/testsuite/gcc.target/powerpc/builtins-7-p9-runnable.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-7-p9-runnable.c b/gcc/testsuite/gcc.target/powerpc/builtins-7-p9-runnable.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/builtins-7-p9-runnable.c (revision 259627) @@ -0,0 +1,169 @@ +/* { dg-do run { target { powerpc*-*-* && p9vector_hw } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mcpu=power9 -O2" } */ + +#include +#define TRUE 1 +#define FALSE 0 + +#ifdef DEBUG +#include +#endif + +#define EXTRACT 0 + +void abort (void); + +int result_wrong_ull (vector unsigned long long vec_expected, + vector unsigned long long vec_actual) +{ + int i; + + for (i = 0; i < 2; i++) + if (vec_expected[i] != vec_actual[i]) + return TRUE; + + return FALSE; +} + +int result_wrong_uc (vector unsigned char vec_expected, + vector unsigned char vec_actual) +{ + int i; + + for (i = 0; i < 16; i++) + if (vec_expected[i] != vec_actual[i]) + return TRUE; + + return FALSE; +} + +#ifdef DEBUG +void print_ull (vector unsigned long long vec_expected, + vector unsigned long long vec_actual) +{ + int i; + + printf("expected unsigned long long data\n"); + for (i = 0; i < 2; i++) + printf(" %lld,", vec_expected[i]); + + printf("\nactual signed char data\n"); + for (i = 0; i < 2; i++) + printf(" %lld,", vec_actual[i]); + printf("\n"); +} + +void print_uc (vector unsigned char vec_expected, + vector unsigned char vec_actual) +{ + int i; + + printf("expected unsigned char data\n"); + for (i = 0; i < 16; i++) + printf(" %d,", vec_expected[i]); + + printf("\nactual unsigned char data\n"); + for (i = 0; i < 16; i++) + printf(" %d,", vec_actual[i]); + printf("\n"); +} +#endif + +#if EXTRACT +vector unsigned long long +vext (vector unsigned char *vc) +{ + return vextract_si_vchar (*vc, 5); +} +#endif + +int main() +{ + vector signed int vsi_arg; + vector unsigned char vec_uc_arg, vec_uc_result, vec_uc_expected; + vector unsigned long long vec_ull_result, vec_ull_expected; + unsigned long long ull_result, ull_expected; + + vec_uc_arg = (vector unsigned char){1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16}; + + vsi_arg = (vector signed int){0xA, 0xB, 0xC, 0xD}; + + vec_uc_expected = (vector unsigned char){0xC, 0, 0, 0, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16}; + /* Test vec_insert4b() */ + /* Insert into char 0 location */ + vec_uc_result = vec_insert4b (vsi_arg, vec_uc_arg, 0); + + if (result_wrong_uc(vec_uc_expected, vec_uc_result)) + { +#ifdef DEBUG + printf("Error: vec_insert4b pos 0, result does not match expected result\n"); + print_uc (vec_uc_expected, vec_uc_result); +#else + abort(); +#endif + } + + /* insert into char 4 location */ + vec_uc_expected = (vector unsigned char){1, 2, 3, 4, + 0xC, 0, 0, 0, + 9, 10, 11, 12, + 13, 14, 15, 16}; + vec_uc_result = vec_insert4b (vsi_arg, vec_uc_arg, 4); + + if (result_wrong_uc(vec_uc_expected, vec_uc_result)) + { +#ifdef DEBUG + printf("Error: vec_insert4b pos 4, result does not match expected result\n"); + print_uc (vec_uc_expected, vec_uc_result); +#else + abort(); +#endif + } + + /* Test vec_extract4b() */ + /* Extract 4b, from char 0 location */ + vec_uc_arg = (vector unsigned char){10, 0, 0, 0, + 20, 0, 0, 0, + 30, 0, 0, 0, + 40, 0, 0, 0}; + + vec_ull_expected = (vector unsigned long long){0, 10}; + vec_ull_result = vec_extract4b(vec_uc_arg, 0); + + if (result_wrong_ull(vec_ull_expected, vec_ull_result)) + { +#ifdef DEBUG + printf("Error: vec_extract4b pos 0, result does not match expected result\n"); + print_ull (vec_ull_expected, vec_ull_result); +#else + abort(); +#endif + } + + /* Extract 4b, from char 12 location */ + vec_uc_arg = (vector unsigned char){10, 0, 0, 0, + 20, 0, 0, 0, + 30, 0, 0, 0, + 40, 0, 0, 0}; + + vec_ull_expected = (vector unsigned long long){0, 40}; + vec_ull_result = vec_extract4b(vec_uc_arg, 12); + + if (result_wrong_ull(vec_ull_expected, vec_ull_result)) + { +#ifdef DEBUG + printf("Error: vec_extract4b pos 12, result does not match expected result\n"); + print_ull (vec_ull_expected, vec_ull_result); +#else + abort(); +#endif + } +} Index: gcc/testsuite/gcc.target/powerpc/pr83399.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/pr83399.c b/gcc/testsuite/gcc.target/powerpc/pr83399.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/pr83399.c (revision 259627) @@ -0,0 +1,15 @@ +/* PR target/83399 */ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O1 -mabi=elfv2 -mlittle -mvsx" } */ + +typedef __attribute__((altivec(vector__))) int v4si_t; +int +foo (void) +{ + v4si_t a, u, v, y; + u = __builtin_altivec_lvx (32, ((void *) &a) - 32); + v = __builtin_altivec_lvx (64, ((void *) &a) - 32); + y = u + v; + return y[0]; +} Index: gcc/testsuite/gcc.target/powerpc/lvsl-lvsr.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/lvsl-lvsr.c b/gcc/testsuite/gcc.target/powerpc/lvsl-lvsr.c --- a/gcc/testsuite/gcc.target/powerpc/lvsl-lvsr.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/lvsl-lvsr.c (revision 259627) @@ -6,7 +6,7 @@ /* { dg-options "-O0 -Wno-deprecated" } */ /* { dg-final { scan-assembler-times "lvsl" 2 } } */ /* { dg-final { scan-assembler-times "lvsr" 2 } } */ -/* { dg-final { scan-assembler-times "lxvd2x" 2 } } */ +/* { dg-final { scan-assembler-times {\mlxvd2x\M|\mlxv\M} 2 } } */ /* { dg-final { scan-assembler-times "vperm" 2 } } */ Index: gcc/testsuite/gcc.target/powerpc/pr84154-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/pr84154-1.c b/gcc/testsuite/gcc.target/powerpc/pr84154-1.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/pr84154-1.c (revision 259627) @@ -0,0 +1,55 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } } */ +/* { dg-require-effective-target powerpc_p8vector_ok } */ +/* { dg-options "-mpower8-vector -O2" } */ + +/* PR target/84154. Make sure conversion to char/short does not generate a + store and a load on ISA 2.07 and newer systems. */ + +unsigned char +double_to_uc (double x) +{ + return x; +} + +signed char +double_to_sc (double x) +{ + return x; +} + +unsigned short +double_to_us (double x) +{ + return x; +} + +short +double_to_ss (double x) +{ + return x; +} + +unsigned int +double_to_ui (double x) +{ + return x; +} + +int +double_to_si (double x) +{ + return x; +} + +/* { dg-final { scan-assembler-times {\mextsb\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mextsh\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mfctiwuz\M|\mxscvdpuxws\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mfctiwz\M|\mxscvdpsxws\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mmfvsrwz\M} 6 } } */ +/* { dg-final { scan-assembler-times {\mrlwinm\M} 2 } } */ +/* { dg-final { scan-assembler-not {\mlbz\M} } } */ +/* { dg-final { scan-assembler-not {\mlhz\M} } } */ +/* { dg-final { scan-assembler-not {\mlha\M} } } */ +/* { dg-final { scan-assembler-not {\mmfvsrd\M} } } */ +/* { dg-final { scan-assembler-not {\mstw\M} } } */ Index: gcc/testsuite/gcc.target/powerpc/crypto-builtin-1-runnable.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/crypto-builtin-1-runnable.c b/gcc/testsuite/gcc.target/powerpc/crypto-builtin-1-runnable.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/crypto-builtin-1-runnable.c (revision 259627) @@ -0,0 +1,109 @@ +/* { dg-do run { target { powerpc*-*-* && p8vector_hw } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O2 " } */ + +/* Make sure the test case compiled with -O2 generates the same expected + results. The expected results were generated with -O0. */ + +#include +#define TRUE 1 +#define FALSE 0 + +#define DEBUG 1 + +#ifdef DEBUG +#include +#endif + +void abort (void); + +typedef vector unsigned long long crypto_t; +typedef vector unsigned long long v2di_t; +typedef vector unsigned int v4si_t; +typedef vector unsigned short v8hi_t; +typedef vector unsigned char v16qi_t; + +v16qi_t crypto6a (v16qi_t a, v16qi_t b, v16qi_t c) +{ + return __builtin_crypto_vpermxor (a, b, c); +} + +v8hi_t crypto6b (v8hi_t a, v8hi_t b, v8hi_t c) +{ + return __builtin_crypto_vpermxor (a, b, c); +} + +v4si_t crypto6c (v4si_t a, v4si_t b, v4si_t c) +{ + return __builtin_crypto_vpermxor (a, b, c); +} + +v2di_t crypto6d (v2di_t a, v2di_t b, v2di_t c) +{ + return __builtin_crypto_vpermxor (a, b, c); +} + +int main() +{ + int i; + v16qi_t expected_v16qi, result_v16qi; + v8hi_t expected_v8hi, result_v8hi; + v4si_t expected_v4si, result_v4si; + v2di_t expected_v2di, result_v2di; + v16qi_t v16qi_arg_a, v16qi_arg_b, v16qi_arg_c; + v8hi_t v8hi_arg_a, v8hi_arg_b, v8hi_arg_c; + v4si_t v4si_arg_a, v4si_arg_b, v4si_arg_c; + v2di_t v2di_arg_a, v2di_arg_b, v2di_arg_c; + + v16qi_arg_a = (vector unsigned char){ 7, 6, 5, 4, 3, 2, 1, 0, + 1, 2, 3, 4, 5, 6, 7, 8 }; + v16qi_arg_b = (vector unsigned char){ 1, 2, 3, 4, 5, 6, 7, 8, + 7, 6, 5, 4, 3, 2, 1, 0 }; + v16qi_arg_c = (vector unsigned char){ 7, 2, 5, 4, 3, 6, 1, 8, + 1, 6, 3, 4, 5, 2, 7, 0 }; + expected_v16qi = (vector unsigned char){ 15, 10, 13, 12, 11, 14, 9, 0, + 9, 14, 11, 12, 13, 10, 15, 8 }; + + result_v16qi = crypto6a (v16qi_arg_a, v16qi_arg_b, v16qi_arg_c); + + for (i = 0; i < 16; i++) + if (expected_v16qi[i] != result_v16qi[i]) + printf("crypto6a: result_v16qi[%d] = %d, expected = %d\n", + i, result_v16qi[i], expected_v16qi[i]); + + v8hi_arg_a = (vector unsigned short int){ 7, 6, 5, 4, 3, 2, 1, 0}; + v8hi_arg_b = (vector unsigned short int){ 1, 2, 3, 4, 5, 6, 7, 8}; + v8hi_arg_c = (vector unsigned short int){ 7, 2, 5, 4, 3, 6, 1, 8}; + expected_v8hi = (vector unsigned short int){ 5, 0, 6, 0, 7, 0, 8}; + + result_v8hi = crypto6b (v8hi_arg_a, v8hi_arg_b, v8hi_arg_c); + + for (i = 0; i < 8; i++) + if (expected_v8hi[i] != result_v8hi[i]) + printf("crypto6a: result_v8hi[%d] = %d, expected = %d\n", + i, result_v8hi[i], expected_v8hi[i]); + + v4si_arg_a = (vector unsigned int){ 7, 6, 5, 4}; + v4si_arg_b = (vector unsigned int){ 15, 6, 7, 8}; + v4si_arg_c = (vector unsigned int){ 7, 14, 3, 6}; + expected_v4si = (vector unsigned int){ 7, 0, 8, 0}; + + result_v4si = crypto6c (v4si_arg_a, v4si_arg_b, v4si_arg_c); + + for (i = 0; i < 4; i++) + if (expected_v4si[i] != result_v4si[i]) + printf("crypto6a: result_v4si[%d] = %d, expected = %d\n", + i, result_v4si[i], expected_v4si[i]); + + v2di_arg_a = (vector unsigned long long int){ 7, 6, }; + v2di_arg_b = (vector unsigned long long int){ 15, 6, }; + v2di_arg_c = (vector unsigned long long int){ 7, 14}; + expected_v2di = (vector unsigned long long int){ 6, 0}; + + result_v2di = crypto6d (v2di_arg_a, v2di_arg_b, v2di_arg_c); + + for (i = 0; i < 2; i++) + if (expected_v2di[i] != result_v2di[i]) + printf("crypto6a: result_v2di[%d] = %d, expected = %d\n", + i, result_v2di[i], expected_v2di[i]); +} Index: gcc/testsuite/gcc.target/powerpc/pr84154-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/pr84154-2.c b/gcc/testsuite/gcc.target/powerpc/pr84154-2.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/pr84154-2.c (revision 259627) @@ -0,0 +1,58 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } } */ +/* { dg-require-effective-target powerpc_p8vector_ok } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O2" } */ + +/* PR target/84154. Make sure on ISA 2.07 (power8) that we store the result of + a conversion to char/short using an offsettable address does not generate + direct moves for storing 32-bit integers, but does do a direct move for + 8/16-bit integers. */ + +void +double_to_uc (double x, unsigned char *p) +{ + p[3] = x; +} + +void +double_to_sc (double x, signed char *p) +{ + p[3] = x; +} + +void +double_to_us (double x, unsigned short *p) +{ + p[3] = x; +} + +void +double_to_ss (double x, short *p) +{ + p[3] = x; +} + +void +double_to_ui (double x, unsigned int *p) +{ + p[3] = x; +} + +void +double_to_si (double x, int *p) +{ + p[3] = x; +} + +/* { dg-final { scan-assembler-times {\mfctiwuz\M|\mxscvdpuxws\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mfctiwz\M|\mxscvdpsxws\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mmfvsrwz\M} 4 } } */ +/* { dg-final { scan-assembler-times {\mstfiwx\M|\mstxsiwx\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mstb\M} 2 } } */ +/* { dg-final { scan-assembler-times {\msth\M} 2 } } */ +/* { dg-final { scan-assembler-not {\mlbz\M} } } */ +/* { dg-final { scan-assembler-not {\mlhz\M} } } */ +/* { dg-final { scan-assembler-not {\mlha\M} } } */ +/* { dg-final { scan-assembler-not {\mmfvsrd\M} } } */ +/* { dg-final { scan-assembler-not {\mstw\M} } } */ Index: gcc/testsuite/gcc.target/powerpc/vsxcopy.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/vsxcopy.c b/gcc/testsuite/gcc.target/powerpc/vsxcopy.c --- a/gcc/testsuite/gcc.target/powerpc/vsxcopy.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/vsxcopy.c (revision 259627) @@ -1,8 +1,8 @@ /* { dg-do compile { target { powerpc64*-*-* } } } */ /* { dg-require-effective-target powerpc_vsx_ok } */ /* { dg-options "-O1 -mvsx" } */ -/* { dg-final { scan-assembler "lxvd2x" } } */ -/* { dg-final { scan-assembler "stxvd2x" } } */ +/* { dg-final { scan-assembler {\mlxvd2x\M|\mlxv\M} } } */ +/* { dg-final { scan-assembler {\mstxvd2x\M|\mstxv\M} } } */ /* { dg-final { scan-assembler-not "xxpermdi" } } */ typedef float vecf __attribute__ ((vector_size (16))); Index: gcc/testsuite/gcc.target/powerpc/pr84154-3.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/pr84154-3.c b/gcc/testsuite/gcc.target/powerpc/pr84154-3.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/powerpc/pr84154-3.c (revision 259627) @@ -0,0 +1,60 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-options "-mcpu=power9 -O2" } */ + +/* PR target/84154. Make sure on ISA 3.0 we store the result of a conversion + to char/short using an offsettable address does not generate direct moves + for storing 8/16/32-bit integers. */ + +void +double_to_uc (double x, unsigned char *p) +{ + p[3] = x; +} + +void +double_to_sc (double x, signed char *p) +{ + p[3] = x; +} + +void +double_to_us (double x, unsigned short *p) +{ + p[3] = x; +} + +void +double_to_ss (double x, short *p) +{ + p[3] = x; +} + +void +double_to_ui (double x, unsigned int *p) +{ + p[3] = x; +} + +void +double_to_si (double x, int *p) +{ + p[3] = x; +} + +/* { dg-final { scan-assembler-times {\maddi\M} 6 } } */ +/* { dg-final { scan-assembler-times {\mfctiwuz\M|\mxscvdpuxws\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mfctiwz\M|\mxscvdpsxws\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mstfiwx\M|\mstxsiwx\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mstxsibx\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mstxsihx\M} 2 } } */ +/* { dg-final { scan-assembler-not {\mlbz\M} } } */ +/* { dg-final { scan-assembler-not {\mlhz\M} } } */ +/* { dg-final { scan-assembler-not {\mlha\M} } } */ +/* { dg-final { scan-assembler-not {\mmfvsrwz\M} } } */ +/* { dg-final { scan-assembler-not {\mmfvsrd\M} } } */ +/* { dg-final { scan-assembler-not {\mstw\M} } } */ +/* { dg-final { scan-assembler-not {\mstb\M} } } */ +/* { dg-final { scan-assembler-not {\msth\M} } } */ Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c --- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c (revision 259627) @@ -1,5 +1,6 @@ -/* { dg-do compile { target { lp64 } } } */ +/* { dg-do compile } */ /* { dg-additional-options "-mno-speculate-indirect-jumps" } */ +/* { dg-warning "'-mno-speculate-indirect-jumps' is deprecated" "" { target *-*-* } 0 } */ /* Test for deliberate misprediction of indirect calls. */ @@ -11,4 +12,10 @@ } /* { dg-final { scan-assembler "crset 2" } } */ -/* { dg-final { scan-assembler "beqctrl-" } } */ + +/* The AIX and ELFv2 ABIs don't allow a sibcall here. */ +/* { dg-final { scan-assembler "beqctrl-" { target { lp64 || { powerpc*-*-aix* } } } } } */ + +/* The other ABIs do allow a sibcall. */ +/* { dg-final { scan-assembler "beqctr-" { target { ilp32 && !powerpc*-*-aix* } } } } */ +/* { dg-final { scan-assembler {b \$} { target { ilp32 && !powerpc*-*-aix* } } } } */ Index: gcc/testsuite/gcc.target/nvptx/pr85056a.c =================================================================== diff --git a/gcc/testsuite/gcc.target/nvptx/pr85056a.c b/gcc/testsuite/gcc.target/nvptx/pr85056a.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/nvptx/pr85056a.c (revision 259627) @@ -0,0 +1,3 @@ +/* { dg-skip-if "" { *-*-* } } */ + +int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; Index: gcc/testsuite/gcc.target/nvptx/pr85056.c =================================================================== diff --git a/gcc/testsuite/gcc.target/nvptx/pr85056.c b/gcc/testsuite/gcc.target/nvptx/pr85056.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/nvptx/pr85056.c (revision 259627) @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-additional-sources "pr85056a.c" } */ + +extern void abort (); + +extern int a[]; + +int +main () +{ + int i, sum; + + sum = 0; + for (i = 0; i < 10; i++) + sum += a[i]; + + if (sum != 55) + abort (); + + return 0; +} Index: gcc/testsuite/gcc.target/nvptx/indirect_call.c =================================================================== diff --git a/gcc/testsuite/gcc.target/nvptx/indirect_call.c b/gcc/testsuite/gcc.target/nvptx/indirect_call.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/nvptx/indirect_call.c (revision 259627) @@ -0,0 +1,19 @@ +/* { dg-options "-O2 -msoft-stack" } */ +/* { dg-do run } */ + +int +f1 (int a) +{ + return a + 1; +} + +int (*f2)(int) = f1; + +int +main () +{ + if (f2 (100) != 101) + __builtin_abort(); + + return 0; +} Index: gcc/testsuite/gcc.target/arm/pr82518.c =================================================================== diff --git a/gcc/testsuite/gcc.target/arm/pr82518.c b/gcc/testsuite/gcc.target/arm/pr82518.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/arm/pr82518.c (revision 259627) @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-require-effective-target arm_neon_hw } */ +/* { dg-additional-options "-O3 -fno-inline -std=gnu99" } */ +/* { dg-add-options arm_neon } */ + +typedef struct { int x, y; } X; + +void f4(X *p, int n) +{ + for (int i = 0; i < n; i++) + { p[i].x = i; + p[i].y = i + 1; + } +} + +__attribute ((aligned (16))) X arr[100]; + +int main(void) +{ + volatile int fail = 0; + f4 (arr, 100); + for (int i = 0; i < 100; i++) + if (arr[i].y != i+1 || arr[i].x != i) + fail = 1; + if (fail) + __builtin_abort (); + + return 0; +} Index: gcc/testsuite/gcc.target/arm/cmse/cmse-16.c =================================================================== diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-16.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-16.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-16.c (revision 259627) @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-options "-Os -mcmse" } */ + +#include + +int +foo (void) +{ + return cmse_nonsecure_caller (); +} + +int +main (void) +{ + /* Return success (0) if main is secure, ie if cmse_nonsecure_caller/foo + returns false (0). */ + return foo (); +} Index: gcc/testsuite/gcc.target/arm/cmse/cmse-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c --- a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c (revision 259627) @@ -71,7 +71,21 @@ { return cmse_nonsecure_caller (); } +/* { dg-final { scan-assembler "baz:" } } */ +/* { dg-final { scan-assembler "__acle_se_baz:" } } */ +/* { dg-final { scan-assembler-not "\tcmse_nonsecure_caller" } } */ +/* Look for an andsi of 1 with a register in function baz, ie. +;; Function baz + +(insn (set (reg:SI ) + (and:SI (reg:SI ) + (const_int 1 ) + > +(insn +*/ +/* { dg-final { scan-rtl-dump "\n;; Function baz\[^\n\]*\[^(\]+\[^;\]*\n\\(insn \[^(\]+ \\(set \\(reg\[^:\]*:SI \[^)\]+\\)\[^(\]*\\(and:SI \\(reg\[^:\]*:SI \[^)\]+\\)\[^(\]*\\((const_int 1|reg\[^:\]*:SI) \[^)\]+\\)\[^(\]+(\\(nil\\)\[^(\]+)?\\(insn" expand } } */ + typedef int __attribute__ ((cmse_nonsecure_call)) (int_nsfunc_t) (void); int default_callback (void) @@ -86,6 +100,11 @@ { fp = cmse_nsfptr_create (callback); } +/* { dg-final { scan-assembler "qux:" } } */ +/* { dg-final { scan-assembler "__acle_se_qux:" } } */ +/* { dg-final { scan-assembler "bic" } } */ +/* { dg-final { scan-assembler "push\t\{r4, r5, r6" } } */ +/* { dg-final { scan-assembler "msr\tAPSR_nzcvq" } } */ int call_callback (void) { @@ -94,13 +113,4 @@ else return default_callback (); } -/* { dg-final { scan-assembler "baz:" } } */ -/* { dg-final { scan-assembler "__acle_se_baz:" } } */ -/* { dg-final { scan-assembler "qux:" } } */ -/* { dg-final { scan-assembler "__acle_se_qux:" } } */ -/* { dg-final { scan-assembler-not "\tcmse_nonsecure_caller" } } */ -/* { dg-final { scan-rtl-dump "and.*reg.*const_int 1" expand } } */ -/* { dg-final { scan-assembler "bic" } } */ -/* { dg-final { scan-assembler "push\t\{r4, r5, r6" } } */ -/* { dg-final { scan-assembler "msr\tAPSR_nzcvq" } } */ /* { dg-final { scan-assembler-times "bl\\s+__gnu_cmse_nonsecure_call" 1 } } */ Index: gcc/testsuite/gcc.target/arm/pr82989.c =================================================================== diff --git a/gcc/testsuite/gcc.target/arm/pr82989.c b/gcc/testsuite/gcc.target/arm/pr82989.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/arm/pr82989.c (revision 259627) @@ -0,0 +1,33 @@ +/* PR target/82989. */ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-a8" } } */ +/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mfpu=*" } { "-mfpu=neon" } } */ +/* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */ +/* { dg-options "-O2 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=hard" } */ +/* { dg-add-options arm_neon } */ + +typedef unsigned long long uint64_t; + +void f_shr_imm (uint64_t *a) +{ + *a += *a >> 32; +} + +void f_shr_reg (uint64_t *a, uint64_t b) +{ + *a += *a >> b; +} + +void f_shl_imm (uint64_t *a) +{ + *a += *a << 32; +} + +void f_shl_reg (uint64_t *a, uint64_t b) +{ + *a += *a << b; +} +/* { dg-final { scan-assembler-not "vshl*" } } */ +/* { dg-final { scan-assembler-not "vshr*" } } */ +/* { dg-final { scan-assembler-not "vmov*" } } */ Index: gcc/testsuite/gcc.target/arm/fpscr.c =================================================================== diff --git a/gcc/testsuite/gcc.target/arm/fpscr.c b/gcc/testsuite/gcc.target/arm/fpscr.c --- a/gcc/testsuite/gcc.target/arm/fpscr.c (revision 257042) +++ b/gcc/testsuite/gcc.target/arm/fpscr.c (revision 259627) @@ -6,11 +6,14 @@ /* { dg-add-options arm_fp } */ void -test_fpscr () +test_fpscr (void) { - volatile unsigned int status = __builtin_arm_get_fpscr (); + unsigned status; + + __builtin_arm_set_fpscr (0); + status = __builtin_arm_get_fpscr (); __builtin_arm_set_fpscr (status); } /* { dg-final { scan-assembler "mrc\tp10, 7, r\[0-9\]+, cr1, cr0, 0" } } */ -/* { dg-final { scan-assembler "mcr\tp10, 7, r\[0-9\]+, cr1, cr0, 0" } } */ +/* { dg-final { scan-assembler-times "mcr\tp10, 7, r\[0-9\]+, cr1, cr0, 0" 2 } } */ Index: gcc/testsuite/gcc.target/arm/pr84826.c =================================================================== diff --git a/gcc/testsuite/gcc.target/arm/pr84826.c b/gcc/testsuite/gcc.target/arm/pr84826.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/arm/pr84826.c (revision 259627) @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_thumb2_ok } */ +/* { dg-options "-Ofast -fstack-check" } */ + +void d (void *); + +void a () +{ + int b; + void bar (int c) + { + if (__builtin_expect (c, 0)) + ++b; + } + d (bar); +} Index: gcc/testsuite/gcc.target/s390/nobp-table-jump-z10.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-table-jump-z10.c b/gcc/testsuite/gcc.target/s390/nobp-table-jump-z10.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-table-jump-z10.c (revision 259627) @@ -0,0 +1,77 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 -mzarch --save-temps -mindirect-branch-jump=thunk -mindirect-branch-table" } */ +/* case-values-threshold will be set to 20 by the back-end when jump + thunk are requested. */ + +int __attribute__((noinline,noclone)) foo1 (void) { return 1; } +int __attribute__((noinline,noclone)) foo2 (void) { return 2; } +int __attribute__((noinline,noclone)) foo3 (void) { return 3; } +int __attribute__((noinline,noclone)) foo4 (void) { return 4; } +int __attribute__((noinline,noclone)) foo5 (void) { return 5; } +int __attribute__((noinline,noclone)) foo6 (void) { return 6; } +int __attribute__((noinline,noclone)) foo7 (void) { return 7; } +int __attribute__((noinline,noclone)) foo8 (void) { return 8; } +int __attribute__((noinline,noclone)) foo9 (void) { return 9; } +int __attribute__((noinline,noclone)) foo10 (void) { return 10; } +int __attribute__((noinline,noclone)) foo11 (void) { return 11; } +int __attribute__((noinline,noclone)) foo12 (void) { return 12; } +int __attribute__((noinline,noclone)) foo13 (void) { return 13; } +int __attribute__((noinline,noclone)) foo14 (void) { return 14; } +int __attribute__((noinline,noclone)) foo15 (void) { return 15; } +int __attribute__((noinline,noclone)) foo16 (void) { return 16; } +int __attribute__((noinline,noclone)) foo17 (void) { return 17; } +int __attribute__((noinline,noclone)) foo18 (void) { return 18; } +int __attribute__((noinline,noclone)) foo19 (void) { return 19; } +int __attribute__((noinline,noclone)) foo20 (void) { return 20; } + + +int __attribute__((noinline,noclone)) +bar (int a) +{ + int ret = 0; + + switch (a) + { + case 1: ret = foo1 (); break; + case 2: ret = foo2 (); break; + case 3: ret = foo3 (); break; + case 4: ret = foo4 (); break; + case 5: ret = foo5 (); break; + case 6: ret = foo6 (); break; + case 7: ret = foo7 (); break; + case 8: ret = foo8 (); break; + case 9: ret = foo9 (); break; + case 10: ret = foo10 (); break; + case 11: ret = foo11 (); break; + case 12: ret = foo12 (); break; + case 13: ret = foo13 (); break; + case 14: ret = foo14 (); break; + case 15: ret = foo15 (); break; + case 16: ret = foo16 (); break; + case 17: ret = foo17 (); break; + case 18: ret = foo18 (); break; + case 19: ret = foo19 (); break; + case 20: ret = foo20 (); break; + default: + __builtin_abort (); + } + + return ret; +} + +int +main () +{ + if (bar (3) != 3) + __builtin_abort (); + + return 0; +} + +/* 1 x bar +/* { dg-final { scan-assembler-times "exrl" 1 } } */ + +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_fromreg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_frommem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-indirect-jump-z900.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-z900.c b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-z900.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-z900.c (revision 259627) @@ -0,0 +1,43 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z900 --save-temps -mindirect-branch-jump=thunk -mindirect-branch-table" } */ +/* { dg-require-effective-target label_values } */ + +/* This is a copy of the gcc.c-torture/execute/20040302-1.c + testcase. */ + +int code[]={0,0,0,0,1}; + +void +foo(int x) { + volatile int b; + b = 0xffffffff; +} + +void +bar(int *pc) { + static const void *l[] = {&&lab0, &&end}; + + foo(0); + goto *l[*pc]; + lab0: + foo(0); + pc++; + goto *l[*pc]; + end: + return; +} + +int +main() { + bar(code); + return 0; +} + +/* 2 x bar +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 2 } } */ +/* { dg-final { scan-assembler "ex\t" } } */ + +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-no-dwarf2-cfi.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-no-dwarf2-cfi.c b/gcc/testsuite/gcc.target/s390/nobp-no-dwarf2-cfi.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-no-dwarf2-cfi.c (revision 259627) @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z900 --save-temps -mfunction-return-reg=thunk -mindirect-branch-table -fno-dwarf2-cfi-asm" } */ + +/* Make sure that we do not emit .cfi directives when -fno-dwarf2-cfi-asm is being used. */ + +int +main () +{ + return 0; +} + +/* 1 x main +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 1 } } */ +/* { dg-final { scan-assembler "ex\t" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/pr84295.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/pr84295.c b/gcc/testsuite/gcc.target/s390/pr84295.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/pr84295.c (revision 259627) @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z900 -fgnu89-inline --save-temps -mfunction-return-reg=thunk -mindirect-branch-table" } */ + +extern void foo (void); +extern __inline void foo (void) {} +void foo (void) {} + +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 1 } } */ +/* { dg-final { scan-assembler "ex\t" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-mem-attr.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-mem-attr.c b/gcc/testsuite/gcc.target/s390/nobp-return-mem-attr.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-mem-attr.c (revision 259627) @@ -0,0 +1,46 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 -mzarch --save-temps -mindirect-branch-table" } */ + +int gl = 0; + +int __attribute__((noinline,noclone)) +bar (int a) +{ + return a + 2; +} + +void __attribute__((function_return_mem("thunk"),noinline,noclone)) +foo (int a) +{ + int i; + + if (a == 42) + return; + + for (i = 0; i < a; i++) + gl += bar (i); +} + +int +main () +{ + foo (3); + if (gl != 9) + __builtin_abort (); + + return 0; +} + +/* With -march=z10 -mzarch the shrink wrapped returns use compare and + swap relative to jump to the exit block instead of making use of + the conditional return pattern. + FIXME: Use compare and branch register for that!!!! */ + +/* 2 x foo +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 2 } } */ +/* { dg-final { scan-assembler "exrl" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-function-pointer-attr.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-function-pointer-attr.c b/gcc/testsuite/gcc.target/s390/nobp-function-pointer-attr.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-function-pointer-attr.c (revision 259627) @@ -0,0 +1,56 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 --save-temps -mindirect-branch-table" } */ + +int gl; + +void __attribute__((noinline,noclone)) +foo (int a) +{ + gl = a + 40; +} + +int __attribute__((noinline,noclone)) +foo_value (int a) +{ + return a + 40; +} + +void* __attribute__((noinline,noclone)) +get_fptr (int a) +{ + switch (a) + { + case 0: return &foo; break; + case 1: return &foo_value; break; + default: __builtin_abort (); + } +} + +void (*f) (int); +int (*g) (int); + +int __attribute__((indirect_branch_call("thunk"))) +main () +{ + int res; + + f = get_fptr(0); + f (2); + if (gl != 42) + __builtin_abort (); + + g = get_fptr(1); + if (g (2) != 42) + __builtin_abort (); + + return 0; +} + +/* 2 x main +/* { dg-final { scan-assembler-times "brasl\t%r\[0-9\]*,__s390_indirect_jump" 2 } } */ +/* { dg-final { scan-assembler "exrl" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-z900.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-z900.c b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-z900.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-z900.c (revision 259627) @@ -0,0 +1,43 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z900 --save-temps -mindirect-branch-jump=thunk-inline -mindirect-branch-table" } */ +/* { dg-require-effective-target label_values } */ + +/* This is a copy of the gcc.c-torture/execute/20040302-1.c + testcase. */ + +int code[]={0,0,0,0,1}; + +void +foo(int x) { + volatile int b; + b = 0xffffffff; +} + +void +bar(int *pc) { + static const void *l[] = {&&lab0, &&end}; + + foo(0); + goto *l[*pc]; + lab0: + foo(0); + pc++; + goto *l[*pc]; + end: + return; +} + +int +main() { + bar(code); + return 0; +} + +/* The two gotos in bar get merged. */ +/* { dg-final { scan-assembler-times "\tex\t" 1 } } */ + +/* { dg-final { scan-assembler-not "jg\t__s390_indirect_jump" } } */ +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-table-jump-inline-z900.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-table-jump-inline-z900.c b/gcc/testsuite/gcc.target/s390/nobp-table-jump-inline-z900.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-table-jump-inline-z900.c (revision 259627) @@ -0,0 +1,78 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z900 -mzarch --save-temps -mindirect-branch-jump=thunk-inline -mindirect-branch-table" } */ + +/* case-values-threshold will be set to 20 by the back-end when jump + thunk are requested. */ + +int __attribute__((noinline,noclone)) foo1 (void) { return 1; } +int __attribute__((noinline,noclone)) foo2 (void) { return 2; } +int __attribute__((noinline,noclone)) foo3 (void) { return 3; } +int __attribute__((noinline,noclone)) foo4 (void) { return 4; } +int __attribute__((noinline,noclone)) foo5 (void) { return 5; } +int __attribute__((noinline,noclone)) foo6 (void) { return 6; } +int __attribute__((noinline,noclone)) foo7 (void) { return 7; } +int __attribute__((noinline,noclone)) foo8 (void) { return 8; } +int __attribute__((noinline,noclone)) foo9 (void) { return 9; } +int __attribute__((noinline,noclone)) foo10 (void) { return 10; } +int __attribute__((noinline,noclone)) foo11 (void) { return 11; } +int __attribute__((noinline,noclone)) foo12 (void) { return 12; } +int __attribute__((noinline,noclone)) foo13 (void) { return 13; } +int __attribute__((noinline,noclone)) foo14 (void) { return 14; } +int __attribute__((noinline,noclone)) foo15 (void) { return 15; } +int __attribute__((noinline,noclone)) foo16 (void) { return 16; } +int __attribute__((noinline,noclone)) foo17 (void) { return 17; } +int __attribute__((noinline,noclone)) foo18 (void) { return 18; } +int __attribute__((noinline,noclone)) foo19 (void) { return 19; } +int __attribute__((noinline,noclone)) foo20 (void) { return 20; } + + +int __attribute__((noinline,noclone)) +bar (int a) +{ + int ret = 0; + + switch (a) + { + case 1: ret = foo1 (); break; + case 2: ret = foo2 (); break; + case 3: ret = foo3 (); break; + case 4: ret = foo4 (); break; + case 5: ret = foo5 (); break; + case 6: ret = foo6 (); break; + case 7: ret = foo7 (); break; + case 8: ret = foo8 (); break; + case 9: ret = foo9 (); break; + case 10: ret = foo10 (); break; + case 11: ret = foo11 (); break; + case 12: ret = foo12 (); break; + case 13: ret = foo13 (); break; + case 14: ret = foo14 (); break; + case 15: ret = foo15 (); break; + case 16: ret = foo16 (); break; + case 17: ret = foo17 (); break; + case 18: ret = foo18 (); break; + case 19: ret = foo19 (); break; + case 20: ret = foo20 (); break; + default: + __builtin_abort (); + } + + return ret; +} + +int +main () +{ + if (bar (3) != 3) + __builtin_abort (); + + return 0; +} + +/* 1 x bar +/* { dg-final { scan-assembler-times "\tex\t" 1 } } */ + +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_fromreg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_frommem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-reg-nothunk.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-reg-nothunk.c b/gcc/testsuite/gcc.target/s390/nobp-return-reg-nothunk.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-reg-nothunk.c (revision 259627) @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z10 --save-temps -mfunction-return-reg=thunk-extern -mindirect-branch-table" } */ + +int gl = 0; + +int __attribute__((noinline,noclone)) +bar (int a) +{ + return a + 2; +} + +void __attribute__((noinline,noclone)) +foo (int a) +{ + int i; + + if (a == 42) + return; + + for (i = 0; i < a; i++) + gl += bar (i); +} + +int +main () +{ + foo (3); + if (gl != 9) + __builtin_abort (); + + return 0; +} + +/* 1 x bar +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 1 } } */ + +/* No thunks due to thunk-extern. */ +/* { dg-final { scan-assembler-not "exrl" } } */ +/* { dg-final { scan-assembler-not ".globl __s390_indirect_jump" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-mem-nothunk.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-mem-nothunk.c b/gcc/testsuite/gcc.target/s390/nobp-return-mem-nothunk.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-mem-nothunk.c (revision 259627) @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z10 -mzarch --save-temps -mfunction-return-mem=thunk-extern -mindirect-branch-table" } */ + +int gl = 0; + +int __attribute__((noinline,noclone)) +bar (int a) +{ + return a + 2; +} + +void __attribute__((noinline,noclone)) +foo (int a) +{ + int i; + + if (a == 42) + return; + + for (i = 0; i < a; i++) + gl += bar (i); +} + +int +main () +{ + foo (3); + if (gl != 9) + __builtin_abort (); + + return 0; +} + +/* With -march=z10 -mzarch the shrink wrapped returns use compare and + swap relative to jump to the exit block instead of making use of + the conditional return pattern. + FIXME: Use compare and branch register for that!!!! */ + +/* 2 x foo, 1 x main +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 3 } } */ + +/* No thunks due to thunk-extern. */ +/* { dg-final { scan-assembler-not "exrl" } } */ +/* { dg-final { scan-assembler-not ".globl __s390_indirect_jump" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-function-pointer-nothunk.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-function-pointer-nothunk.c b/gcc/testsuite/gcc.target/s390/nobp-function-pointer-nothunk.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-function-pointer-nothunk.c (revision 259627) @@ -0,0 +1,59 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z10 --save-temps -mindirect-branch-call=thunk-extern -mindirect-branch-table" } */ + +int gl; + +void __attribute__((noinline,noclone)) +foo (int a) +{ + gl = a + 40; +} + +int __attribute__((noinline,noclone)) +foo_value (int a) +{ + return a + 40; +} + +void* __attribute__((noinline,noclone)) +get_fptr (int a) +{ + switch (a) + { + case 0: return &foo; break; + case 1: return &foo_value; break; + default: __builtin_abort (); + } +} + +void (*f) (int); +int (*g) (int); + +int +main () +{ + int res; + + f = get_fptr(0); + f (2); + if (gl != 42) + __builtin_abort (); + + g = get_fptr(1); + if (g (2) != 42) + __builtin_abort (); + + return 0; +} + +/* 2 x main +/* { dg-final { scan-assembler-times "brasl\t%r\[0-9\]*,__s390_indirect_jump" 2 } } */ + +/* No thunks due to thunk-extern. */ +/* { dg-final { scan-assembler-not "exrl" } } */ +/* { dg-final { scan-assembler-not ".globl __s390_indirect_jump" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-indirect-jump-nothunk.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-nothunk.c b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-nothunk.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-nothunk.c (revision 259627) @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z10 --save-temps -mindirect-branch-jump=thunk-extern -mindirect-branch-table" } */ +/* { dg-require-effective-target label_values } */ + +/* This is a copy of the gcc.c-torture/execute/20040302-1.c + testcase. */ + +int code[]={0,0,0,0,1}; + +void +foo(int x) { + volatile int b; + b = 0xffffffff; +} + +void +bar(int *pc) { + static const void *l[] = {&&lab0, &&end}; + + foo(0); + goto *l[*pc]; + lab0: + foo(0); + pc++; + goto *l[*pc]; + end: + return; +} + +int +main() { + bar(code); + return 0; +} + +/* 2 x bar +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 2 } } */ + +/* No thunks due to thunk-extern. */ +/* { dg-final { scan-assembler-not "exrl" } } */ +/* { dg-final { scan-assembler-not ".globl __s390_indirect_jump" } } */ + +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-mem-z10.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-mem-z10.c b/gcc/testsuite/gcc.target/s390/nobp-return-mem-z10.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-mem-z10.c (revision 259627) @@ -0,0 +1,46 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 -mzarch --save-temps -mfunction-return-mem=thunk -mindirect-branch-table" } */ + +int gl = 0; + +int __attribute__((noinline,noclone)) +bar (int a) +{ + return a + 2; +} + +void __attribute__((noinline,noclone)) +foo (int a) +{ + int i; + + if (a == 42) + return; + + for (i = 0; i < a; i++) + gl += bar (i); +} + +int +main () +{ + foo (3); + if (gl != 9) + __builtin_abort (); + + return 0; +} + +/* With -march=z10 -mzarch the shrink wrapped returns use compare and + swap relative to jump to the exit block instead of making use of + the conditional return pattern. + FIXME: Use compare and branch register for that!!!! */ + +/* 2 x foo, 1 x main +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 3 } } */ +/* { dg-final { scan-assembler "exrl" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-function-pointer-z10.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-function-pointer-z10.c b/gcc/testsuite/gcc.target/s390/nobp-function-pointer-z10.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-function-pointer-z10.c (revision 259627) @@ -0,0 +1,56 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 --save-temps -mindirect-branch-call=thunk -mindirect-branch-table" } */ + +int gl; + +void __attribute__((noinline,noclone)) +foo (int a) +{ + gl = a + 40; +} + +int __attribute__((noinline,noclone)) +foo_value (int a) +{ + return a + 40; +} + +void* __attribute__((noinline,noclone)) +get_fptr (int a) +{ + switch (a) + { + case 0: return &foo; break; + case 1: return &foo_value; break; + default: __builtin_abort (); + } +} + +void (*f) (int); +int (*g) (int); + +int +main () +{ + int res; + + f = get_fptr(0); + f (2); + if (gl != 42) + __builtin_abort (); + + g = get_fptr(1); + if (g (2) != 42) + __builtin_abort (); + + return 0; +} + +/* 2 x main +/* { dg-final { scan-assembler-times "brasl\t%r\[0-9\]*,__s390_indirect_jump" 2 } } */ +/* { dg-final { scan-assembler "exrl" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-reg-attr.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-reg-attr.c b/gcc/testsuite/gcc.target/s390/nobp-return-reg-attr.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-reg-attr.c (revision 259627) @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 --save-temps -mindirect-branch-table" } */ + +int gl = 0; + +int __attribute__((function_return_reg("thunk"),noinline,noclone)) +bar (int a) +{ + return a + 2; +} + +void __attribute__((noinline,noclone)) +foo (int a) +{ + int i; + + if (a == 42) + return; + + for (i = 0; i < a; i++) + gl += bar (i); +} + +int +main () +{ + foo (3); + if (gl != 9) + __builtin_abort (); + + return 0; +} + +/* 1 x bar +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 1 } } */ +/* { dg-final { scan-assembler "exrl" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-indirect-jump-attr.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-attr.c b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-attr.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-attr.c (revision 259627) @@ -0,0 +1,42 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 --save-temps -mindirect-branch-table" } */ +/* { dg-require-effective-target label_values } */ + +/* This is a copy of the gcc.c-torture/execute/20040302-1.c + testcase. */ + +int code[]={0,0,0,0,1}; + +void +foo(int x) { + volatile int b; + b = 0xffffffff; +} + +void __attribute__((indirect_branch_jump("thunk"))) +bar(int *pc) { + static const void *l[] = {&&lab0, &&end}; + + foo(0); + goto *l[*pc]; + lab0: + foo(0); + pc++; + goto *l[*pc]; + end: + return; +} + +int main() { + bar(code); + return 0; +} + +/* 2x bar */ +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 2 } } */ +/* { dg-final { scan-assembler "exrl" } } */ + +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-mem-z900.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-mem-z900.c b/gcc/testsuite/gcc.target/s390/nobp-return-mem-z900.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-mem-z900.c (revision 259627) @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z900 --save-temps -mfunction-return-mem=thunk -mindirect-branch-table" } */ + +int gl = 0; + +int __attribute__((noinline,noclone)) +bar (int a) +{ + return a + 2; +} + +void __attribute__((noinline,noclone)) +foo (int a) +{ + int i; + + if (a == 42) + return; + + for (i = 0; i < a; i++) + gl += bar (i); +} + +int +main () +{ + foo (3); + if (gl != 9) + __builtin_abort (); + + return 0; +} + +/* 1 x foo, 1 x main +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 2 } } */ + +/* 1 x foo, conditional return, shrink wrapped +/* { dg-final { scan-assembler "jge\t__s390_indirect_jump" } } */ + +/* 1 x foo, conditional return, shrink wrapped +/* { dg-final { scan-assembler "jgle\t__s390_indirect_jump" } } */ + +/* { dg-final { scan-assembler "ex\t" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-z10.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-z10.c b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-z10.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-z10.c (revision 259627) @@ -0,0 +1,43 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 --save-temps -mindirect-branch-jump=thunk-inline -mindirect-branch-table" } */ +/* { dg-require-effective-target label_values } */ + +/* This is a copy of the gcc.c-torture/execute/20040302-1.c + testcase. */ + +int code[]={0,0,0,0,1}; + +void +foo(int x) { + volatile int b; + b = 0xffffffff; +} + +void +bar(int *pc) { + static const void *l[] = {&&lab0, &&end}; + + foo(0); + goto *l[*pc]; + lab0: + foo(0); + pc++; + goto *l[*pc]; + end: + return; +} + +int +main() { + bar(code); + return 0; +} + +/* The two gotos in bar get merged. */ +/* { dg-final { scan-assembler-times "exrl" 1 } } */ + +/* { dg-final { scan-assembler-not "jg\t__s390_indirect_jump" } } */ +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-attr-neg.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-attr-neg.c b/gcc/testsuite/gcc.target/s390/nobp-return-attr-neg.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-attr-neg.c (revision 259627) @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 -mzarch --save-temps -mfunction-return-mem=thunk -mindirect-branch-table" } */ + +int gl = 0; + +int __attribute__((noinline,noclone)) +bar (int a) +{ + return a + 2; +} + +void __attribute__((function_return("keep"),noinline,noclone)) +foo (int a) +{ + int i; + + if (a == 42) + return; + + for (i = 0; i < a; i++) + gl += bar (i); +} + +int __attribute__((function_return("keep"))) +main () +{ + foo (3); + if (gl != 9) + __builtin_abort (); + + return 0; +} + +/* { dg-final { scan-assembler-not "jg\t__s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "exrl" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-function-pointer-z900.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-function-pointer-z900.c b/gcc/testsuite/gcc.target/s390/nobp-function-pointer-z900.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-function-pointer-z900.c (revision 259627) @@ -0,0 +1,56 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z900 --save-temps -mindirect-branch-call=thunk -mindirect-branch-table" } */ + +int gl; + +void __attribute__((noinline,noclone)) +foo (int a) +{ + gl = a + 40; +} + +int __attribute__((noinline,noclone)) +foo_value (int a) +{ + return a + 40; +} + +void* __attribute__((noinline,noclone)) +get_fptr (int a) +{ + switch (a) + { + case 0: return &foo; break; + case 1: return &foo_value; break; + default: __builtin_abort (); + } +} + +void (*f) (int); +int (*g) (int); + +int +main () +{ + int res; + + f = get_fptr(0); + f (2); + if (gl != 42) + __builtin_abort (); + + g = get_fptr(1); + if (g (2) != 42) + __builtin_abort (); + + return 0; +} + +/* 2 x main +/* { dg-final { scan-assembler-times "brasl\t%r\[0-9\]*,__s390_indirect_jump" 2 } } */ +/* { dg-final { scan-assembler "ex\t" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-attr.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-attr.c b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-attr.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-inline-attr.c (revision 259627) @@ -0,0 +1,42 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 --save-temps -mindirect-branch-table" } */ +/* { dg-require-effective-target label_values } */ + +/* This is a copy of the gcc.c-torture/execute/20040302-1.c + testcase. */ + +int code[]={0,0,0,0,1}; + +void foo(int x) { + volatile int b; + b = 0xffffffff; +} + +void __attribute__((indirect_branch_jump("thunk-inline"))) +bar(int *pc) { + static const void *l[] = {&&lab0, &&end}; + + foo(0); + goto *l[*pc]; + lab0: + foo(0); + pc++; + goto *l[*pc]; + end: + return; +} + +int +main() { + bar(code); + return 0; +} + +/* The two gotos in bar get merged. */ +/* { dg-final { scan-assembler-times "exrl" 1 } } */ + +/* { dg-final { scan-assembler-not "jg\t__s390_indirect_jump" } } */ +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-table-jump-z900.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-table-jump-z900.c b/gcc/testsuite/gcc.target/s390/nobp-table-jump-z900.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-table-jump-z900.c (revision 259627) @@ -0,0 +1,78 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z900 -mzarch --save-temps -mindirect-branch-jump=thunk -mindirect-branch-table" } */ + +/* case-values-threshold will be set to 20 by the back-end when jump + thunk are requested. */ + +int __attribute__((noinline,noclone)) foo1 (void) { return 1; } +int __attribute__((noinline,noclone)) foo2 (void) { return 2; } +int __attribute__((noinline,noclone)) foo3 (void) { return 3; } +int __attribute__((noinline,noclone)) foo4 (void) { return 4; } +int __attribute__((noinline,noclone)) foo5 (void) { return 5; } +int __attribute__((noinline,noclone)) foo6 (void) { return 6; } +int __attribute__((noinline,noclone)) foo7 (void) { return 7; } +int __attribute__((noinline,noclone)) foo8 (void) { return 8; } +int __attribute__((noinline,noclone)) foo9 (void) { return 9; } +int __attribute__((noinline,noclone)) foo10 (void) { return 10; } +int __attribute__((noinline,noclone)) foo11 (void) { return 11; } +int __attribute__((noinline,noclone)) foo12 (void) { return 12; } +int __attribute__((noinline,noclone)) foo13 (void) { return 13; } +int __attribute__((noinline,noclone)) foo14 (void) { return 14; } +int __attribute__((noinline,noclone)) foo15 (void) { return 15; } +int __attribute__((noinline,noclone)) foo16 (void) { return 16; } +int __attribute__((noinline,noclone)) foo17 (void) { return 17; } +int __attribute__((noinline,noclone)) foo18 (void) { return 18; } +int __attribute__((noinline,noclone)) foo19 (void) { return 19; } +int __attribute__((noinline,noclone)) foo20 (void) { return 20; } + + +int __attribute__((noinline,noclone)) +bar (int a) +{ + int ret = 0; + + switch (a) + { + case 1: ret = foo1 (); break; + case 2: ret = foo2 (); break; + case 3: ret = foo3 (); break; + case 4: ret = foo4 (); break; + case 5: ret = foo5 (); break; + case 6: ret = foo6 (); break; + case 7: ret = foo7 (); break; + case 8: ret = foo8 (); break; + case 9: ret = foo9 (); break; + case 10: ret = foo10 (); break; + case 11: ret = foo11 (); break; + case 12: ret = foo12 (); break; + case 13: ret = foo13 (); break; + case 14: ret = foo14 (); break; + case 15: ret = foo15 (); break; + case 16: ret = foo16 (); break; + case 17: ret = foo17 (); break; + case 18: ret = foo18 (); break; + case 19: ret = foo19 (); break; + case 20: ret = foo20 (); break; + default: + __builtin_abort (); + } + + return ret; +} + +int +main () +{ + if (bar (3) != 3) + __builtin_abort (); + + return 0; +} + +/* 1 x bar +/* { dg-final { scan-assembler-times "ex\t" 1 } } */ + +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_fromreg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_frommem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-reg-z10.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-reg-z10.c b/gcc/testsuite/gcc.target/s390/nobp-return-reg-z10.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-reg-z10.c (revision 259627) @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 --save-temps -mfunction-return-reg=thunk -mindirect-branch-table" } */ + +int gl = 0; + +int __attribute__((noinline,noclone)) +bar (int a) +{ + return a + 2; +} + +void __attribute__((noinline,noclone)) +foo (int a) +{ + int i; + + if (a == 42) + return; + + for (i = 0; i < a; i++) + gl += bar (i); +} + +int +main () +{ + foo (3); + if (gl != 9) + __builtin_abort (); + + return 0; +} + +/* 1 x bar +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 1 } } */ +/* { dg-final { scan-assembler "exrl" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-indirect-jump-z10.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-z10.c b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-z10.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-indirect-jump-z10.c (revision 259627) @@ -0,0 +1,43 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 --save-temps -mindirect-branch-jump=thunk -mindirect-branch-table" } */ +/* { dg-require-effective-target label_values } */ + +/* This is a copy of the gcc.c-torture/execute/20040302-1.c + testcase. */ + +int code[]={0,0,0,0,1}; + +void +foo(int x) { + volatile int b; + b = 0xffffffff; +} + +void +bar(int *pc) { + static const void *l[] = {&&lab0, &&end}; + + foo(0); + goto *l[*pc]; + lab0: + foo(0); + pc++; + goto *l[*pc]; + end: + return; +} + +int +main() { + bar(code); + return 0; +} + +/* 2x bar */ +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 2 } } */ +/* { dg-final { scan-assembler "exrl" } } */ + +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-table-jump-inline-z10.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-table-jump-inline-z10.c b/gcc/testsuite/gcc.target/s390/nobp-table-jump-inline-z10.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-table-jump-inline-z10.c (revision 259627) @@ -0,0 +1,78 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 -mzarch --save-temps -mindirect-branch-jump=thunk-inline -mindirect-branch-table" } */ + +/* case-values-threshold will be set to 20 by the back-end when jump + thunk are requested. */ + +int __attribute__((noinline,noclone)) foo1 (void) { return 1; } +int __attribute__((noinline,noclone)) foo2 (void) { return 2; } +int __attribute__((noinline,noclone)) foo3 (void) { return 3; } +int __attribute__((noinline,noclone)) foo4 (void) { return 4; } +int __attribute__((noinline,noclone)) foo5 (void) { return 5; } +int __attribute__((noinline,noclone)) foo6 (void) { return 6; } +int __attribute__((noinline,noclone)) foo7 (void) { return 7; } +int __attribute__((noinline,noclone)) foo8 (void) { return 8; } +int __attribute__((noinline,noclone)) foo9 (void) { return 9; } +int __attribute__((noinline,noclone)) foo10 (void) { return 10; } +int __attribute__((noinline,noclone)) foo11 (void) { return 11; } +int __attribute__((noinline,noclone)) foo12 (void) { return 12; } +int __attribute__((noinline,noclone)) foo13 (void) { return 13; } +int __attribute__((noinline,noclone)) foo14 (void) { return 14; } +int __attribute__((noinline,noclone)) foo15 (void) { return 15; } +int __attribute__((noinline,noclone)) foo16 (void) { return 16; } +int __attribute__((noinline,noclone)) foo17 (void) { return 17; } +int __attribute__((noinline,noclone)) foo18 (void) { return 18; } +int __attribute__((noinline,noclone)) foo19 (void) { return 19; } +int __attribute__((noinline,noclone)) foo20 (void) { return 20; } + + +int __attribute__((noinline,noclone)) +bar (int a) +{ + int ret = 0; + + switch (a) + { + case 1: ret = foo1 (); break; + case 2: ret = foo2 (); break; + case 3: ret = foo3 (); break; + case 4: ret = foo4 (); break; + case 5: ret = foo5 (); break; + case 6: ret = foo6 (); break; + case 7: ret = foo7 (); break; + case 8: ret = foo8 (); break; + case 9: ret = foo9 (); break; + case 10: ret = foo10 (); break; + case 11: ret = foo11 (); break; + case 12: ret = foo12 (); break; + case 13: ret = foo13 (); break; + case 14: ret = foo14 (); break; + case 15: ret = foo15 (); break; + case 16: ret = foo16 (); break; + case 17: ret = foo17 (); break; + case 18: ret = foo18 (); break; + case 19: ret = foo19 (); break; + case 20: ret = foo20 (); break; + default: + __builtin_abort (); + } + + return ret; +} + +int +main () +{ + if (bar (3) != 3) + __builtin_abort (); + + return 0; +} + +/* 1 x bar +/* { dg-final { scan-assembler-times "exrl" 1 } } */ + +/* { dg-final { scan-assembler "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_fromreg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_frommem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-reg-z900.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-reg-z900.c b/gcc/testsuite/gcc.target/s390/nobp-return-reg-z900.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-reg-z900.c (revision 259627) @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z900 --save-temps -mfunction-return-reg=thunk -mindirect-branch-table" } */ + +int gl = 0; + +int __attribute__((noinline,noclone)) +bar (int a) +{ + return a + 2; +} + +void __attribute__((noinline,noclone)) +foo (int a) +{ + int i; + + if (a == 42) + return; + + for (i = 0; i < a; i++) + gl += bar (i); +} + +int +main () +{ + foo (3); + if (gl != 9) + __builtin_abort (); + + return 0; +} + +/* 1 x bar +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 1 } } */ +/* { dg-final { scan-assembler "ex\t" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-attr-all.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-attr-all.c b/gcc/testsuite/gcc.target/s390/nobp-return-attr-all.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-attr-all.c (revision 259627) @@ -0,0 +1,46 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z10 -mzarch --save-temps -mindirect-branch-table" } */ + +int gl = 0; + +int __attribute__((noinline,noclone)) +bar (int a) +{ + return a + 2; +} + +void __attribute__((function_return("thunk"),noinline,noclone)) +foo (int a) +{ + int i; + + if (a == 42) + return; + + for (i = 0; i < a; i++) + gl += bar (i); +} + +int +main () +{ + foo (3); + if (gl != 9) + __builtin_abort (); + + return 0; +} + +/* With -march=z10 -mzarch the shrink wrapped returns use compare and + swap relative to jump to the exit block instead of making use of + the conditional return pattern. + FIXME: Use compare and branch register for that!!!! */ + +/* 2 x foo +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 2 } } */ +/* { dg-final { scan-assembler "exrl" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/s390/nobp-return-reg-mixed.c =================================================================== diff --git a/gcc/testsuite/gcc.target/s390/nobp-return-reg-mixed.c b/gcc/testsuite/gcc.target/s390/nobp-return-reg-mixed.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/s390/nobp-return-reg-mixed.c (revision 259627) @@ -0,0 +1,44 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -march=z900 --save-temps -mfunction-return-reg=thunk -mindirect-branch-table" } */ + +/* We have to generate different thunks for indirect branches + depending on whether the code is compiled for pre z10 machines or + later. This testcase makes sure this works within the same compile + unit. */ + +int __attribute__((noinline,noclone,target("arch=z10"))) +bar (int a) +{ + return a + 2; +} + +int __attribute__((noinline,noclone,target("arch=z9-ec"))) +foo (int a) +{ + return a + 3; +} + +int +main () +{ + if (bar (42) != 44) + __builtin_abort (); + + if (foo (42) != 45) + __builtin_abort (); + + return 0; +} + +/* 1 x bar, 1 x foo */ +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 2 } } */ +/* 1 x foo */ +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump_r1use" 1 } } */ + +/* { dg-final { scan-assembler-times "ex\t" 1 } } */ +/* { dg-final { scan-assembler-times "exrl\t" 1 } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ Index: gcc/testsuite/gcc.target/msp430/pr79242.c =================================================================== diff --git a/gcc/testsuite/gcc.target/msp430/pr79242.c b/gcc/testsuite/gcc.target/msp430/pr79242.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/msp430/pr79242.c (revision 259627) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { "*-*-*" } { "-mcpu=msp430" "-msmall" } { "" } } */ +/* { dg-options "-mcpu=msp430x" } */ + +typedef _Complex __int20 C; + +C +foo (C x, C y) +{ + return x + y; +} Index: gcc/testsuite/gcc.target/aarch64/pr81647.c =================================================================== diff --git a/gcc/testsuite/gcc.target/aarch64/pr81647.c b/gcc/testsuite/gcc.target/aarch64/pr81647.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/aarch64/pr81647.c (revision 259627) @@ -0,0 +1,45 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-tree-ssa" } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include + +double x[28], y[28]; +int res[28]; + +int +main (void) +{ + int i; + for (i = 0; i < 28; ++i) + { + x[i] = __builtin_nan (""); + y[i] = i; + } + __asm__ volatile ("" ::: "memory"); + feclearexcept (FE_ALL_EXCEPT); + for (i = 0; i < 4; ++i) + res[i] = __builtin_isgreater (x[i], y[i]); + for (i = 4; i < 8; ++i) + res[i] = __builtin_isgreaterequal (x[i], y[i]); + for (i = 8; i < 12; ++i) + res[i] = __builtin_isless (x[i], y[i]); + for (i = 12; i < 16; ++i) + res[i] = __builtin_islessequal (x[i], y[i]); + for (i = 16; i < 20; ++i) + res[i] = __builtin_islessgreater (x[i], y[i]); + for (i = 20; i < 24; ++i) + res[i] = __builtin_isunordered (x[i], y[i]); + for (i = 24; i < 28; ++i) + res[i] = !(__builtin_isunordered (x[i], y[i])); + __asm__ volatile ("" ::: "memory"); + return fetestexcept (FE_ALL_EXCEPT) != 0; +} + +/* { dg-final { scan-tree-dump " u> " "ssa" } } */ +/* { dg-final { scan-tree-dump " u>= " "ssa" } } */ +/* { dg-final { scan-tree-dump " u< " "ssa" } } */ +/* { dg-final { scan-tree-dump " u<= " "ssa" } } */ +/* { dg-final { scan-tree-dump " u== " "ssa" } } */ +/* { dg-final { scan-tree-dump " unord " "ssa" } } */ +/* { dg-final { scan-tree-dump " ord " "ssa" } } */ Index: gcc/testsuite/gcc.target/aarch64/pr63304_1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/aarch64/pr63304_1.c b/gcc/testsuite/gcc.target/aarch64/pr63304_1.c --- a/gcc/testsuite/gcc.target/aarch64/pr63304_1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/aarch64/pr63304_1.c (revision 259627) @@ -1,5 +1,5 @@ /* { dg-do assemble } */ -/* { dg-options "-O1 --save-temps -mno-fix-cortex-a53-843419" } */ +/* { dg-options "-O1 --save-temps" } */ #pragma GCC push_options #pragma GCC target ("+nothing+simd, cmodel=small") Index: gcc/testsuite/gcc.target/aarch64/pr83370.c =================================================================== diff --git a/gcc/testsuite/gcc.target/aarch64/pr83370.c b/gcc/testsuite/gcc.target/aarch64/pr83370.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/aarch64/pr83370.c (revision 259627) @@ -0,0 +1,22 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +typedef void (*fun) (void); + +void +f (fun x1) +{ + register fun x2 asm ("x16"); + int arr[5000]; + int *volatile ptr = arr; + asm ("mov %0, %1" : "=r" (x2) : "r" (x1)); + x2 (); +} + +void g (void) {} + +int +main (void) +{ + f (g); +} Index: gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c (revision 259627) @@ -12,7 +12,7 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ /* { dg-final { scan-assembler-times {\tpause} 1 } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c (revision 259627) @@ -11,9 +11,8 @@ dispatch(offset); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/pr85193.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/pr85193.c b/gcc/testsuite/gcc.target/i386/pr85193.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/pr85193.c (revision 259627) @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-Wno-psabi -O2 -fno-tree-ccp -fno-tree-fre -mno-sse" } */ + +typedef unsigned char U __attribute__((vector_size(16))); +typedef unsigned int V __attribute__((vector_size(16))); +typedef unsigned long long W __attribute__((vector_size(16))); + +extern void bar(U, U); + +V v; + +void +foo(U f) +{ + f[0] = f[0] << (unsigned char)~v[0] | f[~((W)(U){0, 0, 0, 0, 0, 0, 0, 0, 5})[1] & 5] >> (-(unsigned char)~v[0] & 7); + bar(f, (U){}); +} Index: gcc/testsuite/gcc.target/i386/ret-thunk-10.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c --- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c (revision 259627) @@ -15,9 +15,6 @@ /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ /* { dg-final { scan-assembler-times {\tpause} 2 } } */ /* { dg-final { scan-assembler-times {\tlfence} 2 } } */ -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ -/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */ +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c (revision 259627) @@ -9,8 +9,10 @@ bar (); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ Index: gcc/testsuite/gcc.target/i386/pr82795.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/pr82795.c b/gcc/testsuite/gcc.target/i386/pr82795.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/pr82795.c (revision 259627) @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mavx2" } */ + +void +sj (int qh, int rn, int *by) +{ + for (;;) + if (qh != 0) + { + int dc; + + for (dc = 0; dc < 17; ++dc) + { + int nn; + + nn = (rn != 0) ? qh : dc; + if (nn != 0) + qh = nn; + else + qh = (qh != 0) ? *by : dc; + } + } +} Index: gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c (revision 259627) @@ -12,9 +12,8 @@ dispatch[offset](offset); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-25.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-25.c b/gcc/testsuite/gcc.target/i386/ret-thunk-25.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-25.c (revision 259627) @@ -0,0 +1,15 @@ +/* PR target/r84530 */ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-O2 -mfunction-return=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ + +struct s { _Complex unsigned short x; }; +struct s gs = { 100 + 200i }; +struct s __attribute__((noinline)) foo (void) { return gs; } + +/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ +/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk_bnd_ecx" } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler {\tpause} } } */ +/* { dg-final { scan-assembler {\tlfence} } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-9.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c --- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c (revision 259627) @@ -13,12 +13,9 @@ /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ -/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */ -/* { dg-final { scan-assembler-times {\tpause} 1 { target { ! x32 } } } } */ -/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler-times {\tpause} 2 { target { x32 } } } } */ -/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler "__x86_return_thunk:" } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler-times {\tpause} 2 } } */ +/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ Index: gcc/testsuite/gcc.target/i386/avx512f-vpermq-imm-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vpermq-imm-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vpermq-imm-2.c --- a/gcc/testsuite/gcc.target/i386/avx512f-vpermq-imm-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/avx512f-vpermq-imm-2.c (revision 259627) @@ -40,18 +40,14 @@ res3.a[i] = DEFAULT_VALUE; } -#if AVX512F_LEN == 512 res1.x = INTRINSIC (_permutex_epi64) (src1.x, IMM_MASK); -#endif res2.x = INTRINSIC (_maskz_permutex_epi64) (mask, src1.x, IMM_MASK); res3.x = INTRINSIC (_mask_permutex_epi64) (res3.x, mask, src1.x, IMM_MASK); CALC (src1.a, IMM_MASK, res_ref); -#if AVX512F_LEN == 512 if (UNION_CHECK (AVX512F_LEN, i_q) (res1, res_ref)) abort (); -#endif MASK_ZERO (i_q) (res_ref, mask, SIZE); if (UNION_CHECK (AVX512F_LEN, i_q) (res2, res_ref)) Index: gcc/testsuite/gcc.target/i386/avx512bw-pr84524.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pr84524.c b/gcc/testsuite/gcc.target/i386/avx512bw-pr84524.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/avx512bw-pr84524.c (revision 259627) @@ -0,0 +1,14 @@ +/* PR target/84524 */ +/* { dg-do run { target avx512bw } } */ +/* { dg-options "-O3 -mavx512bw" } */ + +#include "avx512bw-check.h" + +#define main() do_main() +#include "../../gcc.c-torture/execute/pr84524.c" + +static void +avx512bw_test (void) +{ + do_main (); +} Index: gcc/testsuite/gcc.target/i386/pr84310-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/pr84310-2.c b/gcc/testsuite/gcc.target/i386/pr84310-2.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/pr84310-2.c (revision 259627) @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -malign-loops=16" } */ +/* { dg-warning "is obsolete" "" { target *-*-* } 0 } */ + +void +c (void) +{ + for (;;) + ; +} Index: gcc/testsuite/gcc.target/i386/pr84625.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/pr84625.c b/gcc/testsuite/gcc.target/i386/pr84625.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/pr84625.c (revision 259627) @@ -0,0 +1,12 @@ +/* PR inline-asm/84625 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse2" } */ + +typedef int V __attribute__((vector_size (16))); + +void +foo (void) +{ + asm volatile ("# %0" : : "X" ((V) { 1, 2, 3, 4 })); // { dg-error "invalid vector immediate" } + asm volatile ("# %0" : : "" ((V) { 2, 3, 4, 5 })); // { dg-error "invalid vector immediate" } +} Index: gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c (revision 259627) @@ -12,7 +12,7 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ /* { dg-final { scan-assembler-times {\tpause} 1 } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c (revision 259627) @@ -11,9 +11,8 @@ dispatch[offset](offset); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-11.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c --- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c (revision 259627) @@ -15,9 +15,6 @@ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ -/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */ +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c (revision 259627) @@ -10,8 +10,8 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c (revision 259627) @@ -14,10 +14,9 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ /* { dg-final { scan-assembler {\tpause} } } */ /* { dg-final { scan-assembler {\tlfence} } } */ /* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-26.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c (revision 259627) @@ -0,0 +1,40 @@ +/* PR target/r84530 */ +/* { dg-do run } */ +/* { dg-options "-Os -mfunction-return=thunk" } */ + +struct S { int i; }; +__attribute__((const, noinline, noclone)) +struct S foo (int x) +{ + struct S s; + s.i = x; + return s; +} + +int a[2048], b[2048], c[2048], d[2048]; +struct S e[2048]; + +__attribute__((noinline, noclone)) void +bar (void) +{ + int i; + for (i = 0; i < 1024; i++) + { + e[i] = foo (i); + a[i+2] = a[i] + a[i+1]; + b[10] = b[10] + i; + c[i] = c[2047 - i]; + d[i] = d[i + 1]; + } +} + +int +main () +{ + int i; + bar (); + for (i = 0; i < 1024; i++) + if (e[i].i != i) + __builtin_abort (); + return 0; +} Index: gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c (revision 259627) @@ -9,7 +9,8 @@ bar (); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-3.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c (revision 259627) @@ -12,9 +12,8 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-12.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c --- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c (revision 259627) @@ -15,8 +15,6 @@ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ -/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */ +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c (revision 259627) @@ -35,9 +35,8 @@ } } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ Index: gcc/testsuite/gcc.target/i386/avx512vl-vpermd-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpermd-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpermd-1.c --- a/gcc/testsuite/gcc.target/i386/avx512vl-vpermd-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpermd-1.c (revision 259627) @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-mavx512vl -O2" } */ +/* { dg-final { scan-assembler-times "vpermd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\](?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vpermd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vpermd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */ @@ -11,6 +12,7 @@ void extern avx512vl_test (void) { + x = _mm256_permutexvar_epi32 (x, x); x = _mm256_maskz_permutexvar_epi32 (m, x, x); x = _mm256_mask_permutexvar_epi32 (x, m, x, x); } Index: gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c (revision 259627) @@ -13,10 +13,9 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ /* { dg-final { scan-assembler {\tpause} } } */ /* { dg-final { scan-assembler {\tlfence} } } */ /* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ Index: gcc/testsuite/gcc.target/i386/avx512vl-vpermq-imm-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpermq-imm-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpermq-imm-1.c --- a/gcc/testsuite/gcc.target/i386/avx512vl-vpermq-imm-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpermq-imm-1.c (revision 259627) @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-mavx512vl -O2" } */ +/* { dg-final { scan-assembler-times "vpermq\[ \\t\]+\[^\{\n\]*%ymm\[0-9\](?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vpermq\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vpermq\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */ @@ -11,6 +12,7 @@ void extern avx512vl_test (void) { + x = _mm256_permutex_epi64 (x, 13); x = _mm256_mask_permutex_epi64 (x, m, x, 13); x = _mm256_maskz_permutex_epi64 (m, x, 13); } Index: gcc/testsuite/gcc.target/i386/avx512f-vpermq-var-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vpermq-var-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vpermq-var-2.c --- a/gcc/testsuite/gcc.target/i386/avx512f-vpermq-var-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/avx512f-vpermq-var-2.c (revision 259627) @@ -41,18 +41,14 @@ res3.a[i] = DEFAULT_VALUE; } -#if AVX512F_LEN == 512 res1.x = INTRINSIC (_permutexvar_epi64) (src1.x, src2.x); -#endif res2.x = INTRINSIC (_maskz_permutexvar_epi64) (mask, src1.x, src2.x); res3.x = INTRINSIC (_mask_permutexvar_epi64) (res3.x, mask, src1.x, src2.x); CALC (src1.a, src2.a, res_ref); -#if AVX512F_LEN == 512 if (UNION_CHECK (AVX512F_LEN, i_q) (res1, res_ref)) abort (); -#endif MASK_ZERO (i_q) (res_ref, mask, SIZE); if (UNION_CHECK (AVX512F_LEN, i_q) (res2, res_ref)) Index: gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c (revision 259627) @@ -10,7 +10,8 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ /* { dg-final { scan-assembler-times {\tpause} 1 } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-4.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c (revision 259627) @@ -12,9 +12,8 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-13.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c --- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c (revision 259627) @@ -14,9 +14,8 @@ /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ /* { dg-final { scan-assembler-times {\tpause} 2 } } */ /* { dg-final { scan-assembler-times {\tlfence} 2 } } */ -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */ /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */ -/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ Index: gcc/testsuite/gcc.target/i386/i386.exp =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/i386.exp b/gcc/testsuite/gcc.target/i386/i386.exp --- a/gcc/testsuite/gcc.target/i386/i386.exp (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/i386.exp (revision 259627) @@ -241,18 +241,6 @@ } "-mrtm" ] } -# Return 1 if avx512f instructions can be compiled. -proc check_effective_target_avx512f { } { - return [check_no_compiler_messages avx512f object { - typedef long long __v8di __attribute__ ((__vector_size__ (64))); - __v8di - mm512_and_epi64 (__v8di __X, __v8di __Y) - { - return __builtin_ia32_pandq512_mask (__X, __Y, __X, -1); - } - } "-mavx512f" ] -} - # Return 1 if avx512vl instructions can be compiled. proc check_effective_target_avx512vl { } { return [check_no_compiler_messages avx512vl object { Index: gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c (revision 259627) @@ -14,9 +14,8 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ Index: gcc/testsuite/gcc.target/i386/avx512f-vpermd-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vpermd-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vpermd-2.c --- a/gcc/testsuite/gcc.target/i386/avx512f-vpermd-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/avx512f-vpermd-2.c (revision 259627) @@ -41,18 +41,14 @@ res3.a[i] = DEFAULT_VALUE; } -#if AVX512F_LEN == 512 res1.x = INTRINSIC (_permutexvar_epi32) (src1.x, src2.x); -#endif res2.x = INTRINSIC (_maskz_permutexvar_epi32) (mask, src1.x, src2.x); res3.x = INTRINSIC (_mask_permutexvar_epi32) (res3.x, mask, src1.x, src2.x); CALC (src1.a, src2.a, res_ref); -#if AVX512F_LEN == 512 if (UNION_CHECK (AVX512F_LEN, i_d) (res1, res_ref)) abort (); -#endif MASK_ZERO (i_d) (res_ref, mask, SIZE); if (UNION_CHECK (AVX512F_LEN, i_d) (res2, res_ref)) Index: gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c (revision 259627) @@ -11,9 +11,8 @@ dispatch(offset); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c (revision 259627) @@ -35,8 +35,8 @@ } } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler-not "pushq\[ \t\]%(r|e)ax" } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-5.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c (revision 259627) @@ -9,8 +9,10 @@ bar (); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c (revision 259627) @@ -10,9 +10,9 @@ dispatch (buf); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd_rax" { target lp64 } } } */ +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_eax" { target ia32 } } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "bnd ret" } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-14.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c --- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c (revision 259627) @@ -16,7 +16,6 @@ /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c (revision 259627) @@ -13,9 +13,8 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ Index: gcc/testsuite/gcc.target/i386/avx512vl-vpermq-var-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpermq-var-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpermq-var-1.c --- a/gcc/testsuite/gcc.target/i386/avx512vl-vpermq-var-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpermq-var-1.c (revision 259627) @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-mavx512vl -O2" } */ +/* { dg-final { scan-assembler-times "vpermq\[ \\t\]+\[^\{\n\]*%ymm\[0-9\](?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vpermq\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vpermq\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */ @@ -11,6 +12,7 @@ void extern avx512vl_test (void) { + x = _mm256_permutexvar_epi64 (x, x); x = _mm256_maskz_permutexvar_epi64 (m, x, x); x = _mm256_mask_permutexvar_epi64 (x, m, x, x); } Index: gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c (revision 259627) @@ -11,9 +11,8 @@ dispatch[offset](offset); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-6.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c (revision 259627) @@ -10,9 +10,13 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 { target x32 } } } */ +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ /* { dg-final { scan-assembler {\tpause} } } */ /* { dg-final { scan-assembler {\tlfence} } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-22.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-22.c b/gcc/testsuite/gcc.target/i386/ret-thunk-22.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-22.c (revision 259627) @@ -0,0 +1,15 @@ +/* PR target/r84530 */ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-O2 -mfunction-return=thunk" } */ + +struct s { _Complex unsigned short x; }; +struct s gs = { 100 + 200i }; +struct s __attribute__((noinline)) foo (void) { return gs; } + +/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ +/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk_ecx" } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler {\tpause} } } */ +/* { dg-final { scan-assembler {\tlfence} } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c (revision 259627) @@ -11,10 +11,8 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_(r|e)ax" } } */ /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "bnd ret" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-15.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c --- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c (revision 259627) @@ -16,7 +16,6 @@ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler-times {\tpause} 1 } } */ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c (revision 259627) @@ -11,7 +11,7 @@ dispatch(offset); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c (revision 259627) @@ -36,9 +36,8 @@ } } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c (revision 259627) @@ -12,9 +12,8 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ Index: gcc/testsuite/gcc.target/i386/pr84310.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/pr84310.c b/gcc/testsuite/gcc.target/i386/pr84310.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/pr84310.c (revision 259627) @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -falign-functions=100000" } */ +/* { dg-error "is not between 0 and 65536" "" { target *-*-* } 0 } */ + +void +test_func (void) +{ +} Index: gcc/testsuite/gcc.target/i386/indirect-thunk-7.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c (revision 259627) @@ -35,9 +35,8 @@ } } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-23.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-23.c b/gcc/testsuite/gcc.target/i386/ret-thunk-23.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-23.c (revision 259627) @@ -0,0 +1,15 @@ +/* PR target/r84530 */ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-O2 -mfunction-return=thunk-extern" } */ + +struct s { _Complex unsigned short x; }; +struct s gs = { 100 + 200i }; +struct s __attribute__((noinline)) foo (void) { return gs; } + +/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ +/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk_ecx" } } */ +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler-not {\tpause} } } */ +/* { dg-final { scan-assembler-not {\tlfence} } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c (revision 259627) @@ -10,8 +10,9 @@ bar (buf); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" } } */ +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd_rax" { target lp64 } } } */ +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_eax" { target ia32 } } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "bnd ret" } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c (revision 259627) @@ -11,7 +11,7 @@ dispatch[offset](offset); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c (revision 259627) @@ -12,9 +12,7 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ /* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c (revision 259627) @@ -14,9 +14,8 @@ dispatch(offset); } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ /* { dg-final { scan-assembler {\tpause} } } */ Index: gcc/testsuite/gcc.target/i386/ret-thunk-24.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-24.c b/gcc/testsuite/gcc.target/i386/ret-thunk-24.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-24.c (revision 259627) @@ -0,0 +1,15 @@ +/* PR target/r84530 */ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ + +struct s { _Complex unsigned short x; }; +struct s gs = { 100 + 200i }; +struct s __attribute__((noinline)) foo (void) { return gs; } + +/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ +/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ +/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk_ecx" } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler {\tpause} } } */ +/* { dg-final { scan-assembler {\tlfence} } } */ Index: gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c =================================================================== diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c (revision 257042) +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c (revision 259627) @@ -11,10 +11,9 @@ return 0; } -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */ -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ -/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */ +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" } } */ +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_(r|e)ax" } } */ +/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 1 } } */ /* { dg-final { scan-assembler "bnd ret" } } */ /* { dg-final { scan-assembler {\tpause} } } */ /* { dg-final { scan-assembler {\tlfence} } } */ Index: gcc/testsuite/lib/prune.exp =================================================================== diff --git a/gcc/testsuite/lib/prune.exp b/gcc/testsuite/lib/prune.exp --- a/gcc/testsuite/lib/prune.exp (revision 257042) +++ b/gcc/testsuite/lib/prune.exp (revision 259627) @@ -28,7 +28,7 @@ #send_user "Before:$text\n" - regsub -all "(^|\n)(\[^\n\]*: )?In ((static member |lambda )?function|member|method|(copy )?constructor|destructor|instantiation|substitution|program|subroutine|block-data)\[^\n\]*" $text "" text + regsub -all "(^|\n)(\[^\n\]*: \[iI\]|I)n ((static member |lambda )?function|member|method|(copy )?constructor|destructor|instantiation|substitution|program|subroutine|block-data)\[^\n\]*" $text "" text regsub -all "(^|\n)\[^\n\]*(: )?At (top level|global scope):\[^\n\]*" $text "" text regsub -all "(^|\n)\[^\n\]*: (recursively )?required \[^\n\]*" $text "" text regsub -all "(^|\n)\[^\n\]*: . skipping \[0-9\]* instantiation contexts \[^\n\]*" $text "" text Index: gcc/testsuite/lib/target-supports.exp =================================================================== diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp --- a/gcc/testsuite/lib/target-supports.exp (revision 257042) +++ b/gcc/testsuite/lib/target-supports.exp (revision 259627) @@ -5940,7 +5940,8 @@ verbose "check_effective_target_vect_load_lanes: using cached result" 2 } else { set et_vect_load_lanes 0 - if { ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) + # We don't support load_lanes correctly on big-endian arm. + if { ([istarget arm-*-*] && [check_effective_target_arm_neon_ok]) || [istarget aarch64*-*-*] } { set et_vect_load_lanes 1 } @@ -7348,11 +7349,22 @@ proc check_effective_target_avx512f { } { return [check_no_compiler_messages avx512f object { typedef double __m512d __attribute__ ((__vector_size__ (64))); + typedef double __m128d __attribute__ ((__vector_size__ (16))); __m512d _mm512_add (__m512d a) { return __builtin_ia32_addpd512_mask (a, a, a, 1, 4); } + + __m128d _mm128_add (__m128d a) + { + return __builtin_ia32_addsd_round (a, a, 8); + } + + __m128d _mm128_getmant (__m128d a) + { + return __builtin_ia32_getmantsd_round (a, a, 0, 8); + } } "-O2 -mavx512f" ] } Index: gcc/testsuite/gfortran.dg/pr71085.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr71085.f90 b/gcc/testsuite/gfortran.dg/pr71085.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr71085.f90 (revision 259627) @@ -0,0 +1,12 @@ +! { dg-do compile } +! PR 71085 +! +! Testcase from PR by Vladimir Fuka +! +program pr71085 + print *, f() +contains + function f() + integer :: f(iargc()*10) + end +end Index: gcc/testsuite/gfortran.dg/matmul_rank_1.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/matmul_rank_1.f90 b/gcc/testsuite/gfortran.dg/matmul_rank_1.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/matmul_rank_1.f90 (revision 259627) @@ -0,0 +1,9 @@ +! { dg-do compile } +! { dg-additional-options "-ffrontend-optimize" } +! PR 85044 - used to die on allocating a negative amount of memory. +! Test case by Gerhard Steinmetz. +program p + real :: a(3,3) = 1.0 + real :: b(33) + b = matmul(a, a) ! { dg-error "Incompatible ranks" } +end Index: gcc/testsuite/gfortran.dg/constant_shape.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/constant_shape.f90 b/gcc/testsuite/gfortran.dg/constant_shape.f90 --- a/gcc/testsuite/gfortran.dg/constant_shape.f90 (revision 257042) +++ b/gcc/testsuite/gfortran.dg/constant_shape.f90 (revision 259627) @@ -3,7 +3,8 @@ ! PR 78392: ICE in gfc_trans_auto_array_allocation, at fortran/trans-array.c:5979 ! ! Contributed by Janus Weil - +! Error message update with patch for PR fortran/83633 +! module mytypes implicit none contains @@ -15,6 +16,6 @@ program test use mytypes implicit none - integer, dimension(get_i()) :: x ! { dg-error "must have constant shape" } - print *, size (x) + integer, dimension(get_i()) :: x ! { dg-error "array with nonconstant bounds" } + print *, size (x) ! { dg-error "has no IMPLICIT type" } end Index: gcc/testsuite/gfortran.dg/pr84117.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr84117.f90 b/gcc/testsuite/gfortran.dg/pr84117.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr84117.f90 (revision 259627) @@ -0,0 +1,7 @@ +! PR tree-optimization/84117 +! { dg-do compile } +! { dg-options "-O3 -ftrapv" } + FUNCTION pw_integral_aa ( cc ) RESULT ( integral_value ) + COMPLEX(KIND=8), DIMENSION(:), POINTER :: cc + integral_value = accurate_sum ( CONJG ( cc (:) ) * cc (:) ) + END FUNCTION pw_integral_aa Index: gcc/testsuite/gfortran.dg/gomp/pr83977.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/gomp/pr83977.f90 b/gcc/testsuite/gfortran.dg/gomp/pr83977.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/gomp/pr83977.f90 (revision 259627) @@ -0,0 +1,15 @@ +! PR middle-end/83977 +! { dg-do compile } + +integer function foo (a, b) + integer :: a, b +!$omp declare simd uniform(b) linear(ref(a):b) + a = a + 1 +! This function can't be called from simd loops, +! because it violates declare simd restrictions. +! We shouldn't ICE on it though, nor attempt to generate +! simd clones for the *omp_fn* functions. +!$omp parallel + call sub +!$omp end parallel +end Index: gcc/testsuite/gfortran.dg/gomp/pr84116.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/gomp/pr84116.f90 b/gcc/testsuite/gfortran.dg/gomp/pr84116.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/gomp/pr84116.f90 (revision 259627) @@ -0,0 +1,12 @@ +! PR fortran/84116 +! { dg-do compile } + +program pr84116 + integer :: i, j + !$omp simd linear ((i)) ! { dg-error "Syntax error" } + do i = 1, 2 + end do + !$omp simd linear () ! { dg-error "Syntax error" } + do j = 1, 2 + end do +end Index: gcc/testsuite/gfortran.dg/coarray_45.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/coarray_45.f90 b/gcc/testsuite/gfortran.dg/coarray_45.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/coarray_45.f90 (revision 259627) @@ -0,0 +1,24 @@ +! { dg-do compile } +! { dg-options "-fcoarray=lib -lcaf_single " } +! +! Test the fix for PR83076 +! +module m + type t + integer, pointer :: z + end type + type(t) :: ptr +contains + function g(x) + type(t) :: x[*] + if (associated (x%z, ptr%z)) deallocate (x%z) ! This used to ICE with -fcoarray=lib + end +end module + + use m +contains + function f(x) + type(t) :: x[*] + if (associated (x%z, ptr%z)) deallocate (x%z) + end +end Index: gcc/testsuite/gfortran.dg/goacc/pr84963.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/goacc/pr84963.f90 b/gcc/testsuite/gfortran.dg/goacc/pr84963.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/goacc/pr84963.f90 (revision 259627) @@ -0,0 +1,7 @@ +! PR ipa/84963 +! { dg-options "-O2" } + +program p + print *, sin([1.0, 2.0]) + print *, cos([1.0, 2.0]) +end Index: gcc/testsuite/gfortran.dg/select_type_40.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/select_type_40.f90 b/gcc/testsuite/gfortran.dg/select_type_40.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/select_type_40.f90 (revision 259627) @@ -0,0 +1,9 @@ +! { dg-do compile } +! { dg-additional-options "-fdefault-integer-8" } +! PR 78238 - this used to cause an ICE. +! Original test cae by Gerhard Steinmetz +class(*), allocatable :: q +select type (x => q) +type is (real) +end select +end Index: gcc/testsuite/gfortran.dg/array_constructor_52.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/array_constructor_52.f90 b/gcc/testsuite/gfortran.dg/array_constructor_52.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/array_constructor_52.f90 (revision 259627) @@ -0,0 +1,11 @@ +! { dg-do run } +! PR 84931 - long array constructors with type conversion were not +! handled correctly. +program test + implicit none + integer, parameter :: n = 2**16 + real, dimension(n) :: y + integer :: i + y = (/ (1, i=1, n) /) + if (y(2) /= 1) stop 1 +end program test Index: gcc/testsuite/gfortran.dg/pr85520.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr85520.f90 b/gcc/testsuite/gfortran.dg/pr85520.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr85520.f90 (revision 259627) @@ -0,0 +1,7 @@ +! { dg-do run } +! PR fortran/85520 +! Original code from Gerhard Steinmetz +program p + character(-huge(1)) :: c = ' ' + if (len(c) /= 0) stop 1 +end Index: gcc/testsuite/gfortran.dg/internal_references_1.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/internal_references_1.f90 b/gcc/testsuite/gfortran.dg/internal_references_1.f90 --- a/gcc/testsuite/gfortran.dg/internal_references_1.f90 (revision 257042) +++ b/gcc/testsuite/gfortran.dg/internal_references_1.f90 (revision 259627) @@ -11,7 +11,7 @@ implicit none contains - subroutine p (i) ! { dg-error "is already defined" } + subroutine p (i) ! { dg-error "(1)" } integer :: i end subroutine @@ -22,11 +22,11 @@ ! ! PR25124 - would happily ignore the declaration of foo in the main program. program test -real :: foo, x ! { dg-error "explicit interface and must not have attributes declared" } +real :: foo, x x = bar () ! This is OK because it is a regular reference. x = foo () contains - function foo () ! { dg-error "explicit interface and must not have attributes declared" } + function foo () ! { dg-error "explicit interface from a previous" } foo = 1.0 end function foo function bar () @@ -33,3 +33,4 @@ bar = 1.0 end function bar end program test + Index: gcc/testsuite/gfortran.dg/bad_automatic_objects_1.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/bad_automatic_objects_1.f90 b/gcc/testsuite/gfortran.dg/bad_automatic_objects_1.f90 --- a/gcc/testsuite/gfortran.dg/bad_automatic_objects_1.f90 (revision 257042) +++ b/gcc/testsuite/gfortran.dg/bad_automatic_objects_1.f90 (revision 259627) @@ -5,16 +5,18 @@ ! ! Contributed by Joost VandeVondele ! +! Error message update with patch for PR fortran/83633 +! module foo integer :: i end module foo module bar use foo - integer, dimension (i) :: j ! { dg-error "must have constant shape" } + integer, dimension (i) :: j ! { dg-error "array with nonconstant bounds" } character (len = i) :: c1 ! { dg-error "must have constant character length" } end module bar program foobar use foo - integer, dimension (i) :: k ! { dg-error "must have constant shape" } + integer, dimension (i) :: k ! { dg-error "array with nonconstant bounds" } character (len = i) :: c2 ! { dg-error "must have constant character length" } end program foobar Index: gcc/testsuite/gfortran.dg/deallocate_error_4.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/deallocate_error_4.f90 b/gcc/testsuite/gfortran.dg/deallocate_error_4.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/deallocate_error_4.f90 (revision 259627) @@ -0,0 +1,10 @@ +! { dg-do compile } +! PR fortran/82994 +! Code contributed by Gerhard Steinmetz +program p + type t + end type + class(t) :: x ! { dg-error "must be dummy, allocatable or pointer" } + allocate (x) ! { dg-error "neither a data pointer nor an allocatable" } + deallocate (x) ! { dg-error "not a nonprocedure pointer nor an allocatable" } +end Index: gcc/testsuite/gfortran.dg/statement_function_2.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/statement_function_2.f90 b/gcc/testsuite/gfortran.dg/statement_function_2.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/statement_function_2.f90 (revision 259627) @@ -0,0 +1,26 @@ +! { dg-do compile } +! PR fortran/54223 +subroutine r(d) + implicit none + integer, optional :: d + integer :: h, q + q(d) = d + 1 ! statement function statement + h = q(d) +end subroutine r + +subroutine s(x) + implicit none + integer, optional :: x + integer :: g, z + g(x) = x + 1 ! statement function statement + z = g() ! { dg-error "Missing actual argument" } +end subroutine s + +subroutine t(a) + implicit none + integer :: a + integer :: f, y + f(a) = a + 1 ! statement function statement + y = f() ! { dg-error "Missing actual argument" } +end subroutine t +! { dg-prune-output " Obsolescent feature" } Index: gcc/testsuite/gfortran.dg/shape_9.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/shape_9.f90 b/gcc/testsuite/gfortran.dg/shape_9.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/shape_9.f90 (revision 259627) @@ -0,0 +1,16 @@ +! { dg-do run } +! { dg-require-effective-target lto } +! { dg-options "-flto" } +! Check that there are no warnings with LTO for a KIND argument. +! +program test + implicit none + real, allocatable :: x(:,:) + + allocate(x(2,5)) + if (any(shape(x) /= [ 2, 5 ])) call abort + if (any(shape(x,kind=1) /= [ 2, 5 ])) call abort + if (any(shape(x,kind=2) /= [ 2, 5 ])) call abort + if (any(shape(x,kind=4) /= [ 2, 5 ])) call abort + if (any(shape(x,kind=8) /= [ 2, 5 ])) call abort + end program test Index: gcc/testsuite/gfortran.dg/class_67.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/class_67.f90 b/gcc/testsuite/gfortran.dg/class_67.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/class_67.f90 (revision 259627) @@ -0,0 +1,55 @@ +! { dg-do run } +! +! Test the fix for PR78990 in which the scalarization of the assignment +! in the main program failed for two reasons: (i) The conversion of 'v1' +! into a class actual was being done after the call to 'return_t1', giving +! rise to the ICE reported in comment #1; and (ii) The 'info' descriptor, +! required for scalarization was not set, which gave rise to the ICE noted +! by the contributor. +! +! Contributed by Chris Macmackin +! +module test_type + implicit none + + type t1 + integer :: i + contains + procedure :: assign + generic :: assignment(=) => assign + end type t1 + +contains + + elemental subroutine assign(this,rhs) + class(t1), intent(inout) :: this + class(t1), intent(in) :: rhs + this%i = rhs%i + end subroutine assign + + function return_t1(arg) + class(t1), dimension(:), intent(in) :: arg + class(t1), dimension(:), allocatable :: return_t1 + allocate(return_t1(size(arg)), source=arg) + end function return_t1 + + function return_t1_p(arg) + class(t1), dimension(:), intent(in), target :: arg + class(t1), dimension(:), pointer :: return_t1_p + return_t1_p => arg + end function return_t1_p +end module test_type + +program test + use test_type + implicit none + + type(t1), dimension(3) :: v1, v2 + v1%i = [1,2,3] + v2 = return_t1(v1) + if (any (v2%i .ne. v1%i)) call abort + + v1%i = [4,5,6] + v2 = return_t1_p(v1) + if (any (v2%i .ne. v1%i)) call abort +end program test Index: gcc/testsuite/gfortran.dg/realloc_on_assign_29.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_29.f90 b/gcc/testsuite/gfortran.dg/realloc_on_assign_29.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_29.f90 (revision 259627) @@ -0,0 +1,13 @@ +! { dg-do run } +! PR fortran/81116 +! The assignment was broken due to a missing temporary. +! Original test case by Clive Page. + +program test10 + implicit none + character(:), allocatable :: string + ! + string = '1234567890' + string = string(1:5) // string(7:) + if (string /= '123457890') STOP 1 +end program test10 Index: gcc/testsuite/gfortran.dg/inline_matmul_22.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_22.f90 b/gcc/testsuite/gfortran.dg/inline_matmul_22.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/inline_matmul_22.f90 (revision 259627) @@ -0,0 +1,44 @@ +! { dg-do compile } +! { dg-additional-options "-ffrontend-optimize" } +! PR 84270 - this used to be rejected. +! Test case by Michael Weinert + +module fp_precision + + integer, parameter :: fp = selected_real_kind(13) + +end module fp_precision + + subroutine lhcal(nrot,orth,ngpts,vgauss,vr_0) + + use fp_precision ! floating point precision + + implicit none + +!---> rotation matrices and rotations (input) + integer, intent(in) :: nrot +! real(kind=fp), intent(in) :: orth(3,3,nrot) ! fine at all -O + real(kind=fp), intent(in) :: orth(3,3,*) + +!---> gaussian integration points + integer, intent(in) :: ngpts + real(kind=fp), intent(in) :: vgauss(3,*) + +!---> output results + real(kind=fp), intent(out) :: vr_0(3) + + real(kind=fp) :: v(3),vr(3) + integer :: n,nn + + vr_0 = 0 + do nn=1,ngpts + v(:) = vgauss(:,nn) +!---> apply rotations + do n=2,nrot + vr = matmul( orth(:,:,n), v ) + vr_0 = vr_0 + vr + enddo + enddo + + return + end subroutine lhcal Index: gcc/testsuite/gfortran.dg/automatic_module_variable.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/automatic_module_variable.f90 b/gcc/testsuite/gfortran.dg/automatic_module_variable.f90 --- a/gcc/testsuite/gfortran.dg/automatic_module_variable.f90 (revision 257042) +++ b/gcc/testsuite/gfortran.dg/automatic_module_variable.f90 (revision 259627) @@ -1,10 +1,12 @@ ! { dg-do compile } ! Tests fix for PR15976 ! +! Error message update with patch for PR fortran/83633 +! module sd integer, parameter :: n = 20 integer :: i(n) - integer :: j(m) ! { dg-error "must have constant shape" } + integer :: j(m) ! { dg-error "array with nonconstant bounds" } integer, pointer :: p(:) integer, allocatable :: q(:) contains Index: gcc/testsuite/gfortran.dg/pr65453.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr65453.f90 b/gcc/testsuite/gfortran.dg/pr65453.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr65453.f90 (revision 259627) @@ -0,0 +1,8 @@ +! { dg-do compile } +! PR fortran/65453 +! Contributed by Tobias Burnus +procedure() :: foo ! { dg-error "(1)" } + contains + subroutine foo() ! { dg-error "clashes with procedure" } + end +end Index: gcc/testsuite/gfortran.dg/pr51434.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr51434.f90 b/gcc/testsuite/gfortran.dg/pr51434.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr51434.f90 (revision 259627) @@ -0,0 +1,19 @@ +! { dg-do run } +! PR fortran/51434 +module foo + implicit none + integer, parameter :: n = 5 + character(len=1), parameter :: s(n) = 'a' + type :: a + integer :: m = n + character(len=1):: t(n) = transfer('abcde ', s) + end type a +end module foo + +program bar + use foo + implicit none + type(a) c + if (c%m /= n) stop 1 + if (any(c%t /= ['a', 'b', 'c', 'd', 'e'])) stop 2 +end program bar Index: gcc/testsuite/gfortran.dg/coarray_8.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/coarray_8.f90 b/gcc/testsuite/gfortran.dg/coarray_8.f90 --- a/gcc/testsuite/gfortran.dg/coarray_8.f90 (revision 257042) +++ b/gcc/testsuite/gfortran.dg/coarray_8.f90 (revision 259627) @@ -145,7 +145,7 @@ subroutine tfgh() integer :: i(2) - DATA i/(i, i=1,2)/ ! { dg-error "Expected PARAMETER symbol" } + DATA i/(i, i=1,2)/ ! { dg-error "Syntax error in DATA" } do i = 1, 5 ! { dg-error "cannot be an array" } end do ! { dg-error "Expecting END SUBROUTINE" } end subroutine tfgh @@ -153,7 +153,7 @@ subroutine tfgh2() integer, save :: x[*] integer :: i(2) - DATA i/(x, x=1,2)/ ! { dg-error "Expected PARAMETER symbol" } + DATA i/(x, x=1,2)/ ! { dg-error "Syntax error in DATA" } do x = 1, 5 ! { dg-error "cannot be a coarray" } end do ! { dg-error "Expecting END SUBROUTINE" } end subroutine tfgh2 Index: gcc/testsuite/gfortran.dg/dec_parameter_1.f =================================================================== diff --git a/gcc/testsuite/gfortran.dg/dec_parameter_1.f b/gcc/testsuite/gfortran.dg/dec_parameter_1.f --- a/gcc/testsuite/gfortran.dg/dec_parameter_1.f (revision 257042) +++ b/gcc/testsuite/gfortran.dg/dec_parameter_1.f (revision 259627) @@ -22,7 +22,6 @@ two = 2.0d0 x = two * pi_1 * f_1 * t y = two * pi_2 * f_2 * t - z = two * pi_3 * f_3 * t return end subroutine Index: gcc/testsuite/gfortran.dg/deallocate_error_3.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/deallocate_error_3.f90 b/gcc/testsuite/gfortran.dg/deallocate_error_3.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/deallocate_error_3.f90 (revision 259627) @@ -0,0 +1,9 @@ +! { dg-do compile } +! PR fortran/82994 +! Code contributed by Gerhard Steinmetz +program p + type t + end type + class(t) :: x ! { dg-error "must be dummy, allocatable or pointer" } + deallocate (x) ! { dg-error "not a nonprocedure pointer nor an allocatable" } +end Index: gcc/testsuite/gfortran.dg/statement_function_1.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/statement_function_1.f90 b/gcc/testsuite/gfortran.dg/statement_function_1.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/statement_function_1.f90 (revision 259627) @@ -0,0 +1,24 @@ +! { dg-do compile } +! PR fortran/84276 + subroutine stepns(hh, h, s, w) + real, intent(inout) :: h, hh, s + real, intent(out) :: w + real :: qofs + integer i + qofs(s) = s + w = qofs(hh + h) + i = 42 + w = qofs(i) ! { dg-error "Type mismatch in argument" } + end subroutine stepns + + subroutine step(hh, h, s, w) + real, intent(inout) :: h, hh, s + real, intent(out) :: w + real :: qofs + integer i + qofs(s, i) = i * s + i = 42 + w = qofs(hh, i) + w = qofs(i = i, s = hh) ! { dg-error "invalid in a statement function" } + end subroutine step +! { dg-prune-output " Obsolescent feature" } Index: gcc/testsuite/gfortran.dg/data_substring.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/data_substring.f90 b/gcc/testsuite/gfortran.dg/data_substring.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/data_substring.f90 (revision 259627) @@ -0,0 +1,6 @@ +! { dg-do compile } +! PR fortran/30792 +character string*1025 +integer i +data (string(i:i),i=1,1025)/1025*'?'/ ! { dg-error "Invalid substring" } +end Index: gcc/testsuite/gfortran.dg/dec_parameter_2.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/dec_parameter_2.f90 b/gcc/testsuite/gfortran.dg/dec_parameter_2.f90 --- a/gcc/testsuite/gfortran.dg/dec_parameter_2.f90 (revision 257042) +++ b/gcc/testsuite/gfortran.dg/dec_parameter_2.f90 (revision 259627) @@ -21,7 +21,6 @@ two = 2.0d0 x = two * pi_1 * f_1 * t y = two * pi_2 * f_2 * t - z = two * pi_3 * f_3 * t return end subroutine Index: gcc/testsuite/gfortran.dg/pr83939.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr83939.f90 b/gcc/testsuite/gfortran.dg/pr83939.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr83939.f90 (revision 259627) @@ -0,0 +1,12 @@ +! { dg-do compile } +elemental function f() result(s) ! { dg-error "shall not have an ALLOCATABLE or POINTER" } + allocatable s + allocate(s) + s = 3.5 +end function + +elemental function g() result(s) ! { dg-error "shall not have an ALLOCATABLE or POINTER" } + pointer s + allocate(s) + s = 3.5 +end function Index: gcc/testsuite/gfortran.dg/pr84734.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr84734.f90 b/gcc/testsuite/gfortran.dg/pr84734.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr84734.f90 (revision 259627) @@ -0,0 +1,4 @@ +! { dg-do compile } +! PR fortran/84734 + integer :: b(huge(1_8)+1_8) = 0 ! { dg-error "Arithmetic overflow" } + end Index: gcc/testsuite/gfortran.dg/inquire_19.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/inquire_19.f90 b/gcc/testsuite/gfortran.dg/inquire_19.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/inquire_19.f90 (revision 259627) @@ -0,0 +1,13 @@ +! { dg-do run } +! PR84506 INQUIRE(pos=) always sets pos=0 with -fdefault-integer-8 +program TestInquire + implicit none + integer(8) :: iUnit + integer(8) :: iPos + open(newunit=iunit, file='output.txt', access='stream', status='replace') + write(iUnit) 'TEXT' + inquire(iUnit, pos=iPos) + close(iUnit, status='delete') + !print *, iPos + if (iPos.ne.5) stop 1 +end program TestInquire Index: gcc/testsuite/gfortran.dg/pr78741.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr78741.f90 b/gcc/testsuite/gfortran.dg/pr78741.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr78741.f90 (revision 259627) @@ -0,0 +1,16 @@ +! { dg-do compile } +! PR fortran/78741 +! Contributed by Gerhard Steinmetz +subroutine s(n, x) + integer :: n + character(n) :: x + character, pointer :: z(:) + x = 'a' + return +entry g(n, x) ! { dg-error "is already defined" } + x = 'b' +contains + subroutine g ! { dg-error "(1)" } + z(1) = x(1:1) + end +end Index: gcc/testsuite/gfortran.dg/statement_function_3.f =================================================================== diff --git a/gcc/testsuite/gfortran.dg/statement_function_3.f b/gcc/testsuite/gfortran.dg/statement_function_3.f new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/statement_function_3.f (revision 259627) @@ -0,0 +1,15 @@ +! { dg-do compile } +! PR fortran/35299 + subroutine phtod(e,n,i,h) + dimension e(n) + hstar(e,b)=b**.4*((1.25*fun(-e/40)+.18)) ! { dg-error "must be scalar" } + a = 1. + h = hstar(e(i-1), a) + end + + function fun(a) + real a(*) + fun = 42 + end +! { dg-prune-output " Obsolescent feature" } + Index: gcc/testsuite/gfortran.dg/interface_41.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/interface_41.f90 b/gcc/testsuite/gfortran.dg/interface_41.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/interface_41.f90 (revision 259627) @@ -0,0 +1,19 @@ +! { dg-do compile } +! PR fortran/85001 +! Contributed by Gerhard Steinmetz. +program p + type t + end type + call s +contains + real function f(x) + class(t) :: x + dimension :: x(:) + f = 1.0 + end + subroutine s + type(t) :: x(2) + real :: z + z = f(x) ! { dg-error "Rank mismatch in argument" } + end +end Index: gcc/testsuite/gfortran.dg/explicit_shape_1.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/explicit_shape_1.f90 b/gcc/testsuite/gfortran.dg/explicit_shape_1.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/explicit_shape_1.f90 (revision 259627) @@ -0,0 +1,7 @@ +! { dg-do compile } +! PR fortran/83633 +! Original testcase by Nathan T. Weeks +! +integer :: A(command_argument_count()) = 1 ! { dg-error "nonconstant bounds" } +write (*,*) A +end Index: gcc/testsuite/gfortran.dg/assumed_charlen_parameter.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/assumed_charlen_parameter.f90 b/gcc/testsuite/gfortran.dg/assumed_charlen_parameter.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/assumed_charlen_parameter.f90 (revision 259627) @@ -0,0 +1,9 @@ +! { dg-do compile } +! PR fortran/82049 +! Original code contributed by John Harper +program ice ! f2003 + implicit none + character(*), parameter:: a = 'ice', b = '*' + character(*), parameter:: c(2) = [character(len(a)) :: a, b] + print "(2A4)",adjustr(c) +end program ice Index: gcc/testsuite/gfortran.dg/pr70409.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr70409.f90 b/gcc/testsuite/gfortran.dg/pr70409.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr70409.f90 (revision 259627) @@ -0,0 +1,23 @@ +! { dg-do run } +! PR fortran/70409 +! Contriubted by Harald Anlauf +program foo + integer, parameter :: huge_1 = huge(0_1) + character( huge_1 ), parameter :: x = 'abc' + character( huge(0_1) ), parameter :: y = 'abc' + character( huge(0_1)+0 ), parameter :: z = 'abcdef' + character( huge(0_1) ) :: a = 'abc' + integer, parameter :: huge_2 = huge(0_2) + character( huge_2 ), parameter :: u = 'abc' + character( huge(0_2) ), parameter :: v = 'abc' + character(int(huge(0_2),4)), parameter :: w = 'abcdef' + character( huge(0_2) ) :: b = 'abc' + if (len(x) /= huge_1) stop 1 + if (len(y) /= huge_1) stop 2 + if (len(z) /= huge_1) stop 3 + if (len(a) /= huge_1) stop 4 + if (len(u) /= huge_2) stop 5 + if (len(v) /= huge_2) stop 6 + if (len(w) /= huge_2) stop 7 + if (len(b) /= huge_2) stop 8 +end program foo Index: gcc/testsuite/gfortran.dg/coarray_46.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/coarray_46.f90 b/gcc/testsuite/gfortran.dg/coarray_46.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/coarray_46.f90 (revision 259627) @@ -0,0 +1,17 @@ +! { dg-do compile } +! { dg-options "-fcoarray=lib -lcaf_single" } +! +! Test the fix for PR83319 +! +module foo_module + implicit none + type foo + integer, allocatable :: i(:) + end type +end module + + use foo_module + implicit none + type(foo), save :: bar[*] + allocate(bar%i(1)) ! Used to ICE here. +end Index: gcc/testsuite/gfortran.dg/pr77414.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr77414.f90 b/gcc/testsuite/gfortran.dg/pr77414.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr77414.f90 (revision 259627) @@ -0,0 +1,9 @@ +! { dg-do compile } +! PR fortran/77414 +subroutine a(x) ! { dg-error "(1)" } + character(*) :: x + contains + subroutine a(x) ! { dg-error " is already defined at" } + character(*) :: x + end subroutine a +end subroutine a Index: gcc/testsuite/gfortran.dg/implied_do_2.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/implied_do_2.f90 b/gcc/testsuite/gfortran.dg/implied_do_2.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/implied_do_2.f90 (revision 259627) @@ -0,0 +1,7 @@ +! { dg-do compile } +! PR fortran/56667 +program error_message + implicit none + integer :: ir + write(*,*) ( ir, ir = 1,10 ! { dg-error "Expected a right parenthesis" } +end program error_message Index: gcc/testsuite/gfortran.dg/select_type_41.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/select_type_41.f90 b/gcc/testsuite/gfortran.dg/select_type_41.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/select_type_41.f90 (revision 259627) @@ -0,0 +1,30 @@ +! { dg-do compile } +! { dg-options "-O2" } +! +! Tests the fix for PR80965 in which the use of the name 'loc' +! for the dummy argument of 'xyz' caused an ICE. If the module +! was used, the error "DUMMY attribute conflicts with INTRINSIC +! attribute in ‘loc’ at (1)" was emitted. Note that although 'loc' +! is a GNU extension and so can be over-ridden, this is not very +! good practice. +! +! Contributed by David Sagan +! +module mode3_mod +contains + subroutine xyz (loc) + implicit none + class(*) :: loc + real x(6) + integer ix_use + select type (loc) + type is (integer) + x = 0 + print *, "integer" + type is (real) + ix_use = 0 + print *, "real" + end select + end subroutine xyz +end module mode3_mod + Index: gcc/testsuite/gfortran.dg/inquire_18.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/inquire_18.f90 b/gcc/testsuite/gfortran.dg/inquire_18.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/inquire_18.f90 (revision 259627) @@ -0,0 +1,11 @@ +! { dg-do run } +! PR84412 Wrong "Inquire statement identifies an internal file" error +program bug + implicit none + integer :: i + character(len=1) :: s + write (s,'(i1)') 0 + open(newUnit=i,file='inquire_18.txt',status='unknown') + inquire(unit=i) + close(i, status="delete") +end program bug Index: gcc/testsuite/gfortran.dg/pr64124.f90 =================================================================== diff --git a/gcc/testsuite/gfortran.dg/pr64124.f90 b/gcc/testsuite/gfortran.dg/pr64124.f90 new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gfortran.dg/pr64124.f90 (revision 259627) @@ -0,0 +1,5 @@ +! { dg-do compile } +! PR fortran/64124.f90 + character(len=kind(1)) x + integer(len(x)) y + end Index: gcc/testsuite/gcc.c-torture/execute/20180131-1.c =================================================================== diff --git a/gcc/testsuite/gcc.c-torture/execute/20180131-1.c b/gcc/testsuite/gcc.c-torture/execute/20180131-1.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.c-torture/execute/20180131-1.c (revision 259627) @@ -0,0 +1,28 @@ +/* PR rtl-optimization/84071 */ +/* Reported by Wilco */ + +extern void abort (void); + +typedef union +{ + signed short ss; + unsigned short us; + int x; +} U; + +int f(int x, int y, int z, int a, U u) __attribute__((noclone, noinline)); + +int f(int x, int y, int z, int a, U u) +{ + return (u.ss <= 0) + u.us; +} + +int main (void) +{ + U u = { .ss = -1 }; + + if (f (0, 0, 0, 0, u) != (1 << sizeof (short) * 8)) + abort (); + + return 0; +} Index: gcc/testsuite/gcc.c-torture/execute/pr82210.c =================================================================== diff --git a/gcc/testsuite/gcc.c-torture/execute/pr82210.c b/gcc/testsuite/gcc.c-torture/execute/pr82210.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.c-torture/execute/pr82210.c (revision 259627) @@ -0,0 +1,26 @@ +/* PR c/82210 */ + +void +foo (int size) +{ + int i; + struct S { + __attribute__((aligned (16))) struct T { short c; } a[size]; + int b[size]; + } s; + + for (i = 0; i < size; i++) + s.a[i].c = 0x1234; + for (i = 0; i < size; i++) + s.b[i] = 0; + for (i = 0; i < size; i++) + if (s.a[i].c != 0x1234 || s.b[i] != 0) + __builtin_abort (); +} + +int +main () +{ + foo (15); + return 0; +} Index: gcc/testsuite/gcc.c-torture/execute/pr84524.c =================================================================== diff --git a/gcc/testsuite/gcc.c-torture/execute/pr84524.c b/gcc/testsuite/gcc.c-torture/execute/pr84524.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.c-torture/execute/pr84524.c (revision 259627) @@ -0,0 +1,41 @@ +/* PR target/84524 */ + +__attribute__((noinline,noclone)) void +foo (unsigned short *x) +{ + unsigned short i, v; + unsigned char j; + for (i = 0; i < 256; i++) + { + v = i << 8; + for (j = 0; j < 8; j++) + if (v & 0x8000) + v = (v << 1) ^ 0x1021; + else + v = v << 1; + x[i] = v; + } +} + +int +main () +{ + unsigned short a[256]; + + foo (a); + for (int i = 0; i < 256; i++) + { + unsigned short v = i << 8; + for (int j = 0; j < 8; j++) + { + asm volatile ("" : "+r" (v)); + if (v & 0x8000) + v = (v << 1) ^ 0x1021; + else + v = v << 1; + } + if (a[i] != v) + __builtin_abort (); + } + return 0; +} Index: gcc/testsuite/gcc.c-torture/execute/pr84748.c =================================================================== diff --git a/gcc/testsuite/gcc.c-torture/execute/pr84748.c b/gcc/testsuite/gcc.c-torture/execute/pr84748.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.c-torture/execute/pr84748.c (revision 259627) @@ -0,0 +1,34 @@ +/* { dg-require-effective-target int128 } */ + +typedef unsigned __int128 u128; + +int a, c, d; +u128 b; + +unsigned long long g0, g1; + +void +store (unsigned long long a0, unsigned long long a1) +{ + g0 = a0; + g1 = a1; +} + +void +foo (void) +{ + b += a; + c = d != 84347; + b /= c; + u128 x = b; + store (x >> 0, x >> 64); +} + +int +main (void) +{ + foo (); + if (g0 != 0 || g1 != 0) + __builtin_abort (); + return 0; +} Index: gcc/testsuite/gcc.c-torture/execute/20180226-1.c =================================================================== diff --git a/gcc/testsuite/gcc.c-torture/execute/20180226-1.c b/gcc/testsuite/gcc.c-torture/execute/20180226-1.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.c-torture/execute/20180226-1.c (revision 259627) @@ -0,0 +1,31 @@ +/* PR rtl-optimization/83496 */ +/* Reported by Hauke Mehrtens */ + +extern void abort (void); + +typedef unsigned long mp_digit; + +typedef struct { int used, alloc, sign; mp_digit *dp; } mp_int; + +int mytest(mp_int *a, mp_digit b) __attribute__((noclone, noinline)); + +int mytest(mp_int *a, mp_digit b) +{ + if (a->sign == 1) + return -1; + if (a->used > 1) + return 1; + if (a->dp[0] > b) + return 1; + if (a->dp[0] < b) + return -1; + return 0; +} + +int main (void) +{ + mp_int i = { 2, 0, -1 }; + if (mytest (&i, 0) != 1) + abort (); + return 0; +} Index: gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x =================================================================== diff --git a/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x b/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x --- a/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x (revision 257042) +++ b/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x (revision 259627) @@ -9,14 +9,14 @@ # loop through all the options foreach option $option_list { - file delete -force dump1 - file mkdir dump1 + file delete -force $tmpdir/dump1 + file mkdir $tmpdir/dump1 c-torture-compile $src "$option $options -dumpbase dump1/$dumpbase -DMASK=1 -x c --param ggc-min-heapsize=1 -fdump-ipa-all -fdump-rtl-all -fdump-tree-all -fdump-noaddr" - file delete -force dump2 - file mkdir dump2 + file delete -force $tmpdir/dump2 + file mkdir $tmpdir/dump2 c-torture-compile $src "$option $options -dumpbase dump2/$dumpbase -DMASK=2 -x c -fdump-ipa-all -fdump-rtl-all -fdump-tree-all -fdump-noaddr" - foreach dump1 [lsort [glob -nocomplain dump1/*]] { - regsub dump1/ $dump1 dump2/ dump2 + foreach dump1 [lsort [glob -nocomplain $tmpdir/dump1/*]] { + set dump2 "$tmpdir/dump2/[file tail $dump1]" set dumptail "gcc.c-torture/unsorted/[file tail $dump1]" regsub {\.\d+((t|r|i)\.[^.]+)$} $dumptail {.*\1} dumptail set tmp [ diff "$dump1" "$dump2" ] @@ -29,8 +29,8 @@ } } } - file delete -force dump1 - file delete -force dump2 + file delete -force $tmpdir/dump1 + file delete -force $tmpdir/dump2 } dump_compare $src $options Index: gcc/testsuite/gcc.c-torture/compile/pr82096.c =================================================================== diff --git a/gcc/testsuite/gcc.c-torture/compile/pr82096.c b/gcc/testsuite/gcc.c-torture/compile/pr82096.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.c-torture/compile/pr82096.c (revision 259627) @@ -0,0 +1,11 @@ +/* { dg-require-effective-target arm_arch_v5t_ok { target arm*-*-* } } */ +/* { dg-skip-if "Do not combine float-abi values" { arm*-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=soft" } } */ +/* { dg-additional-options "-march=armv5t -mthumb -mfloat-abi=soft" { target arm*-*-* } } */ + +static long long AL[24]; + +int +check_ok (void) +{ + return (__sync_bool_compare_and_swap (AL+1, 0x200000003ll, 0x1234567890ll)); +} Index: gcc/testsuite/gcc.c-torture/compile/pr84425.c =================================================================== diff --git a/gcc/testsuite/gcc.c-torture/compile/pr84425.c b/gcc/testsuite/gcc.c-torture/compile/pr84425.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.c-torture/compile/pr84425.c (revision 259627) @@ -0,0 +1,17 @@ +/* PR ipa/84425 */ + +void bar (int); + +void +foo (int x) +{ + if (x < 5) + bar (x); +} + +__attribute__((optimize(0))) void +bar (int x) +{ + if (x > 10) + foo (x); +} Index: gcc/testsuite/gnat.dg/dispatch1.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/dispatch1.adb b/gcc/testsuite/gnat.dg/dispatch1.adb deleted file mode 10644 --- a/gcc/testsuite/gnat.dg/dispatch1.adb (revision 257042) +++ /dev/null (nonexistent) @@ -1,9 +0,0 @@ --- { dg-do run } - -with dispatch1_p; use dispatch1_p; -procedure dispatch1 is - O : DT_I1; - Ptr : access I1'Class; -begin - Ptr := new I1'Class'(I1'Class (O)); -end; Index: gcc/testsuite/gnat.dg/generic_dispatch_p.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/generic_dispatch_p.adb b/gcc/testsuite/gnat.dg/generic_dispatch_p.adb deleted file mode 10644 --- a/gcc/testsuite/gnat.dg/generic_dispatch_p.adb (revision 257042) +++ /dev/null (nonexistent) @@ -1,7 +0,0 @@ -package body generic_dispatch_p is - function Constructor (I : not null access Integer) return DT is - R : DT; - begin - return R; - end Constructor; -end; Index: gcc/testsuite/gnat.dg/generic_dispatch_p.ads =================================================================== diff --git a/gcc/testsuite/gnat.dg/generic_dispatch_p.ads b/gcc/testsuite/gnat.dg/generic_dispatch_p.ads deleted file mode 10644 --- a/gcc/testsuite/gnat.dg/generic_dispatch_p.ads (revision 257042) +++ /dev/null (nonexistent) @@ -1,13 +0,0 @@ -with Ada.Tags.Generic_Dispatching_Constructor; -package generic_dispatch_p is - type Iface is interface; - function Constructor (I : not null access Integer) return Iface is abstract; - function Dispatching_Constructor - is new Ada.Tags.Generic_Dispatching_Constructor - (T => Iface, - Parameters => Integer, - Constructor => Constructor); - type DT is new Iface with null record; - overriding - function Constructor (I : not null access Integer) return DT; -end; Index: gcc/testsuite/gnat.dg/dispatch1_p.ads =================================================================== diff --git a/gcc/testsuite/gnat.dg/dispatch1_p.ads b/gcc/testsuite/gnat.dg/dispatch1_p.ads deleted file mode 10644 --- a/gcc/testsuite/gnat.dg/dispatch1_p.ads (revision 257042) +++ /dev/null (nonexistent) @@ -1,4 +0,0 @@ -package dispatch1_p is - type I1 is interface; - type DT_I1 is new I1 with null record; -end; Index: gcc/testsuite/gnat.dg/dispatch2.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/dispatch2.adb b/gcc/testsuite/gnat.dg/dispatch2.adb deleted file mode 10644 --- a/gcc/testsuite/gnat.dg/dispatch2.adb (revision 257042) +++ /dev/null (nonexistent) @@ -1,10 +0,0 @@ --- { dg-do run } - -with dispatch2_p; use dispatch2_p; -procedure dispatch2 is - Obj : Object_Ptr := new Object; -begin - if Obj.Get_Ptr /= Obj.Impl_Of then - raise Program_Error; - end if; -end; Index: gcc/testsuite/gnat.dg/generic_dispatch.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/generic_dispatch.adb b/gcc/testsuite/gnat.dg/generic_dispatch.adb deleted file mode 10644 --- a/gcc/testsuite/gnat.dg/generic_dispatch.adb (revision 257042) +++ /dev/null (nonexistent) @@ -1,9 +0,0 @@ --- { dg-do run } - -with generic_dispatch_p; use generic_dispatch_p; -procedure generic_dispatch is - I : aliased Integer := 0; - D : Iface'Class := Dispatching_Constructor (DT'Tag, I'access); -begin - null; -end generic_dispatch; Index: gcc/testsuite/gnat.dg/dispatch2_p.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/dispatch2_p.adb b/gcc/testsuite/gnat.dg/dispatch2_p.adb deleted file mode 10644 --- a/gcc/testsuite/gnat.dg/dispatch2_p.adb (revision 257042) +++ /dev/null (nonexistent) @@ -1,7 +0,0 @@ --- -package body dispatch2_p is - function Impl_Of (Self : access Object) return Object_Ptr is - begin - return Object_Ptr (Self); - end Impl_Of; -end; Index: gcc/testsuite/gnat.dg/dispatch2_p.ads =================================================================== diff --git a/gcc/testsuite/gnat.dg/dispatch2_p.ads b/gcc/testsuite/gnat.dg/dispatch2_p.ads deleted file mode 10644 --- a/gcc/testsuite/gnat.dg/dispatch2_p.ads (revision 257042) +++ /dev/null (nonexistent) @@ -1,8 +0,0 @@ -package dispatch2_p is - type Object is tagged null record; - type Object_Ptr is access all Object'CLASS; --- - function Impl_Of (Self : access Object) return Object_Ptr; - function Get_Ptr (Self : access Object) return Object_Ptr - renames Impl_Of; -end; Index: gcc/testsuite/gnat.dg/generic_disp.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/generic_disp.adb b/gcc/testsuite/gnat.dg/generic_disp.adb new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/generic_disp.adb (revision 259627) @@ -0,0 +1,10 @@ +-- { dg-do run } + +with Generic_Disp_Pkg; use Generic_Disp_Pkg; + +procedure Generic_Disp is + I : aliased Integer := 0; + D : Iface'Class := Dispatching_Constructor (DT'Tag, I'access); +begin + null; +end Generic_Disp; Index: gcc/testsuite/gnat.dg/prot3_pkg.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/prot3_pkg.adb b/gcc/testsuite/gnat.dg/prot3_pkg.adb new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/prot3_pkg.adb (revision 259627) @@ -0,0 +1,17 @@ +package body Prot3_Pkg is + + protected body Prot is + function Fn (J : Short_Integer) return Rec + is + begin + return (V1 => J * J, + V2 => J); + end; + + procedure Foo (J : Short_Integer) is + begin + Val := Fn (J); + end; + end Prot; + +end Prot3_Pkg; Index: gcc/testsuite/gnat.dg/prot3_pkg.ads =================================================================== diff --git a/gcc/testsuite/gnat.dg/prot3_pkg.ads b/gcc/testsuite/gnat.dg/prot3_pkg.ads new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/prot3_pkg.ads (revision 259627) @@ -0,0 +1,16 @@ +package Prot3_Pkg is + + type Rec is record + V1 : Short_Integer; + V2 : Short_Integer; + end record with Volatile_Full_Access; + + protected type Prot is + procedure Foo (J : Short_Integer); + private + Val : Rec; + end Prot; + + P : Prot; + +end Prot3_Pkg; Index: gcc/testsuite/gnat.dg/disp1.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/disp1.adb b/gcc/testsuite/gnat.dg/disp1.adb new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/disp1.adb (revision 259627) @@ -0,0 +1,10 @@ +-- { dg-do run } + +with Disp1_Pkg; use Disp1_Pkg; + +procedure Disp1 is + O : DT_I1; + Ptr : access I1'Class; +begin + Ptr := new I1'Class'(I1'Class (O)); +end; Index: gcc/testsuite/gnat.dg/generic_disp_pkg.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/generic_disp_pkg.adb b/gcc/testsuite/gnat.dg/generic_disp_pkg.adb new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/generic_disp_pkg.adb (revision 259627) @@ -0,0 +1,9 @@ +package body Generic_Disp_Pkg is + + function Constructor (I : not null access Integer) return DT is + R : DT; + begin + return R; + end Constructor; + +end Generic_Disp_Pkg; Index: gcc/testsuite/gnat.dg/object_overflow1.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/object_overflow1.adb b/gcc/testsuite/gnat.dg/object_overflow1.adb --- a/gcc/testsuite/gnat.dg/object_overflow1.adb (revision 257042) +++ b/gcc/testsuite/gnat.dg/object_overflow1.adb (revision 259627) @@ -1,10 +1,12 @@ -- { dg-do compile } +with Interfaces.C; use Interfaces.C; + procedure Object_Overflow1 is procedure Proc (x : Boolean) is begin null; end; - type Arr is array(Long_Integer) of Boolean; + type Arr is array(ptrdiff_t) of Boolean; Obj : Arr; -- { dg-warning "Storage_Error" } begin Index: gcc/testsuite/gnat.dg/generic_disp_pkg.ads =================================================================== diff --git a/gcc/testsuite/gnat.dg/generic_disp_pkg.ads b/gcc/testsuite/gnat.dg/generic_disp_pkg.ads new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/generic_disp_pkg.ads (revision 259627) @@ -0,0 +1,14 @@ +with Ada.Tags.Generic_Dispatching_Constructor; + +package Generic_Disp_Pkg is + type Iface is interface; + function Constructor (I : not null access Integer) return Iface is abstract; + function Dispatching_Constructor + is new Ada.Tags.Generic_Dispatching_Constructor + (T => Iface, + Parameters => Integer, + Constructor => Constructor); + type DT is new Iface with null record; + overriding + function Constructor (I : not null access Integer) return DT; +end Generic_Disp_Pkg; Index: gcc/testsuite/gnat.dg/prot3.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/prot3.adb b/gcc/testsuite/gnat.dg/prot3.adb new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/prot3.adb (revision 259627) @@ -0,0 +1,8 @@ +-- { dg-do run } + +with Prot3_Pkg; use Prot3_Pkg; + +procedure Prot3 is +begin + P.Foo (4); +end; Index: gcc/testsuite/gnat.dg/disp2.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/disp2.adb b/gcc/testsuite/gnat.dg/disp2.adb new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/disp2.adb (revision 259627) @@ -0,0 +1,11 @@ +-- { dg-do run } + +with Disp2_Pkg; use Disp2_Pkg; + +procedure Disp2 is + Obj : Object_Ptr := new Object; +begin + if Obj.Get_Ptr /= Obj.Impl_Of then + raise Program_Error; + end if; +end; Index: gcc/testsuite/gnat.dg/object_overflow2.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/object_overflow2.adb b/gcc/testsuite/gnat.dg/object_overflow2.adb --- a/gcc/testsuite/gnat.dg/object_overflow2.adb (revision 257042) +++ b/gcc/testsuite/gnat.dg/object_overflow2.adb (revision 259627) @@ -1,10 +1,12 @@ -- { dg-do compile } +with Interfaces.C; use Interfaces.C; + procedure Object_Overflow2 is procedure Proc (x : Boolean) is begin null; end; - type Arr is array(0 .. Long_Integer'Last) of Boolean; + type Arr is array(0 .. ptrdiff_t'Last) of Boolean; Obj : Arr; -- { dg-warning "Storage_Error" } begin Index: gcc/testsuite/gnat.dg/object_overflow3.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/object_overflow3.adb b/gcc/testsuite/gnat.dg/object_overflow3.adb --- a/gcc/testsuite/gnat.dg/object_overflow3.adb (revision 257042) +++ b/gcc/testsuite/gnat.dg/object_overflow3.adb (revision 259627) @@ -1,10 +1,12 @@ -- { dg-do compile } +with Interfaces.C; use Interfaces.C; + procedure Object_Overflow3 is procedure Proc (x : Boolean) is begin null; end; - type Arr is array(0 .. Long_Integer'Last) of Boolean; + type Arr is array(0 .. ptrdiff_t'Last) of Boolean; type Rec is record A : Arr; Index: gcc/testsuite/gnat.dg/object_overflow4.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/object_overflow4.adb b/gcc/testsuite/gnat.dg/object_overflow4.adb --- a/gcc/testsuite/gnat.dg/object_overflow4.adb (revision 257042) +++ b/gcc/testsuite/gnat.dg/object_overflow4.adb (revision 259627) @@ -1,14 +1,16 @@ -- { dg-do compile } +with Interfaces.C; use Interfaces.C; + procedure Object_Overflow4 is procedure Proc (x : Integer) is begin null; end; - type Index is new Long_Integer range 0 .. Long_Integer'Last; + type Index_T is new ptrdiff_t range 0 .. ptrdiff_t'Last; - type Arr is array(Index range <>) of Integer; + type Arr is array(Index_T range <>) of Integer; - type Rec (Size: Index := 6) is record -- { dg-warning "Storage_Error" } + type Rec (Size: Index_T := 6) is record -- { dg-warning "Storage_Error" } A: Arr (0..Size); end record; Index: gcc/testsuite/gnat.dg/object_overflow5.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/object_overflow5.adb b/gcc/testsuite/gnat.dg/object_overflow5.adb --- a/gcc/testsuite/gnat.dg/object_overflow5.adb (revision 257042) +++ b/gcc/testsuite/gnat.dg/object_overflow5.adb (revision 259627) @@ -1,14 +1,16 @@ -- { dg-do compile } +with Interfaces.C; use Interfaces.C; + procedure Object_Overflow5 is procedure Proc (c : Character) is begin null; end; - type Index is new Long_Integer range 0 .. Long_Integer'Last; + type Index_T is new ptrdiff_t range 0 .. ptrdiff_t'Last; - type Arr is array(Index range <>) of Character; + type Arr is array(Index_T range <>) of Character; - type Rec (Size: Index := 6) is record -- { dg-warning "Storage_Error" } + type Rec (Size: Index_T := 6) is record -- { dg-warning "Storage_Error" } A: Arr (0..Size); end record; Index: gcc/testsuite/gnat.dg/array11.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/array11.adb b/gcc/testsuite/gnat.dg/array11.adb --- a/gcc/testsuite/gnat.dg/array11.adb (revision 257042) +++ b/gcc/testsuite/gnat.dg/array11.adb (revision 259627) @@ -1,15 +1,17 @@ -- { dg-do compile } +with System; + procedure Array11 is type Rec is null record; - type Ptr is access all Rec; + type Index_T is mod System.Memory_Size; - type Arr1 is array (1..8) of aliased Rec; -- { dg-warning "padded" } - type Arr2 is array (Long_Integer) of aliased Rec; -- { dg-warning "padded" } + type Arr1 is array (1 .. 8) of aliased Rec; -- { dg-warning "padded" } + type Arr2 is array (Index_T) of aliased Rec; -- { dg-warning "padded" } A1 : Arr1; - A2 : Arr2; -- { dg-warning "Storage_Error" } + A2 : Arr2; begin null; Index: gcc/testsuite/gnat.dg/disp1_pkg.ads =================================================================== diff --git a/gcc/testsuite/gnat.dg/disp1_pkg.ads b/gcc/testsuite/gnat.dg/disp1_pkg.ads new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/disp1_pkg.ads (revision 259627) @@ -0,0 +1,6 @@ +package Disp1_Pkg is + + type I1 is interface; + type DT_I1 is new I1 with null record; + +end Disp1_Pkg; Index: gcc/testsuite/gnat.dg/disp2_pkg.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/disp2_pkg.adb b/gcc/testsuite/gnat.dg/disp2_pkg.adb new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/disp2_pkg.adb (revision 259627) @@ -0,0 +1,8 @@ +package body Disp2_Pkg is + + function Impl_Of (Self : access Object) return Object_Ptr is + begin + return Object_Ptr (Self); + end Impl_Of; + +end Disp2_Pkg; Index: gcc/testsuite/gnat.dg/disp2_pkg.ads =================================================================== diff --git a/gcc/testsuite/gnat.dg/disp2_pkg.ads b/gcc/testsuite/gnat.dg/disp2_pkg.ads new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gnat.dg/disp2_pkg.ads (revision 259627) @@ -0,0 +1,11 @@ +package Disp2_Pkg is + + type Object is tagged null record; + type Object_Ptr is access all Object'CLASS; + + function Impl_Of (Self : access Object) return Object_Ptr; + function Get_Ptr (Self : access Object) return Object_Ptr + renames Impl_Of; + +end Disp2_Pkg; + Index: gcc/testsuite/gnat.dg/null_pointer_deref1.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/null_pointer_deref1.adb b/gcc/testsuite/gnat.dg/null_pointer_deref1.adb --- a/gcc/testsuite/gnat.dg/null_pointer_deref1.adb (revision 257042) +++ b/gcc/testsuite/gnat.dg/null_pointer_deref1.adb (revision 259627) @@ -17,5 +17,5 @@ begin Data.all := 1; exception - when Constraint_Error | Storage_Error => null; + when others => null; end; Index: gcc/testsuite/gnat.dg/null_pointer_deref2.adb =================================================================== diff --git a/gcc/testsuite/gnat.dg/null_pointer_deref2.adb b/gcc/testsuite/gnat.dg/null_pointer_deref2.adb --- a/gcc/testsuite/gnat.dg/null_pointer_deref2.adb (revision 257042) +++ b/gcc/testsuite/gnat.dg/null_pointer_deref2.adb (revision 259627) @@ -20,7 +20,7 @@ begin Data.all := 1; exception - when Constraint_Error | Storage_Error => null; + when others => null; end T; begin Index: gcc/testsuite/gcc.dg/pr83985.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr83985.c b/gcc/testsuite/gcc.dg/pr83985.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr83985.c (revision 259627) @@ -0,0 +1,25 @@ +/* PR rtl-optimization/83985 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-mcpu=e300c3 -mtune=e300c3" { target { powerpc*-*-* && ilp32 } } } */ + +long long int v; + +void +foo (int x) +{ + if (x == 0) + return; + + while (v < 2) + { + signed char *a; + v /= x; + a = v == 0 ? (signed char *) &x : (signed char *) &v; + ++*a; + ++v; + } + + while (1) + ; +} Index: gcc/testsuite/gcc.dg/pr84628.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr84628.c b/gcc/testsuite/gcc.dg/pr84628.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr84628.c (revision 259627) @@ -0,0 +1,8 @@ +/* PR ipa/84628 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int f0 (void); +__attribute__((error ("err"))) void f1 (void) { f0 (); f0 (); } +__attribute__((error ("err"))) void f2 (void) { f0 (); f0 (); } +/* { dg-bogus "declared with attribute error" "" { target *-*-* } 0 } */ Index: gcc/testsuite/gcc.dg/cpp/trad/pr69869.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/cpp/trad/pr69869.c b/gcc/testsuite/gcc.dg/cpp/trad/pr69869.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/cpp/trad/pr69869.c (revision 259627) @@ -0,0 +1,8 @@ +/* PR preprocessor/69869 */ +/* { dg-do preprocess } */ +/* { dg-options "-traditional-cpp" } */ + +#define C(a,b)a/**/b +C (foo/,**/) +C (foo/,*) +/* { dg-error "unterminated comment" "" {target "*-*-*"} .-1 } */ Index: gcc/testsuite/gcc.dg/pr83605.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr83605.c b/gcc/testsuite/gcc.dg/pr83605.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr83605.c (revision 259627) @@ -0,0 +1,20 @@ +/* PR tree-optimization/83605 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -ftrapv -fexceptions -fnon-call-exceptions" } */ + +int a; + +int +foo (int x) +{ + int b = a; + { + int c; + int *d = (x == 0) ? &c : &b; + + for (a = 0; a < 2; ++a) + c = (x + b) < a; + + return *d; + } +} Index: gcc/testsuite/gcc.dg/rtl/x86_64/final.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/final.c b/gcc/testsuite/gcc.dg/rtl/x86_64/final.c --- a/gcc/testsuite/gcc.dg/rtl/x86_64/final.c (revision 257042) +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/final.c (revision 259627) @@ -1,5 +1,5 @@ /* { dg-do compile { target { { i?86-*-* x86_64-*-* } && lp64 } } } */ -/* { dg-options "-fdump-rtl-final" } */ +/* { dg-options "-fdwarf2-cfi-asm -fdump-rtl-final" } */ /* Lightly-modified dump of test.c.304r.dwarf2 for x86_64 target, with various NOTE_INSN_CFI deleted by hand for now. */ Index: gcc/testsuite/gcc.dg/pr83986.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr83986.c b/gcc/testsuite/gcc.dg/pr83986.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr83986.c (revision 259627) @@ -0,0 +1,14 @@ +/* PR rtl-optimization/83986 */ +/* { dg-do compile } */ +/* { dg-options "-g -O2 -fsched2-use-superblocks -funwind-tables --param max-pending-list-length=1" } */ + +int v; + +int +foo (int x) +{ + v &= !!v && !!x; + if (v != 0) + foo (0); + return 0; +} Index: gcc/testsuite/gcc.dg/debug/dwarf2/prod-options.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/prod-options.c b/gcc/testsuite/gcc.dg/debug/dwarf2/prod-options.c --- a/gcc/testsuite/gcc.dg/debug/dwarf2/prod-options.c (revision 257042) +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/prod-options.c (revision 259627) @@ -3,9 +3,8 @@ the build not reproducible. Other skipped options could be tested here as well. */ /* { dg-do compile } */ -/* { dg-options "-O2 -gdwarf -dA -fdebug-prefix-map=a=b" } */ -/* { dg-final { scan-assembler "DW_AT_producer: \"GNU C" { target { { { ! *-*-solaris2* } || gas } && { { ! hppa*64*-*-* } && { ! powerpc-ibm-aix* } } } } } } */ -/* { dg-final { scan-assembler "\"GNU C\[^\\n\\r\]+ DW_AT_producer" { target { { *-*-solaris2* && { ! gas } } || { hppa*64*-*-* } } } } } */ +/* { dg-options "-O2 -gdwarf -dA -fno-merge-debug-strings -fdebug-prefix-map=a=b" } */ +/* { dg-final { scan-assembler "\"GNU C\[^\\n\\r\]+ DW_AT_producer" } } */ /* { dg-final { scan-assembler-not "debug-prefix-map" } } */ void func (void) Index: gcc/testsuite/gcc.dg/pr84607.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr84607.c b/gcc/testsuite/gcc.dg/pr84607.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr84607.c (revision 259627) @@ -0,0 +1,16 @@ +/* { dg-do run } */ + +extern void exit(int); +extern void abort(void); +int a[10]; +int foo() +{ + exit (0); + return 0; +} +int main() +{ + if (&a[foo()]) + abort (); + return 0; +} Index: gcc/testsuite/gcc.dg/pr82916.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr82916.c b/gcc/testsuite/gcc.dg/pr82916.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr82916.c (revision 259627) @@ -0,0 +1,47 @@ +/* PR bootstrap/82916 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-tree-dse" } */ + +struct A { struct A *next; }; +struct C +{ + int *of; + struct C *parent, *prev, *next; + int depth; + int min; + struct C *min_occ; +}; + +__attribute__((noinline, noclone)) struct C * +foo (int *node) +{ + struct A *p = __builtin_malloc (sizeof (struct C)); + if (!p) + return 0; + p->next = 0; + /* Originally placement new. */ + struct C *nw = (struct C *)(void *)p; + nw->of = node; + nw->parent = 0; + nw->prev = 0; + nw->next = 0; + nw->depth = 0; + nw->min_occ = nw; + nw->min = 0; + return nw; +} + +int +main () +{ + int o; + struct C *p = foo (&o); + if (p) + { + if (p->of != &o || p->parent || p->prev || p->next || p->depth + || p->min || p->min_occ != p) + __builtin_abort (); + } + __builtin_free (p); + return 0; +} Index: gcc/testsuite/gcc.dg/ubsan/bounds-3.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/ubsan/bounds-3.c b/gcc/testsuite/gcc.dg/ubsan/bounds-3.c --- a/gcc/testsuite/gcc.dg/ubsan/bounds-3.c (revision 257042) +++ b/gcc/testsuite/gcc.dg/ubsan/bounds-3.c (revision 259627) @@ -1,6 +1,7 @@ /* PR sanitizer/70875 */ /* { dg-do run } */ -/* { dg-options "-fsanitize=bounds" } */ +/* { dg-options "-fsanitize=bounds -fno-sanitize-recover=bounds" } */ +/* { dg-shouldfail "ubsan" } */ int foo (int n, int k) Index: gcc/testsuite/gcc.dg/pr81228.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr81228.c b/gcc/testsuite/gcc.dg/pr81228.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr81228.c (revision 259627) @@ -0,0 +1,21 @@ +/* PR target/81228. */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-ssa" } */ + +void *a; + +void b () +{ + char c; + long d; + char *e = a; + for (; d; d++) + { + double f, g; + c = g < f || g > f; + e[d] = c; + } +} + +/* Let's make sure we do have a LTGT. */ +/* { dg-final { scan-tree-dump "<>" "ssa" } } */ Index: gcc/testsuite/gcc.dg/pr84956.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr84956.c b/gcc/testsuite/gcc.dg/pr84956.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr84956.c (revision 259627) @@ -0,0 +1,27 @@ +/* { dg-options "-O2 -ftree-tail-merge" } */ + +char a; +int c; +unsigned b (); + +unsigned +setjmp () +{ +} + +static void +d () +{ + if (b ()) + c = 3; +} + +void +e () +{ + d (); + a && ({ setjmp (); }); + a && ({ setjmp (); }); + a && ({ setjmp (); }); +} + Index: gcc/testsuite/gcc.dg/pr84503-1.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr84503-1.c b/gcc/testsuite/gcc.dg/pr84503-1.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr84503-1.c (revision 259627) @@ -0,0 +1,68 @@ +/* PR tree-optimization/84503 */ +/* { dg-do run } */ +/* { dg-options "-O3" } */ + +typedef __SIZE_TYPE__ size_t; +typedef __UINTPTR_TYPE__ uintptr_t; + +struct S { int a; unsigned short b; int c, d, e; long f, g, h; int i, j; }; +static struct S *k; +static size_t l = 0; +int m; + +static int +bar (void) +{ + unsigned i; + int j; + if (k[0].c == 0) + { + ++m; + size_t n = l * 2; + struct S *o; + o = (struct S *) __builtin_realloc (k, sizeof (struct S) * n); + if (!o) + __builtin_exit (0); + k = o; + for (i = l; i < n; i++) + { + void *p = (void *) &k[i]; + int q = 0; + size_t r = sizeof (struct S); + if ((((uintptr_t) p) % __alignof__ (long)) == 0 + && r % sizeof (long) == 0) + { + long __attribute__ ((may_alias)) *s = (long *) p; + long *t = (long *) ((char *) s + r); + while (s < t) + *s++ = 0; + } + else + __builtin_memset (p, q, r); + k[i].c = i + 1; + k[i].a = -1; + } + k[n - 1].c = 0; + k[0].c = l; + l = n; + } + j = k[0].c; + k[0].c = k[j].c; + return j; +} + +int +main () +{ + k = (struct S *) __builtin_malloc (sizeof (struct S)); + if (!k) + __builtin_exit (0); + __builtin_memset (k, '\0', sizeof (struct S)); + k->a = -1; + l = 1; + for (int i = 0; i < 15; ++i) + bar (); + if (m != 4) + __builtin_abort (); + return 0; +} Index: gcc/testsuite/gcc.dg/lto/pr81440.h =================================================================== diff --git a/gcc/testsuite/gcc.dg/lto/pr81440.h b/gcc/testsuite/gcc.dg/lto/pr81440.h new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/lto/pr81440.h (revision 259627) @@ -0,0 +1,4 @@ +typedef struct { + int i; + int ints[]; +} struct_t; Index: gcc/testsuite/gcc.dg/lto/pr81440_0.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/lto/pr81440_0.c b/gcc/testsuite/gcc.dg/lto/pr81440_0.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/lto/pr81440_0.c (revision 259627) @@ -0,0 +1,9 @@ +/* { dg-lto-do link } */ + +#include "pr81440.h" + +extern struct_t my_struct; + +int main() { + return my_struct.ints[0]; +} Index: gcc/testsuite/gcc.dg/lto/pr85248_0.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/lto/pr85248_0.c b/gcc/testsuite/gcc.dg/lto/pr85248_0.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/lto/pr85248_0.c (revision 259627) @@ -0,0 +1,45 @@ +/* PR lto/85248 */ +/* { dg-lto-do run } */ +/* { dg-lto-options { { -flto -O2 } } } */ + +extern void test_alias (int s, int e) __asm__ (__USER_LABEL_PREFIX__ "test"); +extern void test_noreturn (int s, int e) __asm__ (__USER_LABEL_PREFIX__ "test") + __attribute__ ((__noreturn__)); + +extern inline __attribute__ ((__always_inline__, __gnu_inline__)) void +test (int s, int e) +{ + if (__builtin_constant_p (s) && s != 0) + test_noreturn (s, e); + else + test_alias (s, e); +} + +int +foo (void) +{ + static volatile int a; + return a; +} + +static void +bar (void) +{ + test (0, 1); + __builtin_exit (0); +} + +static void +baz () +{ + test (1, 0); +} + +int +main () +{ + if (foo ()) + baz (); + bar (); + __builtin_abort (); +} Index: gcc/testsuite/gcc.dg/lto/pr83954_0.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/lto/pr83954_0.c b/gcc/testsuite/gcc.dg/lto/pr83954_0.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/lto/pr83954_0.c (revision 259627) @@ -0,0 +1,8 @@ +/* { dg-lto-do link } */ +#include "pr83954.h" + +int main() { + // just to prevent symbol removal + FOO_PTR_ARR[1] = 0; + return 0; +} Index: gcc/testsuite/gcc.dg/lto/pr81440_1.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/lto/pr81440_1.c b/gcc/testsuite/gcc.dg/lto/pr81440_1.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/lto/pr81440_1.c (revision 259627) @@ -0,0 +1,6 @@ +#include "pr81440.h" + +struct_t my_struct = { + 20, + { 1, 2 } +}; Index: gcc/testsuite/gcc.dg/lto/pr83954.h =================================================================== diff --git a/gcc/testsuite/gcc.dg/lto/pr83954.h b/gcc/testsuite/gcc.dg/lto/pr83954.h new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/lto/pr83954.h (revision 259627) @@ -0,0 +1,3 @@ +struct foo; +extern struct foo *FOO_PTR_ARR[1]; + Index: gcc/testsuite/gcc.dg/lto/pr85248_1.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/lto/pr85248_1.c b/gcc/testsuite/gcc.dg/lto/pr85248_1.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/lto/pr85248_1.c (revision 259627) @@ -0,0 +1,9 @@ +/* { dg-options "-fno-lto" } */ + +void +test (int s, int e) +{ + asm volatile ("" : "+g" (s), "+g" (e) : : "memory"); + if (s) + __builtin_abort (); +} Index: gcc/testsuite/gcc.dg/lto/pr83954_1.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/lto/pr83954_1.c b/gcc/testsuite/gcc.dg/lto/pr83954_1.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/lto/pr83954_1.c (revision 259627) @@ -0,0 +1,7 @@ +#include "pr83954.h" + +struct foo { + int x; +}; +struct foo *FOO_PTR_ARR[1] = { 0 }; + Index: gcc/testsuite/gcc.dg/tls/pr83945.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/tls/pr83945.c b/gcc/testsuite/gcc.dg/tls/pr83945.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/tls/pr83945.c (revision 259627) @@ -0,0 +1,21 @@ +/* PR middle-end/83945 */ +/* { dg-do compile { target tls } } */ +/* { dg-options "-O2" } */ + +struct S { int a[1]; }; +__thread struct T { int c; } e; +int f; +void bar (int); + +void +foo (int f, int x) +{ + struct S *h = (struct S *) &e.c; + for (;;) + { + int *a = h->a, i; + for (i = x; i; i--) + bar (a[f]); + bar (a[f]); + } +} Index: gcc/testsuite/gcc.dg/pr81661.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr81661.c b/gcc/testsuite/gcc.dg/pr81661.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr81661.c (revision 259627) @@ -0,0 +1,12 @@ +/* PR tree-optimization/81661 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -ftrapv" } */ + +int a, b, c; + +void +foo (void) +{ + while (a + c > b) + a--; +} Index: gcc/testsuite/gcc.dg/pr83930.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr83930.c b/gcc/testsuite/gcc.dg/pr83930.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr83930.c (revision 259627) @@ -0,0 +1,17 @@ +/* PR target/83930 */ +/* { dg-do compile } */ +/* { dg-options "-Og -fno-tree-ccp -w" } */ + +unsigned __attribute__ ((__vector_size__ (16))) v; + +static inline void +bar (unsigned char d) +{ + v /= d; +} + +__attribute__ ((always_inline)) void +foo (void) +{ + bar (4); +} Index: gcc/testsuite/gcc.dg/pr84503-2.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/pr84503-2.c b/gcc/testsuite/gcc.dg/pr84503-2.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/pr84503-2.c (revision 259627) @@ -0,0 +1,5 @@ +/* PR tree-optimization/84503 */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-tree-vectorize -fno-ivopts" } */ + +#include "pr84503-1.c" Index: gcc/testsuite/gcc.dg/vect/pr84485.c =================================================================== diff --git a/gcc/testsuite/gcc.dg/vect/pr84485.c b/gcc/testsuite/gcc.dg/vect/pr84485.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/gcc.dg/vect/pr84485.c (revision 259627) @@ -0,0 +1,34 @@ +/* { dg-do run } */ + +#include "tree-vect.h" + +#define N 256 + +void __attribute__ ((noinline, noclone)) +f (unsigned long incx, unsigned long incy, + float *restrict dx, float *restrict dy) +{ + unsigned long ix = 0, iy = 0; + for (unsigned long i = 0; i < N; ++i) + { + dy[iy] += dx[ix]; + ix += incx; + iy += incy; + } +} + +float a = 0.0; +float b[N]; + +int +main (void) +{ + check_vect (); + + for (int i = 0; i < N; ++i) + b[i] = i; + f (1, 0, b, &a); + if (a != N * (N - 1) / 2) + __builtin_abort (); + return 0; +} Index: gcc/testsuite/ChangeLog =================================================================== diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog --- a/gcc/testsuite/ChangeLog (revision 257042) +++ b/gcc/testsuite/ChangeLog (revision 259627) @@ -1,3 +1,1040 @@ +2018-04-24 Steven G. Kargl + + PR fortran/85520 + * gfortran.dg/pr85520.f90: New test. + +2018-04-24 Martin Liska + + Backport from mainline + 2018-04-10 Jakub Jelinek + + PR lto/85248 + * gcc.dg/lto/pr85248_0.c: New test. + * gcc.dg/lto/pr85248_1.c: New test. + +2018-04-24 Martin Liska + + Backport from mainline + 2018-03-28 Jakub Jelinek + Martin Liska + + PR sanitizer/85081 + * g++.dg/asan/pr85081.C: New test. + +2018-04-24 Martin Liska + + Backport from mainline + 2018-03-21 Martin Liska + + PR ipa/84963 + * gfortran.dg/goacc/pr84963.f90: New test. + +2018-04-24 Martin Liska + + Backport from mainline + 2018-03-13 Martin Liska + + PR ipa/84658. + * g++.dg/ipa/pr84658.C: New test. + +2018-04-23 Aaron Sawdey + + Backport from mainline + 2018-04-16 Aaron Sawdey + + PR target/83660 + * gcc.target/powerpc/pr83660.C: New test. + +2018-04-23 Eric Botcazou + + * g++.dg/torture/pr85496.C: New test. + +2018-04-20 Peter Bergner + + PR target/85436 + * go.dg/pr85436.go: New test. + + Backport from mainline + 2018-03-09 Peter Bergner + + PR target/83969 + * gcc.target/powerpc/pr83969.c: New test. + +2018-04-19 Jonathan Wakely + + PR c++/85464 - missing location for -Wignored-qualifiers diagnostic + * g++.dg/diagnostic/pr85464.C: New. + +2018-04-18 Thomas Preud'homme + + Backport from mainline + 2018-04-11 Thomas Preud'homme + + PR target/85261 + * gcc.target/arm/fpscr.c: Add call to __builtin_arm_set_fpscr with + literal value. Expect 2 MCR instruction. Fix function prototype. + Remove volatile keyword. + +2018-04-12 Andreas Krebbel + + Backport from mainline + 2018-04-12 Andreas Krebbel + + * gcc.target/s390/nobp-no-dwarf2-cfi.c: New test. + +2018-04-11 Thomas Preud'homme + + Backport from mainline + 2018-04-04 Thomas Preud'homme + + PR target/85203 + * gcc.target/arm/cmse/cmse-1.c: Tighten cmse_nonsecure_caller RTL scan + to match a single insn of the baz function. Move scan directives at + the end of the file below the functions they are trying to test for + better readability. + * gcc.target/arm/cmse/cmse-16.c: New testcase. + +2018-04-10 Thomas Schwinge + + PR target/85056 + * gcc.target/nvptx/pr85056.c (main): Initialize "sum". + +2018-04-10 Kyrylo Tkachov + + Backport from mainline + 2018-03-08 Kyrylo Tkachov + + PR target/84748 + * gcc.c-torture/execute/pr84748.c: New test. + +2018-04-06 Eric Botcazou + + * g++.dg/opt/pr85196.C: New test. + +2018-04-05 Uros Bizjak + + PR target/85193 + * gcc.target/i386/pr85193.c: New test. + +2018-04-04 Peter Bergner + + Backport from mainline + 2018-04-04 Peter Bergner + + PR rtl-optimization/84878 + * gcc.target/powerpc/pr84878.c: New test. + +2018-04-03 Cesar Philippidis + + Backport from mainline + 2018-03-27 Cesar Philippidis + + PR target/85056 + * testsuite/gcc.target/nvptx/pr85056.c: New test. + * testsuite/gcc.target/nvptx/pr85056a.c: New test. + +2018-04-02 Peter Bergner + + Backport from mainline + 2018-03-28 Peter Bergner + + PR target/84912 + * gcc.target/powerpc/extend-divide-1.c (div_weo): Remove test for + deleted builtin function. + (div_weuo): Likewise. + * gcc.target/powerpc/extend-divide-2.c (div_deo): Likewise. + (div_deuo): Likewise. + +2018-04-02 Peter Bergner + + Backport from mainline + 2018-02-08 Peter Bergner + + PR target/81143 + * gcc.target/powerpc/pr79799-2.c: Use __LITTLE_ENDIAN__. + +2018-03-29 Sebastian Peryt + + PR c++/84783 + * gcc.target/i386/avx512vl-vpermd-1.c (_mm256_permutexvar_epi32): + Test new intrinsic. + * gcc.target/i386/avx512vl-vpermq-imm-1.c (_mm256_permutex_epi64): + Ditto. + * gcc.target/i386/avx512vl-vpermq-var-1.c (_mm256_permutexvar_epi64): + Ditto. + * gcc.target/i386/avx512f-vpermd-2.c: Do not check for AVX512F_LEN. + * gcc.target/i386/avx512f-vpermq-imm-2.c: Ditto. + * gcc.target/i386/avx512f-vpermq-var-2.c: Ditto. + +2018-03-29 Sudakshina Das + + * gcc.target/arm/pr84826.c: Change dg-option to -fstack-check. + + Backport from mainline + 2018-03-23 Sudakshina Das + + PR target/84826 + * gcc.target/arm/pr84826.c: Add dg directive. + + Backport from mainline + 2018-03-22 Sudakshina Das + + PR target/84826 + * gcc.target/arm/pr84826.c: New test. + +2018-03-28 Carl Love + + * gcc.target/powerpc/crypto-builtin-1-runnable: Add + p8vector_hw to dg-do run. + +2018-03-28 Thomas Koenig + + PR fortran/85084 + Backport from trunk. + * gfortran.dg/matmul_rank_1.f90: New test. + +2018-03-28 Sudakshina Das + Christophe Lyon + + 2018-03-20 Christophe Lyon + + PR target/81647 + * gcc.target/aarch64/pr81647.c: Require fenv_exceptions. + + 2018-03-19 Sudakshina Das + + PR target/81647 + * gcc.target/aarch64/pr81647.c: New. + +2018-03-28 Kyrylo Tkachov + + Backport from mainline + 2018-03-23 Kyrylo Tkachov + + PR target/85026 + * g++.dg/pr85026.C: New test. + +2018-03-28 Segher Boessenkool + + Backport from mainline + 2018-03-08 Segher Boessenkool + + PR target/82411 + * gcc.target/powerpc/ppc-sdata-2.c: Skip if -mno-readonly-in-sdata. + +2018-03-27 Sudakshina Das + + Backport from mainline: + 2018-03-20 Sudakshina Das + + PR target/82989 + * gcc.target/arm/pr82989.c: New test. + + Backport from mainline: + 2018-03-21 Sudakshina Das + + PR target/82989 + * gcc.target/arm/pr82989.c: Change dg scan-assembly directives. + +2018-03-27 Kyrylo Tkachov + + Backport from mainline + 2018-03-20 Kyrylo Tkachov + + PR target/82518 + * lib/target-supports.exp (check_effective_target_vect_load_lanes): + Disable for armeb targets. + * gcc.target/arm/pr82518.c: New test. + +2018-03-23 Carl Love + + * gcc.target/powerpc/crypto-builtin-1-runnable.c: New test file. + +2018-03-22 Tom de Vries + + backport from trunk: + 2018-03-22 Tom de Vries + + PR tree-optimization/84956 + * gcc.dg/pr84956.c: New test. + +2018-03-20 Steven G. Kargl + + PR fortran/85001 + * gfortran.dg/interface_41.f90: New test. + +2018-03-19 Thomas Koenig + + PR fortran/84931 + Backport from trunk + * gfortran.dg/array_constructor_52.f90: New test. + +2018-03-19 Steven G. Kargl + + PR fortran/77414 + * gfortran.dg/pr77414.f90: New test. + * gfortran.dg/internal_references_1.f90: Adjust error message. + +2018-03-19 Steven G. Kargl + + PR fortran/65453 + * gfortran.dg/pr65453.f90: New test. + +2018-03-19 H.J. Lu + + Backport from mainline + 2018-03-15 H.J. Lu + + PR target/84574 + * gcc.target/i386/ret-thunk-9.c: Expect __x86_return_thunk + label instead of __x86_indirect_thunk label. + +2018-03-15 Steven G. Kargl + + PR fortran/78741 + * gfortran.dg/pr78741.f90: New test. + +2018-03-12 Steven G. Kargl + + PR fortran/83939 + * gfortran.dg/pr83939.f90 + +2018-03-12 Richard Sandiford + + PR tree-optimization/84485 + * gcc.dg/vect/pr84485.c: New test. + +2018-03-10 Steven G. Kargl + + PR fortran/84734 + * gfortran.dg/pr84734.f90: New test. + +2018-03-10 Eric Botcazou + + * gnat.dg/prot3.adb: New test. + * gnat.dg/prot3_pkg.ad[sb]: New helper. + +2018-03-09 Kugan Vivekanandarajah + + Backport from mainline + 2017-09-13 Kugan Vivekanandarajah + + * gcc.target/aarch64/pr63304_1.c: Remove-mno-fix-cortex-a53-843419. + +2018-03-08 Steven G. Kargl + + PR fortran/64124 + PR fortran/70409 + * gfortran.dg/pr64124.f90: New tests. + * gfortran.dg/pr70409.f90: New tests. + +2018-03-06 Carl Love + + Backport from mainline + 2/16/18 commit 257748 Carl Love + + * gcc.target/powerpc/p9-vinsert4b-1.c: Remove test file for non-ABI + tests. + * gcc.target/powerpc/p9-vinsert4b-2.c: Remove test file for non-ABI + tests. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-23 Segher Boessenkool + + PR testsuite/80551 + * c-c++-common/tsan/race_on_mutex.c: Change regexp to allow + __GI___pthread_mutex_init as well. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-20 Martin Liska + + PR c/84310 + PR target/79747 + * gcc.target/i386/pr84310.c: New test. + * gcc.target/i386/pr84310-2.c: Likewise. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-01-23 Martin Liska + + PR lto/81440 + * gcc.dg/lto/pr81440.h: New test. + * gcc.dg/lto/pr81440_0.c: New test. + * gcc.dg/lto/pr81440_1.c: New test. + +2018-03-06 Martin Liska + + Backport from mainline + 2017-04-27 Martin Liska + + PR testsuite/79455 + * c-c++-common/tsan/race_on_mutex.c: Make the scanned pattern + more generic. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-01-30 Jan Hubicka + + PR lto/83954 + * gcc.dg/lto/pr83954.h: New testcase. + * gcc.dg/lto/pr83954_0.c: New testcase. + * gcc.dg/lto/pr83954_1.c: New testcase. + +2018-03-06 Steven G. Kargl + + PR fortran/56667 + * gfortran.dg/implied_do_2.f90: New test. + * gfortran.dg/coarray_8.f90: Update for new error message. + +2018-03-06 Peter Bergner + + Backport from mainline + 2018-02-22 Vladimir Makarov + + PR target/81572 + * gcc.target/powerpc/pr81572.c: New. + +2018-03-06 Richard Biener + + Backport from mainline + 2018-02-28 Richard Biener + + PR middle-end/84607 + * gcc.dg/pr84607.c: New testcase. + +2018-03-05 Will Schmidt + + Backport from trunk. + + 2018-02-16 Will Schmidt + + PR target/84371 + * gcc.target/powerpc/builtins-3.c: Update dg-options and dg-skip-if + stanzas. + * gcc.target/powerpc/builtins-3.p8.c: Add dg-skip-if stanza. + * gcc.target/powerpc/builtins-3.p9.c: Add dg-skip-if stanza. + +2018-03-05 Jakub Jelinek + + PR target/84524 + * gcc.c-torture/execute/pr84524.c: New test. + * gcc.target/i386/avx512bw-pr84524.c: New test. + +2018-03-04 Paul Thomas + + PR fortran/83076 + * gfortran.dg/coarray_45.f90: New test. + + PR fortran/83319 + * gfortran.dg/coarray_46.f90: New test. + +2018-03-03 Harald Anlauf + + PR fortran/71085 + * gfortran.dg/pr71085.f90: New test. + +2018-03-03 Steven G. Kargl + + PR fortran/51434 + * gfortran.dg/pr51434.f90: New test. + +2018-03-03 Paul Thomas + + PR fortran/80965 + * gfortran.dg/select_type_41.f90: New test. + +2018-03-03 Paul Thomas + + Backported from trunk. + PR fortran/78990 + * gfortran.dg/class_67.f90: New test. + +2018-03-03 Jakub Jelinek + + Backported from mainline + 2018-03-02 Jakub Jelinek + + PR ipa/84628 + * gcc.dg/pr84628.c: New test. + + PR inline-asm/84625 + * gcc.target/i386/pr84625.c: New test. + + 2018-03-02 Jakub Jelinek + + PR sanitizer/70875 + * gcc.dg/ubsan/bounds-3.c: Add -fno-sanitize-recover=bounds to + dg-options and dg-shouldfail "ubsan" directive. + + 2018-02-26 Jakub Jelinek + + PR c++/84558 + * g++.dg/cpp1y/pr84558.C: New test. + + PR c++/84557 + * g++.dg/gomp/pr84557.C: New test. + + PR c++/84556 + * g++.dg/gomp/pr84556.C: New test. + * g++.dg/vect/pr84556.cc: New test. + + 2018-02-22 Jakub Jelinek + + PR tree-optimization/84503 + * gcc.dg/pr84503-1.c: New test. + * gcc.dg/pr84503-2.c: New test. + + 2017-11-10 Jakub Jelinek + + PR bootstrap/82916 + * gcc.dg/pr82916.c: New test. + + 2018-02-20 Jakub Jelinek + + PR c++/84445 + * g++.dg/cpp1z/launder7.C: New test. + + PR c++/84449 + * g++.dg/cpp0x/constexpr-84449.C: New test. + + 2018-02-19 Jakub Jelinek + + PR c++/84444 + * g++.dg/cpp1z/launder8.C: New test. + + PR c++/84448 + * g++.dg/gomp/pr84448.C: New test. + + PR c++/84430 + * g++.dg/gomp/pr84430.C: New test. + + 2018-02-16 Jakub Jelinek + + PR ipa/84425 + * gcc.c-torture/compile/pr84425.c: New test. + + 2018-02-16 Marek Polacek + Jakub Jelinek + + PR c++/84192 + * g++.dg/cpp1y/constexpr-84192.C: New test. + + 2018-02-13 Jakub Jelinek + + PR c/82210 + * gcc.c-torture/execute/pr82210.c: New test. + + 2018-02-12 Jakub Jelinek + + PR c++/84341 + * c-c++-common/gomp/pr84341.c: New test. + + 2018-02-10 Jakub Jelinek + + PR sanitizer/83987 + * g++.dg/ubsan/pr83987-2.C: New test. + + 2018-02-09 Marek Polacek + Jakub Jelinek + + PR c++/83659 + * g++.dg/torture/pr83659.C: New test. + + 2018-02-07 Jakub Jelinek + + PR c++/84082 + * g++.dg/template/incomplete11.C: New test. + * g++.dg/parse/crash67.C: Expect an incomplete type diagnostics too. + + 2018-02-01 Jakub Jelinek + + PR tree-optimization/81661 + PR tree-optimization/84117 + * gcc.dg/pr81661.c: New test. + * gfortran.dg/pr84117.f90: New test. + + 2018-01-31 Jakub Jelinek + + PR fortran/84116 + * gfortran.dg/gomp/pr84116.f90: New test. + + PR c++/83993 + * g++.dg/init/pr83993-2.C: New test. + + PR preprocessor/69869 + * gcc.dg/cpp/trad/pr69869.c: New test. + + 2018-01-30 Jakub Jelinek + + PR rtl-optimization/83986 + * gcc.dg/pr83986.c: New test. + + 2018-01-25 Jakub Jelinek + + PR c++/84031 + * g++.dg/cpp1z/decomp36.C: New test. + + 2018-01-24 Jakub Jelinek + + PR middle-end/83977 + * c-c++-common/gomp/pr83977-1.c: New test. + * c-c++-common/gomp/pr83977-2.c: New test. + * c-c++-common/gomp/pr83977-3.c: New test. + * gfortran.dg/gomp/pr83977.f90: New test. + + 2018-01-23 Jakub Jelinek + + PR sanitizer/83987 + * g++.dg/ubsan/pr83987.C: New test. + + PR c++/83958 + * g++.dg/cpp1z/decomp35.C: New test. + + 2018-01-20 Jakub Jelinek + + PR middle-end/83945 + * gcc.dg/tls/pr83945.c: New test. + + PR target/83930 + * gcc.dg/pr83930.c: New test. + + 2018-01-18 Jakub Jelinek + + PR c++/83824 + * g++.dg/cpp0x/pr83824.C: New test. + + 2018-01-16 Jakub Jelinek + + PR c++/83817 + * g++.dg/cpp1y/pr83817.C: New test. + + 2018-01-05 Jakub Jelinek + + PR tree-optimization/83605 + * gcc.dg/pr83605.c: New test. + +2018-03-01 H.J. Lu + + Backport from mainline + 2018-02-26 H.J. Lu + + PR target/84039 + * gcc.target/i386/indirect-thunk-1.c: Updated. + * gcc.target/i386/indirect-thunk-2.c: Likewise. + * gcc.target/i386/indirect-thunk-3.c: Likewise. + * gcc.target/i386/indirect-thunk-4.c: Likewise. + * gcc.target/i386/indirect-thunk-5.c: Likewise. + * gcc.target/i386/indirect-thunk-6.c: Likewise. + * gcc.target/i386/indirect-thunk-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. + * gcc.target/i386/ret-thunk-9.c: Likewise. + * gcc.target/i386/ret-thunk-10.c: Likewise. + * gcc.target/i386/ret-thunk-11.c: Likewise. + * gcc.target/i386/ret-thunk-12.c: Likewise. + * gcc.target/i386/ret-thunk-13.c: Likewise. + * gcc.target/i386/ret-thunk-14.c: Likewise. + * gcc.target/i386/ret-thunk-15.c: Likewise. + +2018-03-01 H.J. Lu + + Backport from mainline + 2018-02-26 H.J. Lu + + PR target/84530 + * gcc.target/i386/ret-thunk-22.c: New test. + * gcc.target/i386/ret-thunk-23.c: Likewise. + * gcc.target/i386/ret-thunk-24.c: Likewise. + * gcc.target/i386/ret-thunk-25.c: Likewise. + * gcc.target/i386/ret-thunk-26.c: Likewise. + +2017-03-02 Thomas Schwinge + + Backport from trunk r256891: + 2018-01-19 Cesar Philippidis + + PR target/83790 + * gcc.target/nvptx/indirect_call.c: New test. + +2017-03-01 Thomas Preud'homme + + Backport from mainline + 2017-12-05 Matthew Gretton-Dann + with follow-up r255433 commit. + + * gcc.c-torture/unsorted/dump-noaddr.x: Generate dump files in + tmpdir. + +2018-02-28 Alan Modra + + * lib/prune.exp (prune_gcc_output): Match lower case "in function" + GNU ld message. + * g++.dg/other/anon5.C: Match lower case "bad value" GNU ld message. + +2018-02-26 Carl Love + + Backport from mainline: commit 257747 on 2018-02-16. + + * gcc.target/powerpc/builtins-7-p9-runnable.c: New runnable test file + for the ABI definitions for vec_extract4b and vec_insert4b. + +2018-02-26 Eric Botcazou + + * gcc.c-torture/execute/20180226-1.c: New test. + +2018-02-25 Steven G. Kargl + + ChangeLog for r257972 + PR fortran/83633 + * gfortran.dg/explicit_shape_1.f90: New test. + * gfortran.dg/automatic_module_variable.f90: Update regex. + * gfortran.dg/bad_automatic_objects_1.f90: Ditto. + +2018-02-25 Thomas Koenig + + PR fortran/78238 + Backport from trunk + * gfortran.dg/select_type_40.f90: New test. + +2018-02-24 Steven G. Kargl + + PR fortran/30792 + * gfortran.dg/data_substring.f90: New test. + +2018-02-23 Steven G. Kargl + + PR fortran/84346 + * gfortran.dg/statement_function_1.f90: Update test. + +2018-02-23 Jerry DeLisle + + Backport from trunk + PR fortran/84506 + * gfortran.dg/inquire_19.f90: New test. + +2018-02-22 Thomas Koenig + + PR fortran/81116 + PR fortran/84495 + * gfortran.dg/realloc_on_assignment_29.f90: New test. + +2017-02-22 Sudakshina Das + + Backport from mainline: + 2017-12-14 Sudakshina Das + + PR target/81228 + * gcc.dg/pr81228.c: New. + +2018-02-19 Jonathan Wakely + + Backport from mainline + 2018-01-02 Marek Polacek + + PR c++/81860 + * g++.dg/cpp0x/inh-ctor30.C: New test. + +2018-02-18 Jerry DeLisle + + Backport from trunk + PR libgfortran/84412 + * gfortran.dg/inquire_18.f90: New test. + +2018-02-17 Thomas Koenig + + Backport from trunk + PR fortran/84270 + * gfortran.dg/inline_matmul_22.f90: New test. + +2018-02-16 Jozef Lawrynowicz + + PR target/79242 + gcc.target/msp430/pr79242.c: New test. + +2018-02-16 Eric Botcazou + + PR ada/84277 + * gnat.dg/array11.adb (Array11): Tweak index and remove warning. + * gnat.dg/dispatch1.adb: Rename into... + * gnat.dg/disp1.adb: ...this. + * gnat.dg/dispatch1_p.ads: Rename into... + * gnat.dg/disp1_pkg.ads: ...this. + * gnat.dg/disp2.adb: Rename into... + * gnat.dg/dispatch2.adb: ...this. + * gnat.dg/dispatch2_p.ads: Rename into... + * gnat.dg/disp2_pkg.ads: ...this. + * gnat.dg/dispatch2_p.adb: Rename into... + * gnat.dg/disp2_pkg.adb: this. + * gnat.dg/generic_dispatch.adb: Rename into... + * gnat.dg/generic_disp.adb: this. + * gnat.dg/generic_dispatch_p.ads: Rename into... + * gnat.dg/generic_disp_pkg.ads: ...this. + * gnat.dg/generic_dispatch_p.adb: Rename into... + * gnat.dg/generic_disp_pkg.adb: ...this. + * gnat.dg/null_pointer_deref1.adb (Null_Pointer_Deref1): Robustify. + * gnat.dg/null_pointer_deref2.adb (Null_Pointer_Deref2): Likewise. + * gnat.dg/object_overflow1.adb: Tweak index. + * gnat.dg/object_overflow2.adb: Likewise. + * gnat.dg/object_overflow3.adb: Likewise. + * gnat.dg/object_overflow4.adb: Likewise. + * gnat.dg/object_overflow5.adb: Likewise. + +2018-02-16 Sudakshina Das + + Backport from trunk + 2018-01-12 Sudakshina Das + + * gcc.c-torture/compile/pr82096.c: Add dg-skip-if + directive. + + Backport from trunk + 2018-01-10 Sudakshina Das + + PR target/82096 + * gcc.c-torture/compile/pr82096.c: New test. + +2018-02-16 Richard Biener + + PR tree-optimization/84190 + * g++.dg/torture/pr84190.C: New testcase. + +2018-02-15 Michael Meissner + + Back port from trunk + 2018-02-07 Michael Meissner + + PR target/84154 + * gcc.target/powerpc/pr84154-1.c: New tests. + * gcc.target/powerpc/pr84154-2.c: Likewise. + * gcc.target/powerpc/pr84154-3.c: Likewise. + +2018-02-15 Will Schmidt + + PR target/84388 + * gcc.target/powerpc/fold-vec-mult-int128-p8.c: Update dg-options + and scan-assembler stanzas. + * gcc.target/powerpc/fold-vec-mult-int128-p9.c: Same. + +2018-02-14 Peter Bergner + + PR target/84390 + * gcc.target/powerpc/vsxcopy.c: Also match lxv when compiling + with -mcpu=power9. + +2018-02-14 Peter Bergner + + Back port from mainline + 2018-02-13 Peter Bergner + + PR target/84279 + * g++.dg/pr84279.C: New test. + +2018-02-12 Thomas Koenig + + PR fortran/68560 + * gfortran.dg/shape_9.f90: New test. + +2018-02-12 Francois-Xavier Coudert + + PR fortran/35299 + ChangeLog for r257566 + * gfortran.dg/statement_function_3.f: New test. + +2018-02-12 Steven G. Kargl + + PR fortran/54223 + PR fortran/84276 + * gfortran.dg/statement_function_1.f90: New test. + * gfortran.dg/statement_function_2.f90: New test. + +2018-02-09 Andreas Krebbel + + Backport from mainline + 2018-02-09 Andreas Krebbel + + PR target/PR84295 + * gcc.target/s390/pr84295.c: New test. + +2018-02-08 Andreas Krebbel + + Backport from mainline + 2018-02-08 Andreas Krebbel + + * gcc.target/s390/nobp-function-pointer-attr.c: New test. + * gcc.target/s390/nobp-function-pointer-nothunk.c: New test. + * gcc.target/s390/nobp-function-pointer-z10.c: New test. + * gcc.target/s390/nobp-function-pointer-z900.c: New test. + * gcc.target/s390/nobp-indirect-jump-attr.c: New test. + * gcc.target/s390/nobp-indirect-jump-inline-attr.c: New test. + * gcc.target/s390/nobp-indirect-jump-inline-z10.c: New test. + * gcc.target/s390/nobp-indirect-jump-inline-z900.c: New test. + * gcc.target/s390/nobp-indirect-jump-nothunk.c: New test. + * gcc.target/s390/nobp-indirect-jump-z10.c: New test. + * gcc.target/s390/nobp-indirect-jump-z900.c: New test. + * gcc.target/s390/nobp-return-attr-all.c: New test. + * gcc.target/s390/nobp-return-attr-neg.c: New test. + * gcc.target/s390/nobp-return-mem-attr.c: New test. + * gcc.target/s390/nobp-return-mem-nothunk.c: New test. + * gcc.target/s390/nobp-return-mem-z10.c: New test. + * gcc.target/s390/nobp-return-mem-z900.c: New test. + * gcc.target/s390/nobp-return-reg-attr.c: New test. + * gcc.target/s390/nobp-return-reg-mixed.c: New test. + * gcc.target/s390/nobp-return-reg-nothunk.c: New test. + * gcc.target/s390/nobp-return-reg-z10.c: New test. + * gcc.target/s390/nobp-return-reg-z900.c: New test. + * gcc.target/s390/nobp-table-jump-inline-z10.c: New test. + * gcc.target/s390/nobp-table-jump-inline-z900.c: New test. + * gcc.target/s390/nobp-table-jump-z10.c: New test. + * gcc.target/s390/nobp-table-jump-z900.c: New test. + +2018-02-08 Richard Biener + + PR tree-optimization/84233 + * g++.dg/torture/pr84233.C: New testcase. + +2018-02-07 Steven G. Kargl + + PR fortran/82994 + * gfortran.dg/deallocate_error_3.f90: New test. + * gfortran.dg/deallocate_error_4.f90: New test. + +2018-02-07 Steven G. Kargl + + PR fortran/82049 + * gfortran.dg/assumed_charlen_parameter.f90: New test. + +2018-02-07 Bill Schmidt + + Backport from mainline + 2018-02-06 Bill Schmidt + + * gcc.target/powerpc/safe-indirect-jump-1.c: Detect deprecation + warning for -mno-speculate-indirect-jumps. + * gcc.target/powerpc/safe-indirect-jump-2.c: Likewise. + * gcc.target/powerpc/safe-indirect-jump-3.c: Likewise. + * gcc.target/powerpc/safe-indirect-jump-4.c: Likewise. + * gcc.target/powerpc/safe-indirect-jump-5.c: Likewise. + * gcc.target/powerpc/safe-indirect-jump-6.c: Likewise. + * gcc.target/powerpc/safe-indirect-jump-7.c: Likewise. + +2018-02-06 Rainer Orth + + PR target/79975 + * gcc.dg/rtl/x86_64/final.c: Add -fdwarf2-cfi-asm to dg-options. + +2017-02-02 Uros Bizjak + + * gfortran.dg/dec_parameter_1.f (sub1): Remove statement with no effect. + * gfortran.dg/dec_parameter_2.f90 (sub1): Ditto. + +2018-02-01 Renlin Li + + Backport from mainline + 2018-02-01 Richard Sandiford + + PR target/83370 + * gcc.target/aarch64/pr83370.c: New. + +2018-02-01 Richard Biener + + Backport from mainline + 2017-11-02 Richard Biener + + PR tree-optimization/82795 + * gcc.target/i386/pr82795.c: New testcase. + +2018-02-01 Rainer Orth + + Backport from mainline + 2018-01-12 Rainer Orth + + * lib/target-supports.exp (check_effective_target_avx512f): Also + check for __builtin_ia32_addsd_round, + __builtin_ia32_getmantsd_round. + * gcc.target/i386/i386.exp (check_effective_target_avx512f): + Remove. + +2018-01-31 Eric Botcazou + + * gcc.c-torture/execute/20180131-1.c: New test. + +2018-01-29 Alan Modra + + PR target/84033 + * gcc.target/powerpc/swaps-p8-46.c: New. + +2018-01-26 Segher Boessenkool + + Backport from trunk + 2018-01-26 Segher Boessenkool + + * gcc.target/powerpc/safe-indirect-jump-1.c: Build on all targets. + Make expected output depend on whether we expect sibcalls or not. + * gcc.target/powerpc/safe-indirect-jump-8.c: Delete (merged into + safe-indirect-jump-1.c). + + Backport from trunk + 2018-01-21 Bill Schmidt + + PR target/83946 + * gcc.target/powerpc/safe-indirect-jump-8.c: Skip for AIX. + +2018-01-26 Nathan Sidwell + + PR c++/82878 + * g++.dg/cpp0x/pr82878.C: New. + * g++.dg/cpp1z/inh-ctor38.C: Check moves too. + +2018-01-26 Jakub Jelinek + + PR rtl-optimization/83985 + * gcc.dg/pr83985.c: New test. + +2018-01-25 Michael Meissner + + Back port from trunk + 2018-01-22 Michael Meissner + + PR target/83862 + * gcc.target/powerpc/pr83862.c: New test. + +2018-01-25 Peter Bergner + + Back port from mainline + 2018-01-10 Peter Bergner + + PR target/83399 + * gcc.target/powerpc/pr83399.c: New test. + 2018-01-25 Release Manager * GCC 7.3.0 released. @@ -920,7 +1957,7 @@ Backported from trunk PR fortran/80850 - * gfortran.dg/class_64_f90 : New test. + * gfortran.dg/class_64_f90: New test. 2017-10-30 Paolo Carlini @@ -971,7 +2008,7 @@ Backport from trunk PR fortran/82312 - * gfortran.dg/typebound_proc_36.f90 : New test. + * gfortran.dg/typebound_proc_36.f90: New test. 2017-10-20 Thomas Koenig Index: gcc/testsuite/go.dg/pr85436.go =================================================================== diff --git a/gcc/testsuite/go.dg/pr85436.go b/gcc/testsuite/go.dg/pr85436.go new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/go.dg/pr85436.go (revision 259627) @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mcpu=power9" { target { powerpc*-*-* } } } */ + +package main +import ( + "go/ast" + "go/parser" + "go/token" +) +type testFuncs struct { } +func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) { + var testFileSet = token.NewFileSet() + f, err := parser.ParseFile(testFileSet, filename, nil, parser.ParseComments) + if err != nil { } + for _, d := range f.Decls { + n, ok := d.(*ast.FuncDecl) + if !ok { } + ptr := n.Type.Params.List[0].Type.(*ast.StarExpr) + if sel := ptr.X.(*ast.SelectorExpr); sel.Sel.Name == "M" { } + } +} Index: gcc/testsuite/g++.dg/opt/pr85196.C =================================================================== diff --git a/gcc/testsuite/g++.dg/opt/pr85196.C b/gcc/testsuite/g++.dg/opt/pr85196.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/opt/pr85196.C (revision 259627) @@ -0,0 +1,89 @@ +// PR target/85196 +// Testcase by Rainer Orth + +// { dg-do compile } +// { dg-options "-O -fpermissive -w" } +// { dg-additional-options "-fPIC" { target fpic } } + +class a; +template class b; +template class d : public b {}; +class e {}; +void f(int); +template class g { +public: + h(); + a i(); +}; +template <> class b : public g {}; +typedef (*j)(d); +template class l { +public: + k operator->() { return 0; } +}; +enum m { n, aa, o, ab, q, p }; +inline s(m ac) { + switch (ac) { + case n: + case aa: + case p: + return 1; + case o: + case ab: + return 2; + } +} +class D { + int ad; + +public: + *ae() { return &ad; } +}; +class a { + l af; + +public: + *r() { return af->ae(); } + t(int *c) { + int *w = af->ae(); + return w == c; + } +}; +class F : a { +public: + static int ah[]; + static e v(F *); + unsigned long ai() const; +}; +inline unsigned long F::ai() const { + m aj = r() - &ah[0]; + return s(aj); +} +inline e F::v(F *ak) { + long al = ak->ai(); + f(al); +} +template am() { return q; } +class an : F { +public: + static ao(d u) { + int *ap; + m aq = am(); + ap = &ah[aq]; + return u.h() && u.i().t(ap); + } + template static as() { + F at; + ar(&at); + } + template static au(int *, unsigned, e *) { + j av = ao; + d aw; + if (av(aw)) + as(); + } +}; +int *ax; +int ay; +e az; +ba() { an::au(ax, ay, &az); } Index: gcc/testsuite/g++.dg/pr85026.C =================================================================== diff --git a/gcc/testsuite/g++.dg/pr85026.C b/gcc/testsuite/g++.dg/pr85026.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/pr85026.C (revision 259627) @@ -0,0 +1,61 @@ +/* PR target/85026. */ +/* { dg-do assemble } */ +/* { dg-options "-O2 -std=gnu++11" } */ + +template class a; +class b; +struct c { + typedef a &g; +}; +template struct e { typedef typename d::f iter; }; +class h { +public: + void __attribute__((noreturn)) i(); +} ab; +template class a { +public: + typedef b *f; + b &operator[](unsigned m) { + if (ac) + ab.i(); + return ad[m]; + } + f n() { return ad; } + f m_fn3(); + b *ad; + unsigned ac; +}; +class b { +public: + short j; + short k; + signed l; +} __attribute__((__packed__)); +void o(a &m, b &p2, b &p) { + p2 = p = m[0]; + if (bool at = false) + ; + else + for (c::g au(m);; at = true) + if (bool av = false) + ; + else + for (e>::iter aw = au.n(), ax = au.m_fn3(); ax; + av ? (void)0 : (void)0) + if (bool ay = 0) + ; + else + for (b az = *aw; !ay; ay = true) { + if (p2.j) + p2.j = az.j; + else if (p.j) + p.j = az.j; + if (p2.k) + p2.k = az.k; + else if (az.k > p.k) + p.k = az.k; + if (az.l < p2.l) + if (az.l > p.l) + p.l = az.l; + } +} Index: gcc/testsuite/g++.dg/ubsan/pr83987-2.C =================================================================== diff --git a/gcc/testsuite/g++.dg/ubsan/pr83987-2.C b/gcc/testsuite/g++.dg/ubsan/pr83987-2.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/ubsan/pr83987-2.C (revision 259627) @@ -0,0 +1,24 @@ +// PR sanitizer/83987 +// { dg-do compile { target fopenmp } } +// { dg-options "-fopenmp -fsanitize=vptr" } + +struct A +{ + int i; +}; + +struct B : virtual A +{ + void foo(); +}; + +void B::foo() +{ +#pragma omp parallel + { + #pragma omp sections lastprivate (i) + { + i = 0; + } + } +} Index: gcc/testsuite/g++.dg/ubsan/pr83987.C =================================================================== diff --git a/gcc/testsuite/g++.dg/ubsan/pr83987.C b/gcc/testsuite/g++.dg/ubsan/pr83987.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/ubsan/pr83987.C (revision 259627) @@ -0,0 +1,15 @@ +// PR sanitizer/83987 +// { dg-do compile { target fopenmp } } +// { dg-options "-fopenmp -fsanitize=vptr -O0" } + +struct A { int i; }; +struct B : virtual A { void foo (); }; + +void +B::foo () +{ +#pragma omp sections lastprivate (i) + { + i = 0; + } +} Index: gcc/testsuite/g++.dg/pr84279.C =================================================================== diff --git a/gcc/testsuite/g++.dg/pr84279.C b/gcc/testsuite/g++.dg/pr84279.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/pr84279.C (revision 259627) @@ -0,0 +1,35 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } } */ +/* { dg-require-effective-target powerpc_p8vector_ok } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-O3 -mcpu=power8 -g -fPIC -fvisibility=hidden -fstack-protector-strong" } */ + +template struct E { T e; }; +struct J { + unsigned k, l; + J (unsigned x, unsigned y) : k(x), l(y) {} +}; +typedef struct A { + J n, p; + A (); + A (J x, J y) : n(x), p(y) {} +} *S; +S t; +struct B { + struct C { + S q, r; + int u, v; + bool m1 (S, A &); + J m2 () const; + J m3 () const; + A m4 () const; + }; + typedef E D; + void m5 (D *); + void m6 (unsigned, A); +}; +bool B::C::m1 (S, A &x) { bool o; x = m4 (); return o; } +J B::C::m2 () const { unsigned g (u == 0); unsigned h (v); return J (g, h); } +J B::C::m3 () const { unsigned g (q != t); unsigned h (r != t); return J (g, h); } +A B::C::m4 () const { return A (m2 (), m3 ()); } +void B::m5 (D *c) { unsigned x; C ar; A am; if (ar.m1 (c->e, am)) m6 (x, am); } Index: gcc/testsuite/g++.dg/diagnostic/pr85464.C =================================================================== diff --git a/gcc/testsuite/g++.dg/diagnostic/pr85464.C b/gcc/testsuite/g++.dg/diagnostic/pr85464.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/diagnostic/pr85464.C (revision 259627) @@ -0,0 +1,5 @@ +// { dg-options "-Wignored-qualifiers" } +struct Test { + operator int const(); // { dg-warning "type qualifiers ignored" } + operator int const() const; // { dg-warning "type qualifiers ignored" } +}; Index: gcc/testsuite/g++.dg/parse/crash67.C =================================================================== diff --git a/gcc/testsuite/g++.dg/parse/crash67.C b/gcc/testsuite/g++.dg/parse/crash67.C --- a/gcc/testsuite/g++.dg/parse/crash67.C (revision 257042) +++ b/gcc/testsuite/g++.dg/parse/crash67.C (revision 259627) @@ -2,4 +2,4 @@ class x0; template x2() { // { dg-error "declared|type" } -x0 x3 = x3. // { dg-error "expected" } +x0 x3 = x3. // { dg-error "expected|incomplete type" } Index: gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle5.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle5.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle5.C (revision 259627) @@ -0,0 +1,15 @@ +// { dg-do compile { target c++11 } } +// { dg-final { scan-assembler "_ZZN1AIiEC4IiEET_S2_Ed_NKUlvE_clEv" } } + +template struct A +{ + template + A(U, U = []{ return 42; }()); +}; + +struct B: A +{ + using A::A; +}; + +B b(24); Index: gcc/testsuite/g++.dg/cpp0x/constexpr-84449.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-84449.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-84449.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-84449.C (revision 259627) @@ -0,0 +1,14 @@ +// PR c++/84449 +// { dg-do compile { target c++11 } } + +struct A +{ + constexpr A (int) {} + ~A () = delete; +}; + +struct B +{ + A a; + constexpr B () : a (0) {} // { dg-error "use of deleted function" } +}; Index: gcc/testsuite/g++.dg/cpp0x/pr83824.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/pr83824.C b/gcc/testsuite/g++.dg/cpp0x/pr83824.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/pr83824.C (revision 259627) @@ -0,0 +1,9 @@ +// PR c++/83824 +// { dg-do compile { target c++11 } } + +void +foo () +{ + if (alignas(1 alignas(1))) // { dg-error "expected" } + ; +} Index: gcc/testsuite/g++.dg/cpp0x/extern_template-4.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/extern_template-4.C b/gcc/testsuite/g++.dg/cpp0x/extern_template-4.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/extern_template-4.C (revision 259627) @@ -0,0 +1,23 @@ +// PR c++/85470 +// { dg-do compile { target c++11 } } + +template +struct StaticObject +{ + static T& create() + { + static T t; + return t; + } + + static T & instance; +}; + +template T & StaticObject::instance = StaticObject::create(); + +extern template class StaticObject; + +void test() +{ + StaticObject::instance; +} Index: gcc/testsuite/g++.dg/cpp0x/decltype43.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype43.C b/gcc/testsuite/g++.dg/cpp0x/decltype43.C --- a/gcc/testsuite/g++.dg/cpp0x/decltype43.C (revision 257042) +++ b/gcc/testsuite/g++.dg/cpp0x/decltype43.C (revision 259627) @@ -22,6 +22,6 @@ int main() { int x = B::a(1))>::b(A::a(1)); - int y = B::b(A::a(2)); // { dg-error "template argument" } + int y = B::b(A::a(2)); // { dg-error "template" } return x + y; } Index: gcc/testsuite/g++.dg/cpp0x/ref-qual18.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual18.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual18.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/ref-qual18.C (revision 259627) @@ -0,0 +1,18 @@ +// PR c++/71784 +// { dg-do compile { target c++11 } } + +template struct A { + template void f(U const&) & { } + template void f(U const&) && { } +}; + +template void A::f(int const&) &; +template void A::f(int const&) &&; + +template struct B { + void f(int const&) & { } + void f(int const&) && { } +}; + +template void B::f(int const&) &; +template void B::f(int const&) &&; Index: gcc/testsuite/g++.dg/cpp0x/sfinae60.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae60.C b/gcc/testsuite/g++.dg/cpp0x/sfinae60.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae60.C (revision 259627) @@ -0,0 +1,25 @@ +// PR c++/78489 +// { dg-do compile { target c++11 } } + +template struct enable_if { using type = T; }; +template struct enable_if {}; + +template struct use_type { using type = int; }; + +template +struct get_type { + static_assert(Pred, ""); + using type = int; +}; + +template ::type, // Evaluation/Substitution should end here + class ValT = typename get_type::type, // This should not be instantiated + typename use_type::type = 0 // This NTTP causes ValT to be required + > +constexpr bool test(int) { return false; } + +template +constexpr bool test(long) { return true; } + +static_assert(test(0), ""); // should call test(long) Index: gcc/testsuite/g++.dg/cpp0x/fntmpdefarg8.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg8.C b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg8.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg8.C (revision 259627) @@ -0,0 +1,10 @@ +// PR c++/80227 +// { dg-do compile { target c++11 } } + +template +int foo (T); + +template +int foo (T, U* = 0); + +int i = foo (123); Index: gcc/testsuite/g++.dg/cpp0x/variadic-nested3.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-nested3.C b/gcc/testsuite/g++.dg/cpp0x/variadic-nested3.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-nested3.C (revision 259627) @@ -0,0 +1,10 @@ +// PR c++/71834 +// { dg-do compile { target c++11 } } + +template < typename ... Ts > struct A +{ + template < Ts ..., typename U > struct B {}; +}; + +// should be, e.g.: A < int >::B < 0, int > e; +A < int >::B < 0 > e; // { dg-error "wrong number of template arguments" } Index: gcc/testsuite/g++.dg/cpp0x/decltype67.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype67.C b/gcc/testsuite/g++.dg/cpp0x/decltype67.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/decltype67.C (revision 259627) @@ -0,0 +1,7 @@ +// PR c++/85279 +// { dg-do compile { target c++11 } } + +template struct A +{ + void foo(decltype(T())::Y); // { dg-error {decltype\(T\(\)\)::Y} } +}; Index: gcc/testsuite/g++.dg/cpp0x/constexpr-list2.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-list2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-list2.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-list2.C (revision 259627) @@ -0,0 +1,20 @@ +// PR c++/82461 +// { dg-do compile { target c++11 } } + +class A { +private: +public: + constexpr A() {} + ~A() {} +}; + +class B { +private: + A a; +public: + constexpr B() : a{} {} +// works +// constexpr B() : a() {} + + ~B() {} +}; Index: gcc/testsuite/g++.dg/cpp0x/elision3.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/elision3.C b/gcc/testsuite/g++.dg/cpp0x/elision3.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/elision3.C (revision 259627) @@ -0,0 +1,21 @@ +// PR c++/84441 +// { dg-do compile { target c++11 } } + +struct B { + int *b; +}; +struct A { + B b; + A (A &&); +}; +struct C { + A c; + int d; +}; +C bar (); +struct D : C { + D () + : C (0 ? bar () : bar ()) + {} +}; +D d; Index: gcc/testsuite/g++.dg/cpp0x/initlist98.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist98.C b/gcc/testsuite/g++.dg/cpp0x/initlist98.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/initlist98.C (revision 259627) @@ -0,0 +1,17 @@ +// PR c++/83227 +// { dg-do compile { target c++11 } } + +#include + +template struct f { + f(std::initializer_list) {} +}; + +struct h {}; +struct i : h { + i(); +}; +void foo(f); +int main() { + foo({i{}}); +} Index: gcc/testsuite/g++.dg/cpp0x/inh-ctor30.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor30.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor30.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor30.C (revision 259627) @@ -0,0 +1,27 @@ +// PR c++/81860 +// { dg-do compile { target c++11 } } +// { dg-final { scan-assembler "_ZN1AIjEC\[12\]Ev" } } + +template +struct A +{ + A() {} +}; + +struct B +{ + template + B(D, const A& a = A()) : a(a) {} + + A a; +}; + +struct C : B +{ + using B::B; +}; + +int main() +{ + C c(0); +} Index: gcc/testsuite/g++.dg/cpp0x/auto51.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/auto51.C b/gcc/testsuite/g++.dg/cpp0x/auto51.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/auto51.C (revision 259627) @@ -0,0 +1,9 @@ +// PR c++/84798 +// { dg-do compile { target c++11 } } + +template +struct S { + static constexpr T value = 0; +}; + +constexpr auto x = S::value; // { dg-error "auto" } Index: gcc/testsuite/g++.dg/cpp0x/constexpr-ctor21.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor21.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor21.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor21.C (revision 259627) @@ -0,0 +1,15 @@ +// PR c++/83835 +// { dg-do compile { target c++11 } } + +struct Z +{ + void const * p_; + constexpr Z( void const * p ): p_( p ) {} + ~Z(); +}; + +struct Y +{ + Z z_; + constexpr Y() noexcept: z_( this ) {} +}; Index: gcc/testsuite/g++.dg/cpp0x/decltype-33837.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-33837.C b/gcc/testsuite/g++.dg/cpp0x/decltype-33837.C --- a/gcc/testsuite/g++.dg/cpp0x/decltype-33837.C (revision 257042) +++ b/gcc/testsuite/g++.dg/cpp0x/decltype-33837.C (revision 259627) @@ -2,6 +2,6 @@ // PR c++/33837 void foo() { - __decltype (A::foo()); // { dg-error "was not declared|expected" } - __decltype (B); // { dg-error "was not declared" } + __decltype (A::foo()); // { dg-error "A" } + __decltype (B); // { dg-error "B" } } Index: gcc/testsuite/g++.dg/cpp0x/range-for13.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for13.C b/gcc/testsuite/g++.dg/cpp0x/range-for13.C --- a/gcc/testsuite/g++.dg/cpp0x/range-for13.C (revision 257042) +++ b/gcc/testsuite/g++.dg/cpp0x/range-for13.C (revision 259627) @@ -3,16 +3,6 @@ // { dg-do compile { target c++11 } } -//These should not be used -template int *begin(T &t) -{ - T::fail; -} -template int *end(T &t) -{ - T::fail; -} - struct container1 { int *begin(); @@ -87,10 +77,37 @@ static function end; }; +namespace N +{ +template int *begin(T &t) +{ + return 0; +} +template int *end(T &t) +{ + return 0; +} +struct container11 +{ + int *begin(); + //no end +}; + +struct container12 +{ + int *end(); + //no begin +}; + +struct container13 +{ +}; +} + void test1() { - for (int x : container1()); // { dg-error "member but not" } - for (int x : container2()); // { dg-error "member but not" } + for (int x : container1()); // { dg-error "'begin' was not declared|'end' was not declared" } + for (int x : container2()); // { dg-error "'begin' was not declared|'end' was not declared" } for (int x : container3()); // { dg-error "within this context" } for (int x : container4()); // { dg-error "cannot be used as a function" } for (int x : container5()); // { dg-error "invalid use of" } @@ -99,4 +116,7 @@ for (int x : container8()); for (int x : container9()); // { dg-error "within this context" } for (int x : container10()); + for (int x : N::container11()); + for (int x : N::container12()); + for (int x : N::container13()); } Index: gcc/testsuite/g++.dg/cpp0x/nsdmi14.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi14.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi14.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi14.C (revision 259627) @@ -0,0 +1,19 @@ +// PR c++/71638 +// { dg-do compile { target c++11 } } +// { dg-options "-Wall" } + +struct A { + struct { + int i; + int &j = i; + } b; + int a = b.j; +}; + +void bar (A); + +void +foo () +{ + bar (A{}); +} Index: gcc/testsuite/g++.dg/cpp0x/variadic-nested2.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-nested2.C b/gcc/testsuite/g++.dg/cpp0x/variadic-nested2.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-nested2.C (revision 259627) @@ -0,0 +1,9 @@ +// PR c++/84839 +// { dg-do compile { target c++11 } } + +template +struct S { + using fptr = void(*)(T... x, decltype(x)... y); +}; + +using F = S::fptr; Index: gcc/testsuite/g++.dg/cpp0x/nsdmi-empty1.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-empty1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-empty1.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-empty1.C (revision 259627) @@ -0,0 +1,18 @@ +// PR c++/82764 +// { dg-do compile { target c++11 } } + +struct Empty {}; +struct Empty2 : Empty {}; + +struct A : Empty2 +{ + int x {1}; + int y {2}; +}; + +struct B +{ + A a {}; +}; + +B b; Index: gcc/testsuite/g++.dg/cpp0x/auto-60626.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/auto-60626.C b/gcc/testsuite/g++.dg/cpp0x/auto-60626.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/auto-60626.C (revision 259627) @@ -0,0 +1,6 @@ +// PR c++/60626 +// { dg-do compile { target c++14 } } + +struct A {}; + +void (*A::p)(auto) = 0; // { dg-error "auto|static data member|template" } Index: gcc/testsuite/g++.dg/cpp0x/noexcept32.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept32.C b/gcc/testsuite/g++.dg/cpp0x/noexcept32.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept32.C (revision 259627) @@ -0,0 +1,14 @@ +// PR c++/84045 +// { dg-do compile { target c++11 } } + +template struct K { + static const bool d = true; +}; +template struct B { + typedef K D; + void foo () noexcept (D::d); +}; +template struct P { + P () noexcept (K::d); +}; +P p; Index: gcc/testsuite/g++.dg/cpp0x/pr82878.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/pr82878.C b/gcc/testsuite/g++.dg/cpp0x/pr82878.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/pr82878.C (revision 259627) @@ -0,0 +1,20 @@ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-O" } +// pr 82878 erroneously unwrapped a reference parm in the lambda::_FUN +// thunk. + +struct A { + ~A(); + operator int (); +}; + +void baz (); + +void +bar (A b) +{ + void (*lam) (A) = [](A) { baz (); }; + + if (auto c = b) + lam (c); +} Index: gcc/testsuite/g++.dg/cpp0x/initlist-defarg2.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-defarg2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-defarg2.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-defarg2.C (revision 259627) @@ -0,0 +1,8 @@ +// PR c++/82336 +// { dg-do link { target c++11 } } + +struct foo { int x = 5; }; +struct bar : foo { bar() = default; }; +struct baz { bar x; }; +void qux(baz = {}){} +int main() { qux(); } Index: gcc/testsuite/g++.dg/torture/pr84190.C =================================================================== diff --git a/gcc/testsuite/g++.dg/torture/pr84190.C b/gcc/testsuite/g++.dg/torture/pr84190.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/torture/pr84190.C (revision 259627) @@ -0,0 +1,20 @@ +// { dg-do compile } +// For slim LTO there's no optimized dump +// { dg-skip-if "" { *-*-* } { "-flto" } { "" } } +// { dg-additional-options "-fdump-tree-optimized" } + +typedef double T; +static int equalfn (volatile T* x, volatile T* y); +T gx, gy; +int main () +{ + T x = gx, y = gy; + return equalfn (&x, &y); +} +static int equalfn (volatile T* x, volatile T* y) +{ + return (*x == *y); +} + +// There should be exactly two volatile accesses (ignoring clobbers). +// { dg-final { scan-tree-dump-times " ={v} \[^\{\]" 2 "optimized" } } Index: gcc/testsuite/g++.dg/torture/pr83659.C =================================================================== diff --git a/gcc/testsuite/g++.dg/torture/pr83659.C b/gcc/testsuite/g++.dg/torture/pr83659.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/torture/pr83659.C (revision 259627) @@ -0,0 +1,18 @@ +// PR c++/83659 +// { dg-do compile } + +typedef int V __attribute__ ((__vector_size__ (16))); +V a; +V b[2]; + +int +foo () +{ + return reinterpret_cast (&a)[-1] += 1; +} + +int +bar () +{ + return reinterpret_cast (&a[1])[-1]; +} Index: gcc/testsuite/g++.dg/torture/pr84233.C =================================================================== diff --git a/gcc/testsuite/g++.dg/torture/pr84233.C b/gcc/testsuite/g++.dg/torture/pr84233.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/torture/pr84233.C (revision 259627) @@ -0,0 +1,25 @@ +// { dg-do compile } +// { dg-additional-options "-w" } + +void a(const char *, int, const char *, const char *); +template void c(b); +struct d { + long e; + template union f; + template union f { + f(h *i) : j(i) {} + h *j; + long bits; + }; + static int k(volatile long &i) { return *(int *)f(&i).bits; } + typedef long g; + operator g() volatile { + int l = k(e); + c(l); + } +}; +struct : d { + } m, n; +bool o; +void p() { (o ? m : n) ? (void)0 : a("", 5, "", ""); } + Index: gcc/testsuite/g++.dg/torture/pr85496.C =================================================================== diff --git a/gcc/testsuite/g++.dg/torture/pr85496.C b/gcc/testsuite/g++.dg/torture/pr85496.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/torture/pr85496.C (revision 259627) @@ -0,0 +1,18 @@ +// PR middle-end/85496 +// Reported by Marek Polacek + +template class complex; +template complex<_Tp> operator*(complex<_Tp>, complex<_Tp>); +template <> struct complex { _Complex float _M_value; }; +class A { + complex _f0, _f1; + +public: + complex &m_fn1() { return _f1; } +}; +complex a; +void cos() { + A b; + complex c; + b.m_fn1() = c * a; +} Index: gcc/testsuite/g++.dg/ipa/pr84658.C =================================================================== diff --git a/gcc/testsuite/g++.dg/ipa/pr84658.C b/gcc/testsuite/g++.dg/ipa/pr84658.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/ipa/pr84658.C (revision 259627) @@ -0,0 +1,30 @@ +/* PR ipa/84658 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fmerge-all-constants -std=c++11" } */ + +const int kTestCasesFoo[] = { 0, 1, 2, 3, 4, 5, 8, 15, 16, 17, 512, 1020, 1021, 1022, 1023, 1024 }; +const int kTestCasesBar[] = { 0, 1, 2, 3, 4, 5, 8, 15, 16, 17, 512, 1020, 1021, 1022, 1023, 1024 }; + +void Foo() { + __builtin_printf("foo:"); + for (int count : kTestCasesFoo) { + __builtin_printf("%d,", count); + } + __builtin_printf(";\n"); +} + +void Bar() { + __builtin_printf("bar:"); + for (int count : kTestCasesBar) { + __builtin_printf("%d,", count); + } + __builtin_printf(";\n"); +} + +int main() { + Foo(); + Bar(); +} + +/* { dg-output "foo:0,1,2,3,4,5,8,15,16,17,512,1020,1021,1022,1023,1024,;(\n|\n\r|\r)*" } */ +/* { dg-output "bar:0,1,2,3,4,5,8,15,16,17,512,1020,1021,1022,1023,1024,;(\n|\n\r|\r)*" } */ Index: gcc/testsuite/g++.dg/cpp1y/pr60626.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60626.C b/gcc/testsuite/g++.dg/cpp1y/pr60626.C deleted file mode 10644 --- a/gcc/testsuite/g++.dg/cpp1y/pr60626.C (revision 257042) +++ /dev/null (nonexistent) @@ -1,7 +0,0 @@ -// PR c++/60626 -// { dg-do compile { target c++14 } } -// { dg-options "" } - -struct A {}; - -void (*A::p)(auto) = 0; // { dg-error "static data member|template" } Index: gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr10.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr10.C b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr10.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr10.C (revision 259627) @@ -0,0 +1,7 @@ +// PR c++/71638 +// { dg-do compile { target c++14 } } + +struct { + int &&a; + int b{a}; +} c[] { { 2 } }; Index: gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr11.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr11.C b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr11.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr11.C (revision 259627) @@ -0,0 +1,12 @@ +// PR c++/85148 +// { dg-do compile { target c++14 } } + +template struct A +{ + T x[1]{(__PTRDIFF_TYPE__)this}; +}; + +void foo() +{ + A> a{}; +} Index: gcc/testsuite/g++.dg/cpp1y/pr84558.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/pr84558.C b/gcc/testsuite/g++.dg/cpp1y/pr84558.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/pr84558.C (revision 259627) @@ -0,0 +1,6 @@ +// PR c++/84558 +// { dg-do compile { target c++14 } } + +struct A { static int i; constexpr A () { i = 0; } }; +struct B { A a[2][3][4]; }; +B b; Index: gcc/testsuite/g++.dg/cpp1y/var-templ58a.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ58a.C b/gcc/testsuite/g++.dg/cpp1y/var-templ58a.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ58a.C (revision 259627) @@ -0,0 +1,14 @@ +// PR c++/71569 +// { dg-do compile { target c++14 } } + +template +struct A { + template + static const U u; +}; + +template +template +const U* A::u = 0; + +const int *p = A::u; Index: gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr9.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr9.C b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr9.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr9.C (revision 259627) @@ -0,0 +1,14 @@ +// PR c++/84927 - ICE with NSDMI and reference +// { dg-do compile { target c++14 } } + +struct A +{ + int& r; + int i = r; +}; + +void foo() +{ + int j; + A a = A{j}; +} Index: gcc/testsuite/g++.dg/cpp1y/pr84496.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/pr84496.C b/gcc/testsuite/g++.dg/cpp1y/pr84496.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/pr84496.C (revision 259627) @@ -0,0 +1,44 @@ +// PR c++/84496 +// { dg-do compile { target c++14 } } + +template struct C { static constexpr T D = n; }; +struct E : C {}; +template struct F : C {}; +template T foo (); +template struct H { typedef int G; }; +template class I; +struct L; +template struct J; +template struct K; +struct R { + template + static J () (foo...)), L> o; +}; +template struct K : R { + typedef decltype (o) G; +}; +template +struct D : K::G>::D, P, Q...> {}; +template struct I

: D {}; +template class function; +template struct function { + template ::G> struct C; + template using U = int; + template , typename = U, void>> + function (P); +}; +template +template +function::function (P) +{ +} +void bar (function); + +void +baz () +{ + auto a = [] { + static int counter; + bar ([] (auto) { counter++; }); + }; +} Index: gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C --- a/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C (revision 257042) +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C (revision 259627) @@ -85,4 +85,4 @@ // { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPT_PT0_E4_Z3FoovEUlS1_S3_E5_EvRS0_RS2_:" } } // { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPfS3_E_EvRT_RT0_:" } } // { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPT_PT0_E0_EvRS3_RS5_:" } } -// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPT_zE1_EvRS3_RT0_:" } } +// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsDpPT_E1_EvRT_RT0_:" } } Index: gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic16.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic16.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic16.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic16.C (revision 259627) @@ -0,0 +1,8 @@ +// PR c++/64095 +// { dg-do compile { target c++14 } } + +void f() +{ + [](auto...){}(); + [](auto&&...){}(); +} Index: gcc/testsuite/g++.dg/cpp1y/lambda-generic-nsdmi1.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-nsdmi1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-nsdmi1.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-nsdmi1.C (revision 259627) @@ -0,0 +1,8 @@ +// PR c++/84520 +// { dg-do compile { target c++14 } } + +struct A +{ + static void foo(int); + void (*f)(int) = [](auto i) { foo(i); }; +}; Index: gcc/testsuite/g++.dg/cpp1y/var-templ58.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ58.C b/gcc/testsuite/g++.dg/cpp1y/var-templ58.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ58.C (revision 259627) @@ -0,0 +1,12 @@ +// PR c++/71569 +// { dg-do compile { target c++14 } } + +template +struct A { + template + static const U u; +}; + +template +template +const U A::u = 0; // { dg-error "does not specialize" } Index: gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic17.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic17.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic17.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic17.C (revision 259627) @@ -0,0 +1,125 @@ +// PR c++/85118 +// { dg-do compile { target c++14 } } + +namespace std +{ + template + struct remove_const + { typedef _Tp type; }; + + template + struct remove_const<_Tp const> + { typedef _Tp type; }; + + + template + struct remove_volatile + { typedef _Tp type; }; + + template + struct remove_volatile<_Tp volatile> + { typedef _Tp type; }; + + + template + struct remove_cv + { + typedef typename + remove_const::type>::type type; + }; + + template + struct remove_reference + { typedef _Tp type; }; + + template + struct remove_reference<_Tp&> + { typedef _Tp type; }; + + template + struct remove_reference<_Tp&&> + { typedef _Tp type; }; + + template + struct decay + { + using type = typename remove_reference::type>::type; + }; + + template + _Tp&& + declval() noexcept; + + template + constexpr _Tp&& + forward(typename std::remove_reference<_Tp>::type& __t) noexcept + { return static_cast<_Tp&&>(__t); } + + + template + struct _Mu + { + template + _CVArg&& + operator()(_CVArg&& __arg, _Tuple&) const volatile + { return std::forward<_CVArg>(__arg); } + }; + + template + struct _Bind + { + _Functor _M_f; + _Bound_args _M_bound_args; + + template()( + _Mu<_Bound_args>()( std::declval<_Bound_args&>(), + std::declval<_Args&>() ) ) )> + _Result + operator()(_Args&& __args) { return {}; } + + template()( + _Mu<_Bound_args>()( std::declval(), + std::declval<_Args&>() ) ) )> + _Result + operator()(_Args&& __args) volatile; + + }; + + template + _Bind::type, typename decay<_BoundArgs>::type> + bind(_Func&& __f, _BoundArgs&& __args) + { + return { + std::forward<_Func>(__f), + std::forward<_BoundArgs>(__args) + }; + } + +} // namespace std + + +template +bool isOneOf(const T& ) +{ + return false; +} + +template +bool isOneOf(const T& t, const FirstType& firstValue, const Tail&... tail) +{ + return t == firstValue || isOneOf(t, tail...); +} + +int main() +{ + const auto isOneOfHelper = [](auto&&... params) + { + return isOneOf(std::forward(params)...); + }; + + auto isO = std::bind(isOneOfHelper, 'o'); + + isO('o'); +} Index: gcc/testsuite/g++.dg/cpp1y/pr83817.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/pr83817.C b/gcc/testsuite/g++.dg/cpp1y/pr83817.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/pr83817.C (revision 259627) @@ -0,0 +1,17 @@ +// PR c++/83817 +// { dg-do compile { target c++14 } } + +struct A; +struct B { template using C = A; }; +struct D : B { struct F { typedef C E; }; }; +struct G { + struct I { I (D, A &); } h; + D::F::E &k (); + D j; + G (G &&) : h (j, k ()) {} +}; +struct N { G l; }; +typedef N (*M)(N &); +struct H { const char *o; M s; }; +N foo (N &); +H r { "", [](auto &x) { return foo (x); }}; Index: gcc/testsuite/g++.dg/cpp1y/constexpr-84192.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-84192.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-84192.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-84192.C (revision 259627) @@ -0,0 +1,41 @@ +// PR c++/84192 +// { dg-do compile { target c++14 } } +// { dg-options "" } + +bool +f1 () +{ + return ({ return true; }) && false; // { dg-error "could not convert" } +} + +void +f2 () +{ + for (;;) + constexpr bool b = ({ break; false; }) && false; // { dg-error "statement is not a constant expression" } +} + +constexpr bool +f3 (int n) +{ + bool b = false; + for (int i = 0; i < n; i++) + b = ({ break; }); // { dg-error "void value not ignored as it ought to be" } + return b; +} + +constexpr bool b = f3 (4); + +bool +f4 () +{ + constexpr bool b = ({ return true; }) && false; // { dg-error "could not convert" } + return false; +} + +constexpr bool +f5 (int x) +{ + constexpr bool b = ({ switch (x) case 0: true; }) && false; // { dg-error "could not convert" } + return false; +} Index: gcc/testsuite/g++.dg/cpp1y/var-templ59.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ59.C b/gcc/testsuite/g++.dg/cpp1y/var-templ59.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ59.C (revision 259627) @@ -0,0 +1,14 @@ +// PR c++/71569 +// { dg-do compile { target c++14 } } + +template +struct A { + template + static U u; +}; + +int main() +{ + decltype(A::u) a; // { dg-error "missing template arguments" } + return a; +} Index: gcc/testsuite/g++.dg/cpp1y/pr60393.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60393.C b/gcc/testsuite/g++.dg/cpp1y/pr60393.C --- a/gcc/testsuite/g++.dg/cpp1y/pr60393.C (revision 257042) +++ b/gcc/testsuite/g++.dg/cpp1y/pr60393.C (revision 259627) @@ -1,8 +1,7 @@ // PR c++/60393 // { dg-do compile { target c++14 } } -// { dg-options "" } -void (*f)(auto) + 0; // { dg-error "expected" } +void (*f)(auto) + 0; // { dg-error "auto|expected" } struct A { Index: gcc/testsuite/g++.dg/cpp1z/decomp-lambda1.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp-lambda1.C b/gcc/testsuite/g++.dg/cpp1z/decomp-lambda1.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/decomp-lambda1.C (revision 259627) @@ -0,0 +1,10 @@ +// PR c++/84420 +// { dg-additional-options -std=c++17 } + +int main(){ + int a[1]{}; + [&a]{ + auto [v] = a; + (void)v; + }(); +} Index: gcc/testsuite/g++.dg/cpp1z/noexcept-type19.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type19.C b/gcc/testsuite/g++.dg/cpp1z/noexcept-type19.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type19.C (revision 259627) @@ -0,0 +1,12 @@ +// { dg-do compile { target c++11 } } + +#include "noexcept-type19.h" + +extern "C" void *malloc (size_t); + +template void f(T*); + +int main() +{ + f(operator new); +} Index: gcc/testsuite/g++.dg/cpp1z/class-deduction51.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction51.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction51.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction51.C (revision 259627) @@ -0,0 +1,11 @@ +// PR c++/84937 +// { dg-additional-options -std=c++17 } + +template struct A {}; + +template struct B +{ + template B(A); +}; + +B b(A<0,0>{}); Index: gcc/testsuite/g++.dg/cpp1z/launder7.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/launder7.C b/gcc/testsuite/g++.dg/cpp1z/launder7.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/launder7.C (revision 259627) @@ -0,0 +1,10 @@ +// PR c++/84445 +// { dg-do compile } + +struct A { virtual void foo (); }; + +void +bar (A *p) +{ + __builtin_launder (p)->foo (); +} Index: gcc/testsuite/g++.dg/cpp1z/noexcept-type19.h =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type19.h b/gcc/testsuite/g++.dg/cpp1z/noexcept-type19.h new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type19.h (revision 259627) @@ -0,0 +1,4 @@ +#pragma GCC system_header + +typedef decltype(sizeof(0)) size_t; +extern "C" void *malloc (size_t) throw(); Index: gcc/testsuite/g++.dg/cpp1z/decomp4.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp4.C b/gcc/testsuite/g++.dg/cpp1z/decomp4.C --- a/gcc/testsuite/g++.dg/cpp1z/decomp4.C (revision 257042) +++ b/gcc/testsuite/g++.dg/cpp1z/decomp4.C (revision 259627) @@ -18,10 +18,10 @@ // { dg-warning "decomposition declaration only available with -std=c..1z or -std=gnu..1z" "" { target c++14_down } .-1 } auto [ k ] { b }; // { dg-error "cannot decompose class type 'B' because it has an anonymous union member" } // { dg-warning "decomposition declaration only available with -std=c..1z or -std=gnu..1z" "" { target c++14_down } .-1 } - auto [ l, l2 ] = c; // { dg-error "cannot decompose non-public member 'C::b' of 'C'" } + auto [ l, l2 ] = c; // { dg-error "cannot decompose inaccessible member 'C::b' of 'C'" } // { dg-warning "decomposition declaration only available with -std=c..1z or -std=gnu..1z" "" { target c++14_down } .-1 } auto [ m ] = d; // { dg-warning "decomposition declaration only available with -std=c..1z or -std=gnu..1z" "" { target c++14_down } } - auto [ n ] { e }; // { dg-error "cannot decompose non-public member 'E::a' of 'E'" } + auto [ n ] { e }; // { dg-error "cannot decompose inaccessible member 'E::a' of 'E'" } // { dg-warning "decomposition declaration only available with -std=c..1z or -std=gnu..1z" "" { target c++14_down } .-1 } auto [ o ] { f }; // { dg-warning "decomposition declaration only available with -std=c..1z or -std=gnu..1z" "" { target c++14_down } } auto & [ p ] { g }; // { dg-error "cannot decompose class type 'G': both it and its base class 'F' have non-static data members" } Index: gcc/testsuite/g++.dg/cpp1z/launder8.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/launder8.C b/gcc/testsuite/g++.dg/cpp1z/launder8.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/launder8.C (revision 259627) @@ -0,0 +1,11 @@ +// PR c++/84444 +// { dg-do compile } +// { dg-options "-O2" } + +struct A {}; + +__UINTPTR_TYPE__ +foo (A *p) +{ + return (__UINTPTR_TYPE__) __builtin_launder (p); +} Index: gcc/testsuite/g++.dg/cpp1z/constexpr-84684.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-84684.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-84684.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-84684.C (revision 259627) @@ -0,0 +1,163 @@ +// PR c++/84684 +// { dg-options -std=c++17 } + +typedef decltype (sizeof (0)) size_t; + +namespace std { + template + struct initializer_list + { + typedef _E value_type; + typedef const _E& reference; + typedef const _E& const_reference; + typedef size_t size_type; + typedef const _E* iterator; + typedef const _E* const_iterator; + iterator _M_array; + size_type _M_len; + constexpr initializer_list(const_iterator __a, size_type __l) : _M_array(__a), _M_len(__l) { } + constexpr initializer_list() noexcept : _M_array(0), _M_len(0) { } + constexpr size_type size() const noexcept { return _M_len; } + constexpr const_iterator begin() const noexcept { return _M_array; } + constexpr const_iterator end() const noexcept { return begin() + size(); } + }; +} + +template +struct array +{ + constexpr E &operator[](size_t n) noexcept { return elems[n]; } + constexpr const E &operator[](size_t n) const noexcept { return elems[n]; } + constexpr size_t size() const { return N; } + E elems[N]; +}; + +template +constexpr +inline T +max (std::initializer_list i) +{ + const T *b = i.begin (); + const T *e = i.end (); + if (b == e) return *b; + const T *r = b; + while (++b != e) + if (*r < *b) + r = b; + return *r; +} + +template +constexpr char to_char(alphabet_type const alph) +{ + return alph.to_char(); +} + +template +struct union_composition +{ + static constexpr size_t value_size = (alphabet_types::value_size + ... ); + unsigned char _value; + template + static constexpr auto value_to_char_helper(alphabet_t alphabet) + { + array value_to_char{}; + for (size_t i = 0u; i < alphabet_t::value_size; ++i) + value_to_char[i] = to_char(alphabet.assign_rank(i)); + return value_to_char; + } + + static constexpr auto make_value_to_char() + { + constexpr auto N = sizeof...(alphabet_types); + constexpr array alphabet_sizes { alphabet_types::value_size... }; + constexpr size_t fixed_size = max({alphabet_types::value_size...}); + array value_to_char_tables = array, N> { + value_to_char_helper(alphabet_types{})... + }; + array value_to_char{}; + for (size_t i = 0u, value = 0u; i < N; ++i) + for (size_t k = 0u; k < alphabet_sizes[i]; ++k, ++value) + value_to_char[value] = value_to_char_tables[i][k]; + return value_to_char; + } +}; + +struct gap +{ + constexpr char to_char() const noexcept { return '-'; } + constexpr gap & assign_rank([[maybe_unused]] bool const i) noexcept { return *this; } + static constexpr size_t value_size{1}; +}; + +struct dna4 +{ + constexpr char to_char() const noexcept { return value_to_char[_value]; } + constexpr dna4 & assign_rank(unsigned char const c) { _value = c; return *this; } + static constexpr size_t value_size{4}; + static constexpr char value_to_char[value_size] { 'A', 'C', 'G', 'T' }; + unsigned char _value; +}; + +struct dna5 +{ + constexpr char to_char() const noexcept { return value_to_char[_value]; } + constexpr dna5 & assign_rank(unsigned char const c) { _value = c; return *this; } + static constexpr size_t value_size{5}; + static constexpr char value_to_char[value_size] { 'A', 'C', 'G', 'T', 'N' }; + unsigned char _value; +}; + +constexpr array value_to_char1 = union_composition::make_value_to_char(); +static_assert(value_to_char1.size() == 4u); +static_assert(value_to_char1[0] == 'A'); +static_assert(value_to_char1[1] == 'C'); +static_assert(value_to_char1[2] == 'G'); +static_assert(value_to_char1[3] == 'T'); + +constexpr array value_to_char2 = union_composition::make_value_to_char(); +static_assert(value_to_char2.size() == 5u); +static_assert(value_to_char2[0] == 'A'); +static_assert(value_to_char2[1] == 'C'); +static_assert(value_to_char2[2] == 'G'); +static_assert(value_to_char2[3] == 'T'); +static_assert(value_to_char2[4] == '-'); + +constexpr array value_to_char3 = union_composition::make_value_to_char(); +static_assert(value_to_char3.size() == 10u); +static_assert(value_to_char3[0] == 'A'); +static_assert(value_to_char3[1] == 'C'); +static_assert(value_to_char3[2] == 'G'); +static_assert(value_to_char3[3] == 'T'); +static_assert(value_to_char3[4] == '-'); +static_assert(value_to_char3[5] == 'A'); +static_assert(value_to_char3[6] == 'C'); +static_assert(value_to_char3[7] == 'G'); +static_assert(value_to_char3[8] == 'T'); +static_assert(value_to_char3[9] == 'N'); + +constexpr array value_to_char4 = union_composition::make_value_to_char(); +static_assert(value_to_char4.size() == 10u); +static_assert(value_to_char4[0] == 'A'); +static_assert(value_to_char4[1] == 'C'); +static_assert(value_to_char4[2] == 'G'); +static_assert(value_to_char4[3] == 'T'); +static_assert(value_to_char4[4] == 'N'); +static_assert(value_to_char4[5] == '-'); +static_assert(value_to_char4[6] == 'A'); +static_assert(value_to_char4[7] == 'C'); +static_assert(value_to_char4[8] == 'G'); +static_assert(value_to_char4[9] == 'T'); + +constexpr array value_to_char5 = union_composition::make_value_to_char(); +static_assert(value_to_char5.size() == 10u); +static_assert(value_to_char5[0] == '-'); +static_assert(value_to_char5[1] == 'A'); +static_assert(value_to_char5[2] == 'C'); +static_assert(value_to_char5[3] == 'G'); +static_assert(value_to_char5[4] == 'T'); +static_assert(value_to_char5[5] == 'A'); +static_assert(value_to_char5[6] == 'C'); +static_assert(value_to_char5[7] == 'G'); +static_assert(value_to_char5[8] == 'T'); +static_assert(value_to_char5[9] == 'N'); Index: gcc/testsuite/g++.dg/cpp1z/constexpr-if13.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if13.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if13.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if13.C (revision 259627) @@ -0,0 +1,11 @@ +// PR c++/84854 +// { dg-options -std=c++17 } + +constexpr int foo () { return 1; } +constexpr int foo (int) { return 2; } + +template +void a() +{ + if constexpr(foo) { }; +} Index: gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C b/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C --- a/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C (revision 257042) +++ b/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C (revision 259627) @@ -1,17 +1,19 @@ // { dg-do run { target c++11 } } // PR78495 failed to propagate pass-by-value struct to base ctor. +static int moves = 0; + struct Ptr { void *ptr = 0; Ptr() {} Ptr(Ptr const&) = delete; - Ptr(Ptr&& other) : ptr (other.ptr) {} + Ptr(Ptr&& other) : ptr (other.ptr) {moves++;} }; struct Base { Ptr val; - Base(Ptr val_) : val(static_cast(val_)) {} + Base(Ptr val_); }; struct Derived: Base { @@ -27,5 +29,13 @@ } int main () { - return Foo () != 0; + if (Foo ()) + return 1; + + if (moves != 2) + return 2; + + return 0; } + +Base::Base(Ptr val_) : val(static_cast(val_)) {} Index: gcc/testsuite/g++.dg/cpp1z/class-deduction54.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction54.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction54.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction54.C (revision 259627) @@ -0,0 +1,15 @@ +// PR c++/82152 +// { dg-additional-options -std=c++17 } + +struct Base {}; + +template +struct Derived : public Base { + using Base::Base; +}; + +Derived() -> Derived< void >; + +int main() { + Derived x; +} Index: gcc/testsuite/g++.dg/cpp1z/decomp10.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp10.C b/gcc/testsuite/g++.dg/cpp1z/decomp10.C --- a/gcc/testsuite/g++.dg/cpp1z/decomp10.C (revision 257042) +++ b/gcc/testsuite/g++.dg/cpp1z/decomp10.C (revision 259627) @@ -20,7 +20,7 @@ struct A3a { int i,j; int get(); } a3a; template<> struct std::tuple_size { enum { value = 1 }; }; -void f3a() { auto [ x ] = a3a; } // { dg-error "get<0>" } +void f3a() { auto [ x ] = a3a; } // { dg-error "get" } struct A3b { int i,j; } a3b; int get(A3b&&); Index: gcc/testsuite/g++.dg/cpp1z/decomp35.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp35.C b/gcc/testsuite/g++.dg/cpp1z/decomp35.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/decomp35.C (revision 259627) @@ -0,0 +1,35 @@ +// PR c++/83958 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +template struct A; +class B; +template > class C; +template struct D; +template +struct E { + using X = W; + X operator* (); + T operator++ (); + template + bool operator!= (E); +}; +template +struct F { + class G; + using H = D; + using I = E; + class G : public I {}; + G begin (); + G end (); +}; +template struct C : F { + using J = F; + using J::begin; + using J::end; +}; +using K = class L; +struct M { + void foo () { for (auto & [ a ] : m) {} } // { dg-error "incomplete type" } + C m; // { dg-warning "only available with" "" { target c++14_down } .-1 } +}; Index: gcc/testsuite/g++.dg/cpp1z/decomp36.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp36.C b/gcc/testsuite/g++.dg/cpp1z/decomp36.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/decomp36.C (revision 259627) @@ -0,0 +1,19 @@ +// PR c++/84031 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct A { unsigned char : 1, a1 : 1, a2 : 2, : 1, a3 : 3; }; +struct B { unsigned char : 1, : 7; }; +struct C : B { constexpr C () : c1 (1), c2 (2), c3 (3) {} unsigned char : 1, c1 : 1, c2 : 2, : 1, c3 : 3; }; +struct D : C { constexpr D () {} unsigned char : 1, : 7; }; + +int +main () +{ + static constexpr A a { 1, 2, 3 }; + const auto &[a1, a2, a3] = a; // { dg-warning "only available with" "" { target c++14_down } } + static_assert (a1 == 1 && a2 == 2 && a3 == 3, ""); + static constexpr D d; + const auto &[d1, d2, d3] = d; // { dg-warning "only available with" "" { target c++14_down } } + static_assert (d1 == 1 && d2 == 2 && d3 == 3, ""); +} Index: gcc/testsuite/g++.dg/cpp1z/decomp37.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp37.C b/gcc/testsuite/g++.dg/cpp1z/decomp37.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/decomp37.C (revision 259627) @@ -0,0 +1,62 @@ +// { dg-additional-options -std=c++17 } +// { dg-do compile } + +#include +#include +#include + +struct X : private std::shared_ptr +{ + std::string fun_payload; +}; + +template std::string& get(X& x) +{ + if constexpr(N==0) return x.fun_payload; +} + +namespace std { + template<> class tuple_size : public std::integral_constant {}; + template<> class tuple_element<0, X> {public: using type = std::string;}; +} + +struct X2 : private std::shared_ptr +{ + int fun_payload; + template void get(); +}; + +template int& get(X2& x) +{ + if constexpr(N==0) return x.fun_payload; +} + +namespace std { + template<> class tuple_size : public std::integral_constant {}; + template<> class tuple_element<0, X2> {public: using type = int;}; +} + +class X3 +{ + double fun_payload; +public: + template double& get() + { + if constexpr(N==0) return fun_payload; + } +}; + +namespace std { + template<> class tuple_size : public std::integral_constant {}; + template<> class tuple_element<0, X3> {public: using type = double;}; +} + +int main() +{ + X x; + auto& [b1] = x; + X2 x2; + auto& [b2] = x2; + X3 x3; + auto& [b3] = x3; +} Index: gcc/testsuite/g++.dg/cpp1z/decomp38.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp38.C b/gcc/testsuite/g++.dg/cpp1z/decomp38.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/decomp38.C (revision 259627) @@ -0,0 +1,48 @@ +// { dg-additional-options -std=c++17 } +// { dg-do compile } + +class X +{ + int a, b; + void f() + { + auto[x,y] = *this; + } +}; + +class X2 +{ + int a, b; + void f(X2& other) + { + auto[x,y] = other; + } +}; + +struct X3 +{ + friend void foo(); +private: + int a; +}; + +void foo() +{ + X3 x; + auto [a] = x; +} + +struct X4 +{ + int a; +}; + +struct X5 : private X4 +{ + friend void foo2(); +}; + +void foo2() { + X5 x; + auto [a] = x; +} Index: gcc/testsuite/g++.dg/cpp1z/class-deduction49.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction49.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction49.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction49.C (revision 259627) @@ -0,0 +1,15 @@ +// PR c++/84015 +// { dg-additional-options -std=c++17 } + +template +struct A { }; + +template +struct B +{ + templateclass T> + B(T); +}; + +A<42> a; +B b (a); Index: gcc/testsuite/g++.dg/cpp1z/class-deduction50.C =================================================================== diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction50.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction50.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction50.C (revision 259627) @@ -0,0 +1,22 @@ +// PR c++/84355 +// { dg-additional-options -std=c++17 } + +template struct same; +template struct same {}; + +template struct A +{ + template struct B + { + B(U); + }; + + A() { + B b(0); + same>{}; + } +}; + +struct C {}; + +A a; Index: gcc/testsuite/g++.dg/ext/is_trivially_constructible6.C =================================================================== diff --git a/gcc/testsuite/g++.dg/ext/is_trivially_constructible6.C b/gcc/testsuite/g++.dg/ext/is_trivially_constructible6.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/ext/is_trivially_constructible6.C (revision 259627) @@ -0,0 +1,10 @@ +// PR c++/81589 + +template +struct z { + z() { + k::error; + } +}; + +int x = __is_trivially_constructible(z); Index: gcc/testsuite/g++.dg/ext/stmtexpr22.C =================================================================== diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr22.C b/gcc/testsuite/g++.dg/ext/stmtexpr22.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/ext/stmtexpr22.C (revision 259627) @@ -0,0 +1,13 @@ +// PR c++/81853 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +namespace N { + enum { i }; +} + +int g () +{ + constexpr int j = ({ using namespace N; i; }); + return j; +} Index: gcc/testsuite/g++.dg/ext/builtin12.C =================================================================== diff --git a/gcc/testsuite/g++.dg/ext/builtin12.C b/gcc/testsuite/g++.dg/ext/builtin12.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/ext/builtin12.C (revision 259627) @@ -0,0 +1,10 @@ +// PR c++/85113 +// { dg-do compile { target c++14 } } + +template struct A {}; + +constexpr int foo() +{ + A<__builtin_constant_p(0)> a{}; + return 0; +} Index: gcc/testsuite/g++.dg/ext/attr-noinline-4.C =================================================================== diff --git a/gcc/testsuite/g++.dg/ext/attr-noinline-4.C b/gcc/testsuite/g++.dg/ext/attr-noinline-4.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/ext/attr-noinline-4.C (revision 259627) @@ -0,0 +1,10 @@ +// PR c++/84665 + +struct S {} a[1]; + +template +void +foo () +{ + __attribute__ ((noinline (a[0]))) int c = 0; // { dg-error "wrong number of arguments" } +} Index: gcc/testsuite/g++.dg/vect/pr84556.cc =================================================================== diff --git a/gcc/testsuite/g++.dg/vect/pr84556.cc b/gcc/testsuite/g++.dg/vect/pr84556.cc new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/vect/pr84556.cc (revision 259627) @@ -0,0 +1,21 @@ +// PR c++/84556 +// { dg-do run { target c++11 } } +// { dg-options "-O2 -fopenmp-simd" } +// { dg-additional-options "-mavx" { target avx_runtime } } + +int +main () +{ + int y[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + auto x = [&y] () + { + #pragma omp simd + for (int i = 0; i < 8; ++i) + y[i]++; + }; + x (); + x (); + for (int i = 0; i < 8; ++i) + if (y[i] != i + 3) + __builtin_abort (); +} Index: gcc/testsuite/g++.dg/gomp/pr84556.C =================================================================== diff --git a/gcc/testsuite/g++.dg/gomp/pr84556.C b/gcc/testsuite/g++.dg/gomp/pr84556.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/gomp/pr84556.C (revision 259627) @@ -0,0 +1,14 @@ +// PR c++/84556 +// { dg-do compile } +// { dg-options "-std=c++17 -fopenmp-simd" } + +void +foo () +{ + auto x = [] () + { + #pragma omp simd + for (int i = 0; i < 8; ++i) + ; + }; +} Index: gcc/testsuite/g++.dg/gomp/pr84430.C =================================================================== diff --git a/gcc/testsuite/g++.dg/gomp/pr84430.C b/gcc/testsuite/g++.dg/gomp/pr84430.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/gomp/pr84430.C (revision 259627) @@ -0,0 +1,12 @@ +// PR c++/84430 +// { dg-do compile { target c++11 } } + +void +foo () +{ + auto a = [] { + #pragma omp simd + for (int i = 0; i < 10; ++i) + ; + }; +} Index: gcc/testsuite/g++.dg/gomp/pr84557.C =================================================================== diff --git a/gcc/testsuite/g++.dg/gomp/pr84557.C b/gcc/testsuite/g++.dg/gomp/pr84557.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/gomp/pr84557.C (revision 259627) @@ -0,0 +1,14 @@ +// PR c++/84557 +// { dg-do compile } + +template struct A {}; +template struct B {}; + +void +foo () +{ + #pragma omp parallel firstprivate (A) // { dg-error "is not a variable in clause" } + ; + #pragma omp parallel firstprivate (B<0>) // { dg-error "is not a variable in clause" } + ; +} Index: gcc/testsuite/g++.dg/gomp/pr84448.C =================================================================== diff --git a/gcc/testsuite/g++.dg/gomp/pr84448.C b/gcc/testsuite/g++.dg/gomp/pr84448.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/gomp/pr84448.C (revision 259627) @@ -0,0 +1,17 @@ +// PR c++/84448 +// { dg-do compile } + +struct A +{ + operator int () const; + A& operator += (int); + A& operator ++ (); +}; + +void +foo (A a, A b) +{ + #pragma omp for + for (A i = a; i <=; ++i) // { dg-error "expected primary-expression before" } + ; // { dg-error "invalid controlling predicate" "" { target *-*-* } .-1 } +} Index: gcc/testsuite/g++.dg/init/pr83993-2.C =================================================================== diff --git a/gcc/testsuite/g++.dg/init/pr83993-2.C b/gcc/testsuite/g++.dg/init/pr83993-2.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/init/pr83993-2.C (revision 259627) @@ -0,0 +1,14 @@ +// PR c++/83993 +// { dg-do compile } +// { dg-options "-w" } + +int a[5]; +extern int b[]; +int *const c = &a[6]; +int *const d = &b[1]; + +int +foo () +{ + return c[-4] + d[-1]; +} Index: gcc/testsuite/g++.dg/init/new44.C =================================================================== diff --git a/gcc/testsuite/g++.dg/init/new44.C b/gcc/testsuite/g++.dg/init/new44.C --- a/gcc/testsuite/g++.dg/init/new44.C (revision 257042) +++ b/gcc/testsuite/g++.dg/init/new44.C (revision 259627) @@ -87,10 +87,10 @@ static void __attribute__ ((used)) test_two_dim_char_array () { - p = new char [1][MAX]; // { dg-error "size of unnamed array" } - p = new char [1][MAX - 1]; // { dg-error "size of unnamed array" } - p = new char [1][MAX - 2]; // { dg-error "size of unnamed array" } - p = new char [1][MAX - 99]; // { dg-error "size of unnamed array" } + p = new char [1][MAX]; // { dg-error "size of (unnamed )?array" } + p = new char [1][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new char [1][MAX - 2]; // { dg-error "size of (unnamed )?array" } + p = new char [1][MAX - 99]; // { dg-error "size of (unnamed )?array" } p = new char [1][MAX / 2]; // { dg-error "size of array" } p = new char [1][MAX / 2 - 1]; // { dg-error "size of array" } p = new char [1][MAX / 2 - 2]; // { dg-error "size of array" } @@ -104,9 +104,9 @@ p = new char [1][MAX / 2 - 7]; // okay p = new char [1][MAX / 2 - 8]; // okay - p = new char [2][MAX]; // { dg-error "size of unnamed array" } - p = new char [2][MAX - 1]; // { dg-error "size of unnamed array" } - p = new char [2][MAX - 2]; // { dg-error "size of unnamed array" } + p = new char [2][MAX]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX - 2]; // { dg-error "size of (unnamed )?array" } p = new char [2][MAX / 2]; // { dg-error "size of array" } p = new char [2][MAX / 2 - 1]; // { dg-error "size of array" } p = new char [2][MAX / 2 - 2]; // { dg-error "size of array" } @@ -113,9 +113,9 @@ p = new char [2][MAX / 2 - 7]; // { dg-error "size of array" } p = new char [2][MAX / 2 - 8]; // { dg-error "size of array" } - p = new char [MAX][MAX]; // { dg-error "size of unnamed array" } - p = new char [MAX][MAX - 1]; // { dg-error "size of unnamed array" } - p = new char [MAX][MAX - 2]; // { dg-error "size of unnamed array" } + p = new char [MAX][MAX]; // { dg-error "size of (unnamed )?array" } + p = new char [MAX][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new char [MAX][MAX - 2]; // { dg-error "size of (unnamed )?array" } p = new char [MAX][MAX / 2]; // { dg-error "size of array" } p = new char [MAX][MAX / 2 - 1]; // { dg-error "size of array" } p = new char [MAX][MAX / 2 - 2]; // { dg-error "size of array" } @@ -142,10 +142,10 @@ static __attribute__ ((used)) void test_three_dim_char_array () { - p = new char [1][1][MAX]; // { dg-error "size of unnamed array" } - p = new char [1][1][MAX - 1]; // { dg-error "size of unnamed array" } - p = new char [1][1][MAX - 2]; // { dg-error "size of unnamed array" } - p = new char [1][1][MAX - 99]; // { dg-error "size of unnamed array" } + p = new char [1][1][MAX]; // { dg-error "size of (unnamed )?array" } + p = new char [1][1][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new char [1][1][MAX - 2]; // { dg-error "size of (unnamed )?array" } + p = new char [1][1][MAX - 99]; // { dg-error "size of (unnamed )?array" } p = new char [1][1][MAX / 2]; // { dg-error "size of array" } p = new char [1][1][MAX / 2 - 1]; // { dg-error "size of array" } p = new char [1][1][MAX / 2 - 2]; // { dg-error "size of array" } @@ -159,19 +159,19 @@ p = new char [1][1][MAX / 2 - 7]; // okay p = new char [1][1][MAX / 2 - 8]; // okay - p = new char [1][2][MAX]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX - 1]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX - 2]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX - 99]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX / 2]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX / 2 - 1]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX / 2 - 2]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX / 2 - 3]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX / 2 - 4]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX / 2 - 5]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX / 2 - 6]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX / 2 - 7]; // { dg-error "size of unnamed array" } - p = new char [1][2][MAX / 2 - 8]; // { dg-error "size of unnamed array" } + p = new char [1][2][MAX]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX - 2]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX - 99]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX / 2]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX / 2 - 1]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX / 2 - 2]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX / 2 - 3]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX / 2 - 4]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX / 2 - 5]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX / 2 - 6]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX / 2 - 7]; // { dg-error "size of (unnamed )?array" } + p = new char [1][2][MAX / 2 - 8]; // { dg-error "size of (unnamed )?array" } p = new char [1][2][MAX / 4]; // { dg-error "size of array" } // Avoid exercising data model-dependent expressions. @@ -181,10 +181,10 @@ p = new char [1][2][MAX / 4 - 3]; // okay p = new char [1][2][MAX / 4 - 4]; // okay - p = new char [2][1][MAX]; // { dg-error "size of unnamed array" } - p = new char [2][1][MAX - 1]; // { dg-error "size of unnamed array" } - p = new char [2][1][MAX - 2]; // { dg-error "size of unnamed array" } - p = new char [2][1][MAX - 99]; // { dg-error "size of unnamed array" } + p = new char [2][1][MAX]; // { dg-error "size of (unnamed )?array" } + p = new char [2][1][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new char [2][1][MAX - 2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][1][MAX - 99]; // { dg-error "size of (unnamed )?array" } p = new char [2][1][MAX / 2]; // { dg-error "size of array" } p = new char [2][1][MAX / 2 - 1]; // { dg-error "size of array" } p = new char [2][1][MAX / 2 - 2]; // { dg-error "size of array" } @@ -203,19 +203,19 @@ p = new char [2][1][MAX / 4 - 3]; // okay p = new char [2][1][MAX / 4 - 4]; // okay - p = new char [2][2][MAX]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX - 1]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX - 2]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX - 99]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX / 2]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX / 2 - 1]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX / 2 - 2]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX / 2 - 3]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX / 2 - 4]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX / 2 - 5]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX / 2 - 6]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX / 2 - 7]; // { dg-error "size of unnamed array" } - p = new char [2][2][MAX / 2 - 8]; // { dg-error "size of unnamed array" } + p = new char [2][2][MAX]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX - 2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX - 99]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX / 2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX / 2 - 1]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX / 2 - 2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX / 2 - 3]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX / 2 - 4]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX / 2 - 5]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX / 2 - 6]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX / 2 - 7]; // { dg-error "size of (unnamed )?array" } + p = new char [2][2][MAX / 2 - 8]; // { dg-error "size of (unnamed )?array" } p = new char [2][2][MAX / 4]; // { dg-error "size of array" } p = new char [2][2][MAX / 4 - 1]; // { dg-error "size of array" } p = new char [2][2][MAX / 4 - 2]; // { dg-error "size of array" } @@ -227,19 +227,19 @@ p = new char [2][2][MAX / 8 - 2]; p = new char [2][2][MAX / 8 - 3]; - p = new char [2][MAX][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX - 1][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX - 2][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX - 99][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX / 2][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX / 2 - 1][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX / 2 - 2][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX / 2 - 3][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX / 2 - 4][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX / 2 - 5][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX / 2 - 6][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX / 2 - 7][2]; // { dg-error "size of unnamed array" } - p = new char [2][MAX / 2 - 8][2]; // { dg-error "size of unnamed array" } + p = new char [2][MAX][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX - 1][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX - 2][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX - 99][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX / 2][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX / 2 - 1][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX / 2 - 2][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX / 2 - 3][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX / 2 - 4][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX / 2 - 5][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX / 2 - 6][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX / 2 - 7][2]; // { dg-error "size of (unnamed )?array" } + p = new char [2][MAX / 2 - 8][2]; // { dg-error "size of (unnamed )?array" } p = new char [2][MAX / 4][2]; // { dg-error "size of array" } p = new char [2][MAX / 4 - 1][2]; // { dg-error "size of array" } p = new char [2][MAX / 4 - 2][2]; // { dg-error "size of array" } @@ -275,11 +275,11 @@ p = new char [MAX / 8 - 2][2][2]; p = new char [MAX / 8 - 3][2][2]; - p = new char [MAX][MAX][MAX]; // { dg-error "size of unnamed array" } - p = new char [MAX][MAX][MAX / 2]; // { dg-error "size of unnamed array" } - p = new char [MAX][MAX / 2][MAX]; // { dg-error "size of unnamed array" } - p = new char [MAX][MAX / 2][MAX / 2]; // { dg-error "size of unnamed array" } - p = new char [MAX / 2][MAX / 2][MAX / 2]; // { dg-error "size of unnamed array" } + p = new char [MAX][MAX][MAX]; // { dg-error "size of (unnamed )?array" } + p = new char [MAX][MAX][MAX / 2]; // { dg-error "size of (unnamed )?array" } + p = new char [MAX][MAX / 2][MAX]; // { dg-error "size of (unnamed )?array" } + p = new char [MAX][MAX / 2][MAX / 2]; // { dg-error "size of (unnamed )?array" } + p = new char [MAX / 2][MAX / 2][MAX / 2]; // { dg-error "size of (unnamed )?array" } } // Exercise new expression with N-dimensional arrays where N is @@ -342,10 +342,10 @@ static void __attribute__ ((used)) test_placement_two_dim_byte_struct_array (void *p) { - p = new (p) B [1][MAX]; // { dg-error "size of unnamed array" } - p = new (p) B [1][MAX - 1]; // { dg-error "size of unnamed array" } - p = new (p) B [1][MAX - 2]; // { dg-error "size of unnamed array" } - p = new (p) B [1][MAX - 99]; // { dg-error "size of unnamed array" } + p = new (p) B [1][MAX]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][MAX - 2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][MAX - 99]; // { dg-error "size of (unnamed )?array" } p = new (p) B [1][MAX / 2]; // { dg-error "size of array" } p = new (p) B [1][MAX / 2 - 1]; // { dg-error "size of array" } p = new (p) B [1][MAX / 2 - 2]; // { dg-error "size of array" } @@ -359,9 +359,9 @@ p = new (p) B [1][MAX / 2 - 7]; // okay p = new (p) B [1][MAX / 2 - 8]; // okay - p = new (p) B [2][MAX]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX - 1]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX - 2]; // { dg-error "size of unnamed array" } + p = new (p) B [2][MAX]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX - 2]; // { dg-error "size of (unnamed )?array" } p = new (p) B [2][MAX / 2]; // { dg-error "size of array" } p = new (p) B [2][MAX / 2 - 1]; // { dg-error "size of array" } p = new (p) B [2][MAX / 2 - 2]; // { dg-error "size of array" } @@ -368,9 +368,9 @@ p = new (p) B [2][MAX / 2 - 7]; // { dg-error "size of array" } p = new (p) B [2][MAX / 2 - 8]; // { dg-error "size of array" } - p = new (p) B [MAX][MAX]; // { dg-error "size of unnamed array" } - p = new (p) B [MAX][MAX - 1]; // { dg-error "size of unnamed array" } - p = new (p) B [MAX][MAX - 2]; // { dg-error "size of unnamed array" } + p = new (p) B [MAX][MAX]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [MAX][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [MAX][MAX - 2]; // { dg-error "size of (unnamed )?array" } p = new (p) B [MAX][MAX / 2]; // { dg-error "size of array" } p = new (p) B [MAX][MAX / 2 - 1]; // { dg-error "size of array" } p = new (p) B [MAX][MAX / 2 - 2]; // { dg-error "size of array" } @@ -397,10 +397,10 @@ static __attribute__ ((used)) void test_placement_three_dim_byte_struct_array (void *p) { - p = new (p) B [1][1][MAX]; // { dg-error "size of unnamed array" } - p = new (p) B [1][1][MAX - 1]; // { dg-error "size of unnamed array" } - p = new (p) B [1][1][MAX - 2]; // { dg-error "size of unnamed array" } - p = new (p) B [1][1][MAX - 99]; // { dg-error "size of unnamed array" } + p = new (p) B [1][1][MAX]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][1][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][1][MAX - 2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][1][MAX - 99]; // { dg-error "size of (unnamed )?array" } p = new (p) B [1][1][MAX / 2]; // { dg-error "size of array" } p = new (p) B [1][1][MAX / 2 - 1]; // { dg-error "size of array" } p = new (p) B [1][1][MAX / 2 - 2]; // { dg-error "size of array" } @@ -414,19 +414,19 @@ p = new (p) B [1][1][MAX / 2 - 7]; // okay p = new (p) B [1][1][MAX / 2 - 8]; // okay - p = new (p) B [1][2][MAX]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX - 1]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX - 2]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX - 99]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX / 2]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX / 2 - 1]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX / 2 - 2]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX / 2 - 3]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX / 2 - 4]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX / 2 - 5]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX / 2 - 6]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX / 2 - 7]; // { dg-error "size of unnamed array" } - p = new (p) B [1][2][MAX / 2 - 8]; // { dg-error "size of unnamed array" } + p = new (p) B [1][2][MAX]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX - 2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX - 99]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX / 2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX / 2 - 1]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX / 2 - 2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX / 2 - 3]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX / 2 - 4]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX / 2 - 5]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX / 2 - 6]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX / 2 - 7]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [1][2][MAX / 2 - 8]; // { dg-error "size of (unnamed )?array" } p = new (p) B [1][2][MAX / 4]; // { dg-error "size of array" } // Avoid exercising data model-dependent expressions. @@ -436,10 +436,10 @@ p = new (p) B [1][2][MAX / 4 - 3]; // okay p = new (p) B [1][2][MAX / 4 - 4]; // okay - p = new (p) B [2][1][MAX]; // { dg-error "size of unnamed array" } - p = new (p) B [2][1][MAX - 1]; // { dg-error "size of unnamed array" } - p = new (p) B [2][1][MAX - 2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][1][MAX - 99]; // { dg-error "size of unnamed array" } + p = new (p) B [2][1][MAX]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][1][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][1][MAX - 2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][1][MAX - 99]; // { dg-error "size of (unnamed )?array" } p = new (p) B [2][1][MAX / 2]; // { dg-error "size of array" } p = new (p) B [2][1][MAX / 2 - 1]; // { dg-error "size of array" } p = new (p) B [2][1][MAX / 2 - 2]; // { dg-error "size of array" } @@ -458,19 +458,19 @@ p = new (p) B [2][1][MAX / 4 - 3]; // okay p = new (p) B [2][1][MAX / 4 - 4]; // okay - p = new (p) B [2][2][MAX]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX - 1]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX - 2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX - 99]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX / 2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX / 2 - 1]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX / 2 - 2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX / 2 - 3]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX / 2 - 4]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX / 2 - 5]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX / 2 - 6]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX / 2 - 7]; // { dg-error "size of unnamed array" } - p = new (p) B [2][2][MAX / 2 - 8]; // { dg-error "size of unnamed array" } + p = new (p) B [2][2][MAX]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX - 1]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX - 2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX - 99]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX / 2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX / 2 - 1]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX / 2 - 2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX / 2 - 3]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX / 2 - 4]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX / 2 - 5]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX / 2 - 6]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX / 2 - 7]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][2][MAX / 2 - 8]; // { dg-error "size of (unnamed )?array" } p = new (p) B [2][2][MAX / 4]; // { dg-error "size of array" } p = new (p) B [2][2][MAX / 4 - 1]; // { dg-error "size of array" } p = new (p) B [2][2][MAX / 4 - 2]; // { dg-error "size of array" } @@ -482,19 +482,19 @@ p = new (p) B [2][2][MAX / 8 - 2]; p = new (p) B [2][2][MAX / 8 - 3]; - p = new (p) B [2][MAX][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX - 1][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX - 2][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX - 99][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX / 2][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX / 2 - 1][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX / 2 - 2][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX / 2 - 3][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX / 2 - 4][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX / 2 - 5][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX / 2 - 6][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX / 2 - 7][2]; // { dg-error "size of unnamed array" } - p = new (p) B [2][MAX / 2 - 8][2]; // { dg-error "size of unnamed array" } + p = new (p) B [2][MAX][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX - 1][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX - 2][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX - 99][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX / 2][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX / 2 - 1][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX / 2 - 2][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX / 2 - 3][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX / 2 - 4][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX / 2 - 5][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX / 2 - 6][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX / 2 - 7][2]; // { dg-error "size of (unnamed )?array" } + p = new (p) B [2][MAX / 2 - 8][2]; // { dg-error "size of (unnamed )?array" } p = new (p) B [2][MAX / 4][2]; // { dg-error "size of array" } p = new (p) B [2][MAX / 4 - 1][2]; // { dg-error "size of array" } p = new (p) B [2][MAX / 4 - 2][2]; // { dg-error "size of array" } Index: gcc/testsuite/g++.dg/other/anon5.C =================================================================== diff --git a/gcc/testsuite/g++.dg/other/anon5.C b/gcc/testsuite/g++.dg/other/anon5.C --- a/gcc/testsuite/g++.dg/other/anon5.C (revision 257042) +++ b/gcc/testsuite/g++.dg/other/anon5.C (revision 259627) @@ -4,7 +4,7 @@ // Ignore additional message on powerpc-ibm-aix // { dg-prune-output "obtain more information" } */ // Ignore additional messages on Linux/x86 with PIE -// { dg-prune-output "Bad value" } */ +// { dg-prune-output "\[Bb\]ad value" } */ namespace { struct c Index: gcc/testsuite/g++.dg/tree-ssa/volatile2.C =================================================================== diff --git a/gcc/testsuite/g++.dg/tree-ssa/volatile2.C b/gcc/testsuite/g++.dg/tree-ssa/volatile2.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/tree-ssa/volatile2.C (revision 259627) @@ -0,0 +1,20 @@ +// PR c++/84686 +// { dg-additional-options -fdump-tree-gimple } +// { dg-final { scan-tree-dump-times "= i" 10 "gimple" } } + +volatile int i; + +int main() +{ + i; //evaluated (a load is performed) + (i); //unevaluated => the load shall be performed + + (void)i; //evaluated (a load is performed) + (void)(i); //unevaluated => the load shall be performed + + (void)i; //evaluated (a load is performed) + (void)(i); //unevaluated => the load shall be performed + + (i,i); // the two subexpression are evaluated + ((i),(i)); // no evaluation, => two loads shall happen +} Index: gcc/testsuite/g++.dg/tree-ssa/volatile1.C =================================================================== diff --git a/gcc/testsuite/g++.dg/tree-ssa/volatile1.C b/gcc/testsuite/g++.dg/tree-ssa/volatile1.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/tree-ssa/volatile1.C (revision 259627) @@ -0,0 +1,28 @@ +// PR c++/84151 +// { dg-additional-options "-fdump-tree-gimple" } +// { dg-final { scan-tree-dump-not {\*this} "gimple" } } + +struct A { + static int& bar(int& a) { + return a; + } + static int i; + + int foo() volatile { + int v = c; + return i + bar(v); + } + + int c; +}; + +int A::i = 0; + +A a; + +int main() { + a.c = 2; + a.foo(); + + return 0; +} Index: gcc/testsuite/g++.dg/concepts/auto4.C =================================================================== diff --git a/gcc/testsuite/g++.dg/concepts/auto4.C b/gcc/testsuite/g++.dg/concepts/auto4.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/concepts/auto4.C (revision 259627) @@ -0,0 +1,11 @@ +// PR c++/85006 +// { dg-additional-options "-std=c++17 -fconcepts" } + +template struct A {}; + +template A foo() { return A{}; } + +void bar() +{ + foo(); +} Index: gcc/testsuite/g++.dg/asan/pr85081.C =================================================================== diff --git a/gcc/testsuite/g++.dg/asan/pr85081.C b/gcc/testsuite/g++.dg/asan/pr85081.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/asan/pr85081.C (revision 259627) @@ -0,0 +1,20 @@ +/* PR sanitizer/85081 */ +/* { dg-do run } */ +/* { dg-options "-fopenmp-simd" } */ +/* { dg-require-effective-target fopenmp } */ + +inline const int& max(const int& a, const int& b) +{ + return a < b ? b : a; +} + +int main() +{ + #pragma omp simd + for ( int i = 0; i < 20; ++i ) + { + const int j = max(i, 1); + } + + return 0; +} Index: gcc/testsuite/g++.dg/template/nontype-fn1.C =================================================================== diff --git a/gcc/testsuite/g++.dg/template/nontype-fn1.C b/gcc/testsuite/g++.dg/template/nontype-fn1.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/template/nontype-fn1.C (revision 259627) @@ -0,0 +1,11 @@ +// PR c++/82664 + +template < typename > struct target_disambiguator; +template < typename R, typename A1 > struct target_disambiguator< R(A1) > { + typedef A1 type; + template < R (&)() > struct layout; +}; + +int main() { + typedef target_disambiguator< void (int) > ::type target_type ; +} Index: gcc/testsuite/g++.dg/template/dependent-base3.C =================================================================== diff --git a/gcc/testsuite/g++.dg/template/dependent-base3.C b/gcc/testsuite/g++.dg/template/dependent-base3.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/template/dependent-base3.C (revision 259627) @@ -0,0 +1,26 @@ +// PR c++/85060 +// { dg-do compile { target c++14 } } + +struct CA { + constexpr int foo() const { return 42; } +}; + +template +struct CB : CA { }; + +template +struct CC : CB { + constexpr int bar() const { + const int m = CA::foo(); + return m; + } + + constexpr int baz() const { + const T m = CA::foo(); + return m; + } +}; + +constexpr CC c; + +static_assert( c.bar() == 42, "" ); Index: gcc/testsuite/g++.dg/template/incomplete11.C =================================================================== diff --git a/gcc/testsuite/g++.dg/template/incomplete11.C b/gcc/testsuite/g++.dg/template/incomplete11.C new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/g++.dg/template/incomplete11.C (revision 259627) @@ -0,0 +1,10 @@ +// PR c++/84082 +// { dg-do compile } +// { dg-options "" } + +struct A; + +template void foo() +{ + static int a[A().operator=(A())]; // { dg-error "invalid use of incomplete type 'struct A'" } +} Index: gcc/testsuite/c-c++-common/tsan/race_on_mutex.c =================================================================== diff --git a/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c b/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c --- a/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c (revision 257042) +++ b/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c (revision 259627) @@ -37,9 +37,10 @@ } /* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ -/* { dg-output " Atomic read of size 1 at .* by thread T2:(\n|\r\n|\r)" } */ +/* { dg-output " Atomic read of size \[0-9]\+ at .* by thread T2:(\n|\r\n|\r)" } */ /* { dg-output " #0 pthread_mutex_lock.*" } */ /* { dg-output " #1 Thread2.* .*(race_on_mutex.c:22|\\?{2}:0) (.*)" } */ -/* { dg-output " Previous write of size 1 at .* by thread T1:(\n|\r\n|\r)" } */ -/* { dg-output " #0 pthread_mutex_init .* (.)*" } */ -/* { dg-output " #1 Thread1.* .*(race_on_mutex.c:12|\\?{2}:0) .*" } */ +/* { dg-output " Previous write of size \[0-9]\+ at .* by thread T1:(\n|\r\n|\r)" } */ +/* { dg-output "( #0 \[^\n\r\]*(\n|\r\n|\r))?" } */ +/* { dg-output " #\[01\] ((__GI_)?__)?pthread_mutex_init \[^\n\r\]* (.)*" } */ +/* { dg-output " #\[12\] Thread1.* .*(race_on_mutex.c:12|\\?{2}:0) .*" } */ Index: gcc/testsuite/c-c++-common/gomp/pr83977-2.c =================================================================== diff --git a/gcc/testsuite/c-c++-common/gomp/pr83977-2.c b/gcc/testsuite/c-c++-common/gomp/pr83977-2.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/c-c++-common/gomp/pr83977-2.c (revision 259627) @@ -0,0 +1,18 @@ +/* PR middle-end/83977 */ +/* { dg-do compile } */ + +void bar (void); + +#pragma omp declare simd uniform (b) linear(a:b) +int +foo (int a, int b) +{ + a = a + 1; +/* This function can't be called from simd loops, + because it violates declare simd restrictions. + We shouldn't ICE on it though, nor attempt to generate + simd clones for the *omp_fn* functions. */ + #pragma omp parallel + bar (); + return a; +} Index: gcc/testsuite/c-c++-common/gomp/pr84341.c =================================================================== diff --git a/gcc/testsuite/c-c++-common/gomp/pr84341.c b/gcc/testsuite/c-c++-common/gomp/pr84341.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/c-c++-common/gomp/pr84341.c (revision 259627) @@ -0,0 +1,10 @@ +/* PR c++/84341 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +void +foo (int i) +{ + #pragma omp atomic + i = &i + 1; /* { dg-error "invalid form of" } */ +} Index: gcc/testsuite/c-c++-common/gomp/pr83977-1.c =================================================================== diff --git a/gcc/testsuite/c-c++-common/gomp/pr83977-1.c b/gcc/testsuite/c-c++-common/gomp/pr83977-1.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/c-c++-common/gomp/pr83977-1.c (revision 259627) @@ -0,0 +1,19 @@ +/* PR middle-end/83977 */ +/* { dg-do compile } */ +/* { dg-additional-options "-O2" } */ + +struct S { int a, b, c; }; + +#pragma omp declare simd uniform(z) linear(v:1) +__attribute__((noinline)) static int +foo (int x, int y, struct S z, int u, int v) +{ + return x + y + z.a; +} + +int +bar (int x, int y, int z) +{ + struct S s = { z, 1, 1 }; + return foo (x, y, s, 0, 0); +} Index: gcc/testsuite/c-c++-common/gomp/pr83977-3.c =================================================================== diff --git a/gcc/testsuite/c-c++-common/gomp/pr83977-3.c b/gcc/testsuite/c-c++-common/gomp/pr83977-3.c new file mode 10644 --- /dev/null (nonexistent) +++ b/gcc/testsuite/c-c++-common/gomp/pr83977-3.c (revision 259627) @@ -0,0 +1,21 @@ +/* PR middle-end/83977 */ +/* { dg-do compile } */ + +void bar (void); +int foo (int, int) __attribute__((used)); + +#pragma omp declare simd uniform (b) linear(a:b) +int +foo (int a, int b) +{ + a = a + 1; +/* This function can't be called from simd loops, + because it violates declare simd restrictions. + We shouldn't ICE on it though, nor attempt to generate + simd clones for the *omp_fn* functions. */ + #pragma omp parallel + bar (); + return a; +} + +int foo (int, int) __attribute__((unused)); Index: gcc/cp/typeck.c =================================================================== diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c --- a/gcc/cp/typeck.c (revision 257042) +++ b/gcc/cp/typeck.c (revision 259627) @@ -905,14 +905,14 @@ return t1; default:; + if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes)) + return t1; + else if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes)) + return t2; + break; } - if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes)) - return t1; - else if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes)) - return t2; - else - return cp_build_type_attribute_variant (t1, attributes); + return cp_build_type_attribute_variant (t1, attributes); } /* Return the ARRAY_TYPE type without its domain. */ Index: gcc/cp/class.c =================================================================== diff --git a/gcc/cp/class.c b/gcc/cp/class.c --- a/gcc/cp/class.c (revision 257042) +++ b/gcc/cp/class.c (revision 259627) @@ -4532,8 +4532,14 @@ DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; DECL_FIELD_CONTEXT (decl) = t; - DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype); - DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype); + if (is_empty_class (basetype)) + /* CLASSTYPE_SIZE is one byte, but the field needs to have size zero. */ + DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = size_zero_node; + else + { + DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype); + DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype); + } SET_DECL_ALIGN (decl, CLASSTYPE_ALIGN (basetype)); DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype); SET_DECL_MODE (decl, TYPE_MODE (basetype)); @@ -7592,7 +7598,8 @@ case CALL_EXPR: /* This is a call to a constructor, hence it's never zero. */ - if (TREE_HAS_CONSTRUCTOR (instance)) + if (CALL_EXPR_FN (instance) + && TREE_HAS_CONSTRUCTOR (instance)) { if (nonnull) *nonnull = 1; Index: gcc/cp/decl.c =================================================================== diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c --- a/gcc/cp/decl.c (revision 257042) +++ b/gcc/cp/decl.c (revision 259627) @@ -5042,19 +5042,17 @@ if (field == NULL_TREE || !(VAR_P (field) || variable_template_p (field))) error ("%q+#D is not a static data member of %q#T", decl, context); + else if (variable_template_p (field) + && (DECL_LANG_SPECIFIC (decl) + && DECL_TEMPLATE_SPECIALIZATION (decl))) + /* OK, specialization was already checked. */; else if (variable_template_p (field) && !this_tmpl) { - if (DECL_LANG_SPECIFIC (decl) - && DECL_TEMPLATE_SPECIALIZATION (decl)) - /* OK, specialization was already checked. */; - else - { - error_at (DECL_SOURCE_LOCATION (decl), - "non-member-template declaration of %qD", decl); - inform (DECL_SOURCE_LOCATION (field), "does not match " - "member template declaration here"); - return error_mark_node; - } + error_at (DECL_SOURCE_LOCATION (decl), + "non-member-template declaration of %qD", decl); + inform (DECL_SOURCE_LOCATION (field), "does not match " + "member template declaration here"); + return error_mark_node; } else { @@ -6402,7 +6400,9 @@ } if (init_code - && (DECL_IN_AGGR_P (decl) && !DECL_VAR_DECLARED_INLINE_P (decl))) + && (DECL_IN_AGGR_P (decl) + && DECL_INITIALIZED_IN_CLASS_P (decl) + && !DECL_VAR_DECLARED_INLINE_P (decl))) { static int explained = 0; @@ -7213,7 +7213,9 @@ { bool member_seen = false; for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) - if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) + if (TREE_CODE (field) != FIELD_DECL + || DECL_ARTIFICIAL (field) + || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))) continue; else if (ret) return type; @@ -7228,9 +7230,9 @@ inform (DECL_SOURCE_LOCATION (field), "declared here"); return error_mark_node; } - else if (TREE_PRIVATE (field) || TREE_PROTECTED (field)) + else if (!accessible_p (type, field, true)) { - error_at (loc, "cannot decompose non-public member %qD of %qT", + error_at (loc, "cannot decompose inaccessible member %qD of %qT", field, type); inform (DECL_SOURCE_LOCATION (field), TREE_PRIVATE (field) @@ -7252,7 +7254,7 @@ tree t = find_decomp_class_base (loc, TREE_TYPE (base_binfo), ret); if (t == error_mark_node) return error_mark_node; - if (t != NULL_TREE) + if (t != NULL_TREE && t != ret) { if (ret == type) { @@ -7263,9 +7265,6 @@ } else if (orig_ret != NULL_TREE) return t; - else if (ret == t) - /* OK, found the same base along another path. We'll complain - in convert_to_base if it's ambiguous. */; else if (ret != NULL_TREE) { error_at (loc, "cannot decompose class type %qT: its base " @@ -7341,8 +7340,30 @@ tree fns = lookup_qualified_name (TREE_TYPE (e), get_id, /*type*/false, /*complain*/false); - if (fns != error_mark_node) + bool use_member_get = false; + + /* To use a member get, member lookup must find at least one + declaration that is a function template + whose first template parameter is a non-type parameter. */ + for (tree iter = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns; + iter; + iter = OVL_NEXT (iter)) { + tree fn = OVL_CURRENT (iter); + if (TREE_CODE (fn) == TEMPLATE_DECL) + { + tree tparms = DECL_TEMPLATE_PARMS (fn); + tree parm = TREE_VEC_ELT (INNERMOST_TEMPLATE_PARMS (tparms), 0); + if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL) + { + use_member_get = true; + break; + } + } + } + + if (use_member_get) + { fns = lookup_template_function (fns, targs); return build_new_method_call (e, fns, /*args*/NULL, /*path*/NULL_TREE, LOOKUP_NORMAL, @@ -7466,6 +7487,12 @@ type = complete_type (TREE_TYPE (type)); if (type == error_mark_node) goto error_out; + if (!COMPLETE_TYPE_P (type)) + { + error_at (loc, "structured binding refers to incomplete type %qT", + type); + goto error_out; + } } tree eltype = NULL_TREE; @@ -7640,7 +7667,9 @@ goto error_out; } for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field)) - if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) + if (TREE_CODE (field) != FIELD_DECL + || DECL_ARTIFICIAL (field) + || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))) continue; else eltscnt++; @@ -7655,7 +7684,9 @@ } unsigned int i = 0; for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field)) - if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) + if (TREE_CODE (field) != FIELD_DECL + || DECL_ARTIFICIAL (field) + || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))) continue; else { @@ -9517,7 +9548,8 @@ constant_expression_error (size); /* An array must have a positive number of elements. */ - if (tree_int_cst_lt (size, integer_zero_node)) + tree signed_size = fold_convert (ssizetype, size); + if (tree_int_cst_lt (signed_size, integer_zero_node)) { if (!(complain & tf_error)) return error_mark_node; @@ -10097,6 +10129,8 @@ declspecs->locations); if (typespec_loc == UNKNOWN_LOCATION) typespec_loc = declspecs->locations[ds_type_spec]; + if (typespec_loc == UNKNOWN_LOCATION) + typespec_loc = input_location; /* Look inside a declarator for the name being declared and get it as a string, for an error message. */ @@ -12556,7 +12590,9 @@ A default argument expression is implicitly converted to the parameter type. */ ++cp_unevaluated_operand; - perform_implicit_conversion_flags (decl_type, arg, complain, + /* Avoid digest_init clobbering the initializer. */ + tree carg = BRACE_ENCLOSED_INITIALIZER_P (arg) ? unshare_expr (arg): arg; + perform_implicit_conversion_flags (decl_type, carg, complain, LOOKUP_IMPLICIT); --cp_unevaluated_operand; Index: gcc/cp/method.c =================================================================== diff --git a/gcc/cp/method.c b/gcc/cp/method.c --- a/gcc/cp/method.c (revision 257042) +++ b/gcc/cp/method.c (revision 259627) @@ -1165,6 +1165,7 @@ { tree ctype = to; vec *args = NULL; + cp_unevaluated cp_uneval_guard; if (TREE_CODE (to) != REFERENCE_TYPE) to = cp_build_reference_type (to, /*rval*/false); tree ob = build_stub_object (to); @@ -1430,7 +1431,7 @@ synthesized_method_base_walk (tree binfo, tree base_binfo, int quals, bool copy_arg_p, bool move_p, bool ctor_p, - tree inheriting_ctor, tree inherited_parms, + tree *inheriting_ctor, tree inherited_parms, tree fnname, int flags, bool diag, tree *spec_p, bool *trivial_p, bool *deleted_p, bool *constexpr_p) @@ -1441,8 +1442,9 @@ if (copy_arg_p) argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, move_p); - else if ((inherited_binfo - = binfo_inherited_from (binfo, base_binfo, inheriting_ctor))) + else if (inheriting_ctor + && (inherited_binfo + = binfo_inherited_from (binfo, base_binfo, *inheriting_ctor))) { argtype = inherited_parms; /* Don't check access on the inherited constructor. */ @@ -1464,6 +1466,12 @@ if (defer != dk_no_deferred) pop_deferring_access_checks (); + /* Replace an inherited template with the appropriate specialization. */ + if (inherited_binfo && rval + && DECL_P (*inheriting_ctor) && DECL_P (rval) + && DECL_CONTEXT (*inheriting_ctor) == DECL_CONTEXT (rval)) + *inheriting_ctor = DECL_CLONED_FUNCTION (rval); + process_subob_fn (rval, spec_p, trivial_p, deleted_p, constexpr_p, diag, BINFO_TYPE (base_binfo)); if (ctor_p && @@ -1498,7 +1506,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, tree *spec_p, bool *trivial_p, bool *deleted_p, bool *constexpr_p, bool diag, - tree inheriting_ctor, tree inherited_parms) + tree *inheriting_ctor, tree inherited_parms) { tree binfo, base_binfo, fnname; int i; @@ -1553,7 +1561,7 @@ } gcc_assert ((sfk == sfk_inheriting_constructor) - == (inheriting_ctor != NULL_TREE)); + == (inheriting_ctor && *inheriting_ctor != NULL_TREE)); /* If that user-written default constructor would satisfy the requirements of a constexpr constructor (7.1.5), the @@ -1628,7 +1636,7 @@ tree scope = push_scope (ctype); int flags = LOOKUP_NORMAL | LOOKUP_SPECULATIVE; - if (!inheriting_ctor) + if (sfk != sfk_inheriting_constructor) flags |= LOOKUP_DEFAULTED; tsubst_flags_t complain = diag ? tf_warning_or_error : tf_none; @@ -1731,9 +1739,9 @@ tree parm_type = TREE_VALUE (parms); bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); tree spec = empty_except_spec; + tree inh = DECL_INHERITED_CTOR (decl); synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL, - NULL, false, DECL_INHERITED_CTOR (decl), - parms); + NULL, false, &inh, parms); return spec; } @@ -1810,10 +1818,11 @@ tree raises = NULL_TREE; bool deleted_p = false; tree scope = push_scope (ctype); + tree inh = DECL_INHERITED_CTOR (decl); synthesized_method_walk (ctype, sfk, const_p, &raises, NULL, &deleted_p, NULL, false, - DECL_INHERITED_CTOR (decl), parms); + &inh, parms); if (deleted_p) { inform (DECL_SOURCE_LOCATION (decl), @@ -1821,7 +1830,7 @@ "definition would be ill-formed:", decl); synthesized_method_walk (ctype, sfk, const_p, NULL, NULL, NULL, NULL, true, - DECL_INHERITED_CTOR (decl), parms); + &inh, parms); } else if (!comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)), @@ -1850,11 +1859,12 @@ { tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl)); bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); + tree inh = DECL_INHERITED_CTOR (decl); bool dummy; synthesized_method_walk (DECL_CLASS_CONTEXT (decl), special_function_p (decl), const_p, NULL, NULL, NULL, &dummy, true, - DECL_INHERITED_CTOR (decl), + &inh, FUNCTION_FIRST_USER_PARMTYPE (decl)); } @@ -1869,10 +1879,11 @@ gcc_assert (DECL_INHERITED_CTOR (decl)); tree spec; bool trivial, constexpr_, deleted; + tree inh = DECL_INHERITED_CTOR (decl); synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor, false, &spec, &trivial, &deleted, &constexpr_, /*diag*/false, - DECL_INHERITED_CTOR (decl), + &inh, FUNCTION_FIRST_USER_PARMTYPE (decl)); if (TREE_CODE (inherited_ctor_binfo (decl)) != TREE_BINFO) /* Inherited the same constructor from different base subobjects. */ @@ -1879,6 +1890,7 @@ deleted = true; DECL_DELETED_FN (decl) = deleted; TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec); + SET_DECL_INHERITED_CTOR (decl, inh); tree clone; FOR_EACH_CLONE (clone, decl) @@ -1885,6 +1897,7 @@ { DECL_DELETED_FN (clone) = deleted; TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec); + SET_DECL_INHERITED_CTOR (clone, inh); } } @@ -1999,12 +2012,12 @@ raises = unevaluated_noexcept_spec (); synthesized_method_walk (type, kind, const_p, NULL, &trivial_p, &deleted_p, &constexpr_p, false, - inherited_ctor, inherited_parms); + &inherited_ctor, inherited_parms); } else synthesized_method_walk (type, kind, const_p, &raises, &trivial_p, &deleted_p, &constexpr_p, false, - inherited_ctor, inherited_parms); + &inherited_ctor, inherited_parms); /* Don't bother marking a deleted constructor as constexpr. */ if (deleted_p) constexpr_p = false; @@ -2120,7 +2133,7 @@ input_location = DECL_SOURCE_LOCATION (fn); synthesized_method_walk (type, kind, const_p, NULL, NULL, NULL, NULL, true, - NULL_TREE, NULL_TREE); + NULL, NULL_TREE); input_location = loc; } Index: gcc/cp/constexpr.c =================================================================== diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c --- a/gcc/cp/constexpr.c (revision 257042) +++ b/gcc/cp/constexpr.c (revision 259627) @@ -1140,7 +1140,10 @@ /* Don't fold __builtin_constant_p within a constexpr function. */ bool bi_const_p = (DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P); + /* If we aren't requiring a constant expression, defer __builtin_constant_p + in a constexpr function until we have values for the parameters. */ if (bi_const_p + && ctx->quiet && current_function_decl && DECL_DECLARED_CONSTEXPR_P (current_function_decl)) { @@ -1274,6 +1277,8 @@ if (!*non_constant_p) { + /* Don't share a CONSTRUCTOR that might be changed. */ + arg = unshare_constructor (arg); /* Make sure the binding has the same type as the parm. But only for constant args. */ if (TREE_CODE (type) != REFERENCE_TYPE) @@ -2783,14 +2788,20 @@ gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (index)))); changed = true; } - else if (new_ctx.ctor != ctx->ctor) + else { - /* We appended this element above; update the value. */ - gcc_assert ((*p)->last().index == index); - (*p)->last().value = elt; + if (new_ctx.ctor != ctx->ctor) + { + /* We appended this element above; update the value. */ + gcc_assert ((*p)->last().index == index); + (*p)->last().value = elt; + } + else + CONSTRUCTOR_APPEND_ELT (*p, index, elt); + /* Adding or replacing an element might change the ctor's flags. */ + TREE_CONSTANT (ctx->ctor) = constant_p; + TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p; } - else - CONSTRUCTOR_APPEND_ELT (*p, index, elt); } if (*non_constant_p || !changed) return t; @@ -2895,9 +2906,8 @@ if (!lvalue_p (init)) eltinit = move (eltinit); eltinit = force_rvalue (eltinit, tf_warning_or_error); - eltinit = (cxx_eval_constant_expression - (&new_ctx, eltinit, lval, - non_constant_p, overflow_p)); + eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval, + non_constant_p, overflow_p); } if (*non_constant_p && !ctx->quiet) break; @@ -2910,12 +2920,13 @@ else CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit); /* Reuse the result of cxx_eval_constant_expression call - from the first iteration to all others if it is a constant - initializer that doesn't require relocations. */ + from the first iteration to all others if it is a constant + initializer that doesn't require relocations. */ if (reuse && max > 1 - && (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit)) - == null_pointer_node)) + && (eltinit == NULL_TREE + || (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit)) + == null_pointer_node))) { if (new_ctx.ctor != ctx->ctor) eltinit = new_ctx.ctor; @@ -2966,9 +2977,9 @@ static tree cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) { - tree sub, subtype; + tree sub = op0; + tree subtype; - sub = op0; STRIP_NOPS (sub); subtype = TREE_TYPE (sub); if (!POINTER_TYPE_P (subtype)) @@ -3023,7 +3034,8 @@ { tree part_width = TYPE_SIZE (type); tree index = bitsize_int (0); - return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index); + return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, + index); } /* Also handle conversion to an empty base class, which is represented with a NOP_EXPR. */ @@ -3063,19 +3075,31 @@ /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF */ if (VECTOR_TYPE_P (op00type) && (same_type_ignoring_top_level_qualifiers_p - (type, TREE_TYPE (op00type)))) + (type, TREE_TYPE (op00type))) + /* POINTER_PLUS_EXPR second operand is sizetype, unsigned, + but we want to treat offsets with MSB set as negative. + For the code below negative offsets are invalid and + TYPE_SIZE of the element is something unsigned, so + check whether op01 fits into HOST_WIDE_INT, which + implies it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and + then just use unsigned HOST_WIDE_INT because we want to treat + the value as unsigned. */ + && tree_fits_shwi_p (op01)) { - HOST_WIDE_INT offset = tree_to_shwi (op01); tree part_width = TYPE_SIZE (type); - unsigned HOST_WIDE_INT part_widthi = tree_to_shwi (part_width)/BITS_PER_UNIT; - unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; - tree index = bitsize_int (indexi); - - if (offset / part_widthi < TYPE_VECTOR_SUBPARTS (op00type)) - return fold_build3_loc (loc, - BIT_FIELD_REF, type, op00, - part_width, index); - + unsigned HOST_WIDE_INT max_offset + = (tree_to_uhwi (part_width) / BITS_PER_UNIT + * TYPE_VECTOR_SUBPARTS (op00type)); + if (tree_int_cst_sign_bit (op01) == 0 + && compare_tree_int (op01, max_offset) == -1) + { + unsigned HOST_WIDE_INT offset = tree_to_uhwi (op01); + unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; + tree index = bitsize_int (indexi); + return fold_build3_loc (loc, + BIT_FIELD_REF, type, op00, + part_width, index); + } } /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ else if (TREE_CODE (op00type) == COMPLEX_TYPE @@ -3132,7 +3156,8 @@ { tree type_domain; tree min_val = size_zero_node; - tree newsub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL); + tree newsub + = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL); if (newsub) sub = newsub; else @@ -4170,7 +4195,16 @@ r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, non_constant_p, overflow_p); - *jump_target = t; + if (jump_target) + *jump_target = t; + else + { + /* Can happen with ({ return true; }) && false; passed to + maybe_constant_value. There is nothing to jump over in this + case, and the bug will be diagnosed later. */ + gcc_assert (ctx->quiet); + *non_constant_p = true; + } break; case SAVE_EXPR: @@ -4414,11 +4448,7 @@ { /* Don't re-process a constant CONSTRUCTOR, but do fold it to VECTOR_CST if applicable. */ - /* FIXME after GCC 6 branches, make the verify unconditional. */ - if (CHECKING_P) - verify_constructor_flags (t); - else - recompute_constructor_flags (t); + verify_constructor_flags (t); if (TREE_CONSTANT (t)) return fold (t); } @@ -4640,6 +4670,10 @@ jump_target); break; + case USING_STMT: + r = void_node; + break; + default: if (STATEMENT_CODE_P (TREE_CODE (t))) { @@ -4763,8 +4797,12 @@ return error_mark_node; else if (non_constant_p && TREE_CONSTANT (r)) { - /* This isn't actually constant, so unset TREE_CONSTANT. */ - if (EXPR_P (r)) + /* This isn't actually constant, so unset TREE_CONSTANT. + Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires + it to be set if it is invariant address, even when it is not + a valid C++ constant expression. Wrap it with a NOP_EXPR + instead. */ + if (EXPR_P (r) && TREE_CODE (r) != ADDR_EXPR) r = copy_node (r); else if (TREE_CODE (r) == CONSTRUCTOR) r = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (r), r); @@ -5453,6 +5491,7 @@ case OMP_PARALLEL: case OMP_TASK: case OMP_FOR: + case OMP_SIMD: case OMP_DISTRIBUTE: case OMP_TASKLOOP: case OMP_TEAMS: @@ -5627,7 +5666,8 @@ return RECUR (TREE_OPERAND (t, 1), want_rval); case TARGET_EXPR: - if (!literal_type_p (TREE_TYPE (t))) + if (!TARGET_EXPR_DIRECT_INIT_P (t) + && !literal_type_p (TREE_TYPE (t))) { if (flags & tf_error) { Index: gcc/cp/except.c =================================================================== diff --git a/gcc/cp/except.c b/gcc/cp/except.c --- a/gcc/cp/except.c (revision 257042) +++ b/gcc/cp/except.c (revision 259627) @@ -1218,6 +1218,10 @@ { gcc_assert (processing_template_decl || TREE_CODE (expr) == DEFERRED_NOEXCEPT); + if (TREE_CODE (expr) != DEFERRED_NOEXCEPT) + /* Avoid problems with a function type built with a dependent typedef + being reused in another scope (c++/84045). */ + expr = strip_typedefs_expr (expr); return build_tree_list (expr, NULL_TREE); } } Index: gcc/cp/error.c =================================================================== diff --git a/gcc/cp/error.c b/gcc/cp/error.c --- a/gcc/cp/error.c (revision 257042) +++ b/gcc/cp/error.c (revision 259627) @@ -2695,6 +2695,7 @@ case INTEGER_TYPE: case COMPLEX_TYPE: case VECTOR_TYPE: + case DECLTYPE_TYPE: pp_type_specifier_seq (pp, t); break; Index: gcc/cp/tree.c =================================================================== diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c --- a/gcc/cp/tree.c (revision 257042) +++ b/gcc/cp/tree.c (revision 259627) @@ -2589,6 +2589,8 @@ { u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1), tf_warning_or_error); + if (u == error_mark_node) + return u; if (AGGR_INIT_ZERO_FIRST (TREE_OPERAND (t, 1))) AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true; } @@ -2606,6 +2608,8 @@ (splay_tree_value) TREE_OPERAND (u, 0)); TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1)); + if (TREE_OPERAND (u, 1) == error_mark_node) + return error_mark_node; /* Replace the old expression with the new version. */ *tp = u; @@ -2718,7 +2722,8 @@ target_remap = splay_tree_new (splay_tree_compare_pointers, /*splay_tree_delete_key_fn=*/NULL, /*splay_tree_delete_value_fn=*/NULL); - cp_walk_tree (&t, bot_manip, target_remap, NULL); + if (cp_walk_tree (&t, bot_manip, target_remap, NULL) == error_mark_node) + t = error_mark_node; cp_walk_tree (&t, bot_replace, target_remap, NULL); if (!--target_remap_count) @@ -2793,7 +2798,7 @@ for (; !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (*t), TREE_TYPE (x)); x = TREE_OPERAND (x, 0)) - gcc_assert (TREE_CODE (x) == COMPONENT_REF); + gcc_assert (handled_component_p (x)); *t = x; *walk_subtrees = false; d->seen = true; Index: gcc/cp/ChangeLog =================================================================== diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog --- a/gcc/cp/ChangeLog (revision 257042) +++ b/gcc/cp/ChangeLog (revision 259627) @@ -1,3 +1,387 @@ +2018-04-23 Ville Voutilainen + + Backport from mainline + 2018-04-05 Ville Voutilainen + + Implement P0969 + * decl.c (find_decomp_class_base): Check accessibility instead + of declared access, adjust diagnostic. + +2018-04-23 Jakub Jelinek + Jason Merrill + + PR c++/85470 - wrong error with static data member. + * decl.c (check_initializer): Check DECL_INITIALIZED_IN_CLASS_P. + * typeck2.c (store_init_value): Likewise. + +2018-04-23 Ville Voutilainen + + Backport from mainline + 2018-04-05 Ville Voutilainen + + Implement P0961 + * decl.c (get_tuple_decomp_init): Check the templatedness + of a member get. + +2018-04-19 Jonathan Wakely + + PR c++/85464 - missing location for -Wignored-qualifiers diagnostic + * decl.c (grokdeclarator): If declspecs->locations[ds_type_spec] + is UNKNOWN_LOCATION fall back to input_location. + +2018-04-09 Jason Merrill + + PR c++/85279 - dump_expr doesn't understand decltype. + * error.c (dump_expr): Handle DECLTYPE_TYPE. + +2018-04-05 Jason Merrill + + PR c++/82152 - ICE with class deduction and inherited ctor. + * pt.c (do_class_deduction): Ignore inherited ctors. + + PR c++/84665 - ICE with array of empty class. + * decl2.c (cp_check_const_attributes): Use fold_non_dependent_expr. + + PR c++/85006 - -fconcepts ICE with A return type + * pt.c (tsubst_pack_expansion): Allow unsubstituted auto pack. + +2018-04-04 Jason Merrill + + PR c++/85118 - wrong error with generic lambda and std::bind. + * call.c (add_template_conv_candidate): Disable if there are any + call operators. + + PR c++/85148 - ICE with 'this' in array NSDMI. + * tree.c (replace_placeholders_r): Use handled_component_p. + +2018-04-03 Jason Merrill + + PR c++/85113 - ICE with constexpr and __builtin_constant_p. + * constexpr.c (cxx_eval_builtin_function_call): Only defer + __builtin_constant_p if ctx->quiet. + + * typeck.c (merge_types): Limit matching attribute shortcut to + the default case. + + PR c++/64095 - auto... parameter pack. + * parser.c (cp_parser_parameter_declaration): Handle turning autos + into packs here. + (cp_parser_parameter_declaration_list): Not here. + + PR c++/85060 - wrong-code with call to base member in template. + * search.c (any_dependent_bases_p): Check uses_template_parms + rather than processing_template_decl. + +2018-03-29 Ville Voutilainen + + Backport from mainline + 2018-03-23 Ville Voutilainen + + Implement P0962 + * parser.c (cp_parser_perform_range_for_lookup): Change + the condition for deciding whether to use members. + +2018-03-23 Jason Merrill + + PR c++/78489 - Substitution in wrong order + PR c++/84489 + * pt.c (type_unification_real): Revert last two changes. + + PR c++/71834 - template-id with too few arguments. + * pt.c (coerce_template_parms): Make sure we gave an error. + + PR c++/84937 - ICE with class deduction and auto. + * pt.c (rewrite_template_parm): Fix auto handling. + + PR c++/80227 - SFINAE and negative array size. + * decl.c (compute_array_index_type): Convert to signed for negative + check. + + PR c++/84839 - ICE with decltype of parameter pack. + * pt.c (tsubst_pack_expansion): Set cp_unevaluated_operand while + instantiating dummy parms. + + PR c++/84798 - ICE with auto in abstract function declarator. + * parser.c (cp_parser_parameter_declaration_clause): Check + parser->default_arg_ok_p. + + PR c++/84355 - ICE with deduction for member class template. + * pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Always substitute into + CLASS_PLACEHOLDER_TEMPLATE. + +2018-03-23 Paolo Carlini + Jason Merrill + + PR c++/82336 - link error with list-init default argument. + * decl.c (check_default_argument): Unshare an initializer list. + +2018-03-22 Marek Polacek + + Backported from mainline + 2018-03-22 Marek Polacek + + PR c++/84854 + * semantics.c (finish_if_stmt_cond): Check if the type of the condition + is boolean. + + 2018-03-19 Marek Polacek + + PR c++/84927 + * constexpr.c (cxx_eval_bare_aggregate): Update constructor's flags + as we evaluate the elements. + (cxx_eval_constant_expression): Verify constructor's flags + unconditionally. + + 2018-03-21 Marek Polacek + + PR c++/71638, ICE with NSDMI and reference. + * constexpr.c (cxx_eval_bare_aggregate): Update constructor's flags + even when we replace an element. + +2018-03-09 Jason Merrill + + PR c++/84785 - ICE with alias template and default targs. + * pt.c (type_unification_real): Set processing_template_decl if + saw_undeduced == 1. + +2018-03-07 Marek Polacek + + Backported from mainline + 2018-03-06 Marek Polacek + + PR c++/84684 + * constexpr.c (cxx_bind_parameters_in_call): Unshare evaluated + arguments. + +2018-03-03 Jason Merrill + + PR c++/84686 - missing volatile loads. + * cvt.c (convert_to_void): Call maybe_undo_parenthesized_ref. + +2018-03-03 Jakub Jelinek + + Backported from mainline + 2018-02-26 Jakub Jelinek + + PR c++/84558 + * constexpr.c (cxx_eval_vec_init_1): For reuse, treat NULL eltinit like + a valid constant initializer. Formatting fixes. + + PR c++/84557 + * parser.c (cp_parser_omp_var_list_no_open): Only call + cp_parser_lookup_name_simple on names satisfying identifier_p. + (cp_parser_oacc_routine): Likewise. + + 2018-02-20 Jakub Jelinek + + PR c++/84445 + * class.c (fixed_type_or_null) : Only test + TREE_HAS_CONSTRUCTOR if instance is not an internal function call. + + PR c++/84449 + * tree.c (bot_manip): If build_cplus_new or break_out_target_exprs + returns error_mark_node, return it immediately. + (break_out_target_exprs): If cp_walk_tree with bot_manip returns + error_mark_node, return error_mark_node. + + 2018-02-19 Jakub Jelinek + + PR c++/84448 + * parser.c (cp_parser_binary_expression): For no_toplevel_fold_p, if + either operand is error_mark_node, set current.lhs to that instead of + creating a binary op with error_mark_node operands. + + PR c++/84430 + * constexpr.c (potential_constant_expression_1): Handle OMP_SIMD. + + 2018-02-16 Marek Polacek + Jakub Jelinek + + PR c++/84192 + * constexpr.c (cxx_eval_constant_expression) : Don't + set *jump_target to anything if jump_target is NULL. + + 2018-02-12 Jakub Jelinek + + PR c++/84341 + * parser.c (cp_parser_binary_expression): Use build_min instead of + build2_loc to build the no_toplevel_fold_p toplevel binary expression. + + 2018-02-10 Jakub Jelinek + + PR sanitizer/83987 + * tree.c (cp_free_lang_data): Revert 2018-01-23 change. + + 2018-02-09 Marek Polacek + Jakub Jelinek + + PR c++/83659 + * constexpr.c (cxx_fold_indirect_ref): Sync some changes from + fold_indirect_ref_1. Verify first that tree_fits_shwi_p (op01). + Formatting fixes. + + 2018-02-07 Jakub Jelinek + + PR c++/84082 + * parser.c (cp_parser_dot_deref_incomplete): New function. + (cp_parser_postfix_dot_deref_expression): Use it. + + 2018-01-31 Jason Merrill + Jakub Jelinek + + PR c++/83993 + * constexpr.c (cxx_eval_outermost_constant_expr): Build NOP_EXPR + around non-constant ADDR_EXPRs rather than clearing TREE_CONSTANT + on ADDR_EXPR. + + 2018-01-25 Jakub Jelinek + + PR c++/84031 + * decl.c (find_decomp_class_base): Ignore unnamed bitfields. Ignore + recursive calls that return ret. + (cp_finish_decomp): Ignore unnamed bitfields. + + 2018-01-23 Jakub Jelinek + + PR sanitizer/83987 + * tree.c (cp_free_lang_data): Change DECL_VALUE_EXPR of + DECL_OMP_PRIVATIZED_MEMBER vars to error_mark_node. + + PR c++/83958 + * decl.c (cp_finish_decomp): Diagnose if reference structure binding + refers to incomplete type. + + 2018-01-18 Jakub Jelinek + + PR c++/83824 + * parser.c (attr_chainon): New function. + (cp_parser_label_for_labeled_statement, cp_parser_decl_specifier_seq, + cp_parser_namespace_definition, cp_parser_init_declarator, + cp_parser_type_specifier_seq, cp_parser_parameter_declaration, + cp_parser_gnu_attributes_opt): Use it. + (cp_parser_member_declaration, cp_parser_objc_class_ivars, + cp_parser_objc_struct_declaration): Likewise. Don't reset + prefix_attributes if attributes is error_mark_node. + + 2018-01-16 Jakub Jelinek + + PR c++/83817 + * pt.c (tsubst_copy_and_build) : If function + is AGGR_INIT_EXPR rather than CALL_EXPR, set AGGR_INIT_FROM_THUNK_P + instead of CALL_FROM_THUNK_P. + +2018-03-02 Jason Merrill + + Fix MIPS16 ICE. + * pt.c (type_dependent_expression_p): Check DECL_LANG_SPECIFIC. + +2018-02-27 Jason Merrill + + PR c++/84489 - dependent default template argument + * pt.c (type_unification_real): Handle early substitution failure. + +2018-03-01 Jason Merrill + + PR c++/71569 - decltype of template. + * parser.c (cp_parser_decltype_expr): Handle missing template args. + +2018-03-01 Jason Merrill + Alexandre Oliva + + PR c++/71569 - ICE with redundant args on member variable template. + * decl.c (start_decl): Handle partial specialization of member + variable template. + * pt.c (determine_specialization): Allow partial specialization + of member variable template without specializing enclosing class. + (process_partial_specialization): Improve error message. + +2018-02-28 Jason Merrill + + PR c++/71784 - ICE with ref-qualifier and explicit specialization. + * pt.c (determine_specialization): Check ref-qualifier. + +2018-02-27 Jason Merrill + + PR c++/84496 - ICE with generic lambda in lambda. + * pt.c (type_dependent_expression_p): Fix dependency checking of + functions without DECL_TEMPLATE_INFO. + +2018-02-26 Jason Merrill + + PR c++/84441 - ICE with base initialized from ?: + * call.c (unsafe_copy_elision_p): Handle COND_EXPR. + + PR c++/84520 - ICE with generic lambda in NSDMI. + * lambda.c (lambda_expr_this_capture): Don't look for fake NSDMI + 'this' in a generic lambda instantiation. + +2018-02-26 Jason Merrill + Ville Voutilainen + + PR c++/81589 - error with is_trivially_constructible. + * method.c (constructible_expr): Set cp_unevaluated. + +2018-02-25 Jason Merrill + + PR c++/84015 - ICE with class deduction and auto template parm. + * pt.c (rewrite_template_parm): Use tf_partial in first tsubst. + +2018-02-19 Jonathan Wakely + + Backport from mainline + 2017-08-29 Jason Merrill + + Fix lambdas in template default argument of inherited ctor. + * method.c (synthesized_method_base_walk): Replace an inherited + template with its specialization. + (synthesized_method_walk): Make inheriting_ctor a pointer. + (maybe_explain_implicit_delete, explain_implicit_non_constexpr) + (deduce_inheriting_ctor, implicitly_declare_fn): Adjust. + +2018-02-16 Jason Merrill + + PR c++/84151 - unnecessary volatile load with static member. + * call.c (build_new_method_call_1): Avoid loading from a volatile + lvalue used as the object argument for a static member function. + + PR c++/81853 - using-directive and constexpr. + * constexpr.c (cxx_eval_constant_expression): Handle USING_STMT. + + PR c++/84420 - ICE with structured binding in lambda. + * lambda.c (is_capture_proxy): Check DECL_DECOMPOSITION_P. + + PR c++/83835 - C++17 error with constructor ctors. + * call.c (build_special_member_call): Set TARGET_EXPR_DIRECT_INIT_P. + + PR c++/82664 - ICE with reference to function template parm. + * pt.c (convert_nontype_argument_function): Avoid obfuscationg + NOP_EXPRs. + + PR c++/82764 - C++17 ICE with empty base + * class.c (build_base_field_1): Set DECL_SIZE to zero for empty base. + + PR c++/83227 - C++17 ICE with init-list derived-to-base conversion. + * call.c (convert_like_real): Don't use the copy-list-initialization + shortcut for ck_base. + + PR c++/84045 - ICE with typedef and noexcept. + * except.c (build_noexcept_spec): Use strip_typedefs_expr. + +2018-01-29 Jason Merrill + + PR c++/82461 - constexpr list-initialized member + * constexpr.c (potential_constant_expression_1): Check + TARGET_EXPR_DIRECT_INIT_P. + +2018-01-26 Nathan Sidwell + + PR c++/82878 + PR c++/78495 + * call.c (build_call_a): Don't set CALL_FROM_THUNK_P for inherited + ctor. + * cp-gimplify.c (cp_genericize_r): Restore THUNK dereference + inhibibition check removed in previous c++/78495 change. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: gcc/cp/cp-gimplify.c =================================================================== diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c --- a/gcc/cp/cp-gimplify.c (revision 257042) +++ b/gcc/cp/cp-gimplify.c (revision 259627) @@ -1107,6 +1107,14 @@ && omp_var_to_track (stmt)) omp_cxx_notice_variable (wtd->omp_ctx, stmt); + /* Don't dereference parms in a thunk, pass the references through. */ + if ((TREE_CODE (stmt) == CALL_EXPR && CALL_FROM_THUNK_P (stmt)) + || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt))) + { + *walk_subtrees = 0; + return NULL; + } + /* Dereference invisible reference parms. */ if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt)) { Index: gcc/cp/typeck2.c =================================================================== diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c --- a/gcc/cp/typeck2.c (revision 257042) +++ b/gcc/cp/typeck2.c (revision 259627) @@ -817,9 +817,12 @@ bool const_init; value = instantiate_non_dependent_expr (value); if (DECL_DECLARED_CONSTEXPR_P (decl) - || (DECL_IN_AGGR_P (decl) && !DECL_VAR_DECLARED_INLINE_P (decl))) + || (DECL_IN_AGGR_P (decl) + && DECL_INITIALIZED_IN_CLASS_P (decl) + && !DECL_VAR_DECLARED_INLINE_P (decl))) { - /* Diagnose a non-constant initializer for constexpr. */ + /* Diagnose a non-constant initializer for constexpr variable or + non-inline in-class-initialized static data member. */ if (processing_template_decl && !require_potential_constant_expression (value)) value = error_mark_node; Index: gcc/cp/pt.c =================================================================== diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c --- a/gcc/cp/pt.c (revision 257042) +++ b/gcc/cp/pt.c (revision 259627) @@ -2072,7 +2072,8 @@ /* We shouldn't be specializing a member template of an unspecialized class template; we already gave an error in check_specialization_scope, now avoid crashing. */ - if (template_count && DECL_CLASS_SCOPE_P (decl) + if (!VAR_P (decl) + && template_count && DECL_CLASS_SCOPE_P (decl) && template_class_depth (DECL_CONTEXT (decl)) > 0) { gcc_assert (errorcount); @@ -2175,11 +2176,18 @@ that the const qualification is the same. Since get_bindings does not try to merge the "this" parameter, we must do the comparison explicitly. */ - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) - && !same_type_p (TREE_VALUE (fn_arg_types), - TREE_VALUE (decl_arg_types))) - continue; + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + { + if (!same_type_p (TREE_VALUE (fn_arg_types), + TREE_VALUE (decl_arg_types))) + continue; + /* And the ref-qualification. */ + if (type_memfn_rqual (TREE_TYPE (decl)) + != type_memfn_rqual (TREE_TYPE (fn))) + continue; + } + /* Skip the "this" parameter and, for constructors of classes with virtual bases, the VTT parameter. A full specialization of a constructor will have a VTT @@ -2284,6 +2292,11 @@ decl_arg_types)) continue; + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) + && (type_memfn_rqual (TREE_TYPE (decl)) + != type_memfn_rqual (TREE_TYPE (fn)))) + continue; + // If the deduced arguments do not satisfy the constraints, // this is not a candidate. if (flag_concepts && !constraints_satisfied_p (fn)) @@ -4601,10 +4614,13 @@ { if (!flag_concepts) error ("partial specialization %q+D does not specialize " - "any template arguments", decl); + "any template arguments; to define the primary template, " + "remove the template argument list", decl); else error ("partial specialization %q+D does not specialize any " - "template arguments and is not more constrained than", decl); + "template arguments and is not more constrained than " + "the primary template; to define the primary template, " + "remove the template argument list", decl); inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here"); } @@ -6032,7 +6048,12 @@ accept: if (TREE_CODE (type) == REFERENCE_TYPE) - fn = build_address (fn); + { + if (REFERENCE_REF_P (fn)) + fn = TREE_OPERAND (fn, 0); + else + fn = build_address (fn); + } if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (fn))) fn = build_nop (type, fn); @@ -8244,7 +8265,11 @@ } if (lost) - return error_mark_node; + { + if ((complain & tf_error) && !seen_error()) + error ("wrong number of template arguments"); + return error_mark_node; + } if (CHECKING_P && !NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args)) SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args, @@ -11454,7 +11479,9 @@ { /* This parameter pack was used in an unevaluated context. Just make a dummy decl, since it's only used for its type. */ + ++cp_unevaluated_operand; arg_pack = tsubst_decl (parm_pack, args, complain); + --cp_unevaluated_operand; if (arg_pack && DECL_PACK_P (arg_pack)) /* Partial instantiation of the parm_pack, we can't build up an argument pack yet. */ @@ -11524,7 +11551,7 @@ /* We can't substitute for this parameter pack. We use a flag as well as the missing_level counter because function parameter packs don't have a level. */ - gcc_assert (processing_template_decl); + gcc_assert (processing_template_decl || is_auto (parm_pack)); unsubstituted_packs = true; } } @@ -13755,8 +13782,7 @@ = tsubst_constraint (constr, args, complain, in_decl); else if (tree pl = CLASS_PLACEHOLDER_TEMPLATE (t)) { - if (DECL_TEMPLATE_TEMPLATE_PARM_P (pl)) - pl = tsubst (pl, args, complain, in_decl); + pl = tsubst_copy (pl, args, complain, in_decl); CLASS_PLACEHOLDER_TEMPLATE (r) = pl; } } @@ -17492,7 +17518,10 @@ CALL_EXPR_REVERSE_ARGS (function) = rev; if (thk) { - CALL_FROM_THUNK_P (function) = true; + if (TREE_CODE (function) == CALL_EXPR) + CALL_FROM_THUNK_P (function) = true; + else + AGGR_INIT_FROM_THUNK_P (function) = true; /* The thunk location is not interesting. */ SET_EXPR_LOCATION (function, UNKNOWN_LOCATION); } @@ -24065,20 +24094,21 @@ && (any_dependent_template_arguments_p (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression))))) return true; + } - /* Otherwise, if the decl isn't from a dependent scope, it can't be - type-dependent. Checking this is important for functions with auto - return type, which looks like a dependent type. */ - if (TREE_CODE (expression) == FUNCTION_DECL - && undeduced_auto_decl (expression) - && (!DECL_CLASS_SCOPE_P (expression) - || !dependent_type_p (DECL_CONTEXT (expression))) - && (!DECL_FRIEND_CONTEXT (expression) - || !dependent_type_p (DECL_FRIEND_CONTEXT (expression))) - && !DECL_LOCAL_FUNCTION_P (expression)) - { - return false; - } + /* Otherwise, if the decl isn't from a dependent scope, it can't be + type-dependent. Checking this is important for functions with auto + return type, which looks like a dependent type. */ + if (TREE_CODE (expression) == FUNCTION_DECL + && undeduced_auto_decl (expression) + && (!DECL_CLASS_SCOPE_P (expression) + || !dependent_type_p (DECL_CONTEXT (expression))) + && (!DECL_LANG_SPECIFIC (expression) + || !DECL_FRIEND_CONTEXT (expression) + || !dependent_type_p (DECL_FRIEND_CONTEXT (expression))) + && !DECL_LOCAL_FUNCTION_P (expression)) + { + return false; } /* Always dependent, on the number of arguments if nothing else. */ @@ -25105,8 +25135,21 @@ = TEMPLATE_TYPE_PARM_FOR_CLASS (oldtype); } else - newtype = tsubst (TREE_TYPE (olddecl), tsubst_args, - complain, NULL_TREE); + { + newtype = TREE_TYPE (olddecl); + if (type_uses_auto (newtype)) + { + // Substitute once to fix references to other template parameters. + newtype = tsubst (newtype, tsubst_args, + complain|tf_partial, NULL_TREE); + // Now substitute again to reduce the level of the auto. + newtype = tsubst (newtype, current_template_args (), + complain, NULL_TREE); + } + else + newtype = tsubst (newtype, tsubst_args, + complain, NULL_TREE); + } tree newdecl = build_decl (DECL_SOURCE_LOCATION (olddecl), TREE_CODE (olddecl), @@ -25145,7 +25188,7 @@ // Substitute ttargs into ttparms to fix references to // other template parameters. ttparms = tsubst_template_parms_level (ttparms, ttargs, - complain); + complain|tf_partial); // Now substitute again with args based on tparms, to reduce // the level of the ttparms. ttargs = current_template_args (); @@ -25386,6 +25429,9 @@ // FIXME cache artificial deduction guides for (tree fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns)) { + if (TREE_CODE (fns) == OVERLOAD && OVL_USED (fns)) + continue; + tree fn = OVL_CURRENT (fns); tree guide = build_deduction_guide (fn, outer_args, complain); cands = ovl_cons (guide, cands); Index: gcc/cp/semantics.c =================================================================== diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c --- a/gcc/cp/semantics.c (revision 257042) +++ b/gcc/cp/semantics.c (revision 259627) @@ -730,7 +730,10 @@ cond = maybe_convert_cond (cond); if (IF_STMT_CONSTEXPR_P (if_stmt) && require_potential_rvalue_constant_expression (cond) - && !value_dependent_expression_p (cond)) + && !value_dependent_expression_p (cond) + /* Wait until instantiation time, since only then COND has been + converted to bool. */ + && TREE_TYPE (cond) == boolean_type_node) { cond = instantiate_non_dependent_expr (cond); cond = cxx_constant_value (cond, NULL_TREE); Index: gcc/cp/decl2.c =================================================================== diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c --- a/gcc/cp/decl2.c (revision 257042) +++ b/gcc/cp/decl2.c (revision 259627) @@ -1360,7 +1360,7 @@ { tree expr = TREE_VALUE (arg); if (EXPR_P (expr)) - TREE_VALUE (arg) = maybe_constant_value (expr); + TREE_VALUE (arg) = fold_non_dependent_expr (expr); } } } Index: gcc/cp/parser.c =================================================================== diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c --- a/gcc/cp/parser.c (revision 257042) +++ b/gcc/cp/parser.c (revision 259627) @@ -7252,6 +7252,60 @@ return postfix_expression; } +/* A subroutine of cp_parser_postfix_dot_deref_expression. Handle dot + dereference of incomplete type, returns true if error_mark_node should + be returned from caller, otherwise adjusts *SCOPE, *POSTFIX_EXPRESSION + and *DEPENDENT_P. */ + +bool +cp_parser_dot_deref_incomplete (tree *scope, cp_expr *postfix_expression, + bool *dependent_p) +{ + /* In a template, be permissive by treating an object expression + of incomplete type as dependent (after a pedwarn). */ + diagnostic_t kind = (processing_template_decl + && MAYBE_CLASS_TYPE_P (*scope) ? DK_PEDWARN : DK_ERROR); + + switch (TREE_CODE (*postfix_expression)) + { + case CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case CONST_CAST_EXPR: + case STATIC_CAST_EXPR: + case DYNAMIC_CAST_EXPR: + case IMPLICIT_CONV_EXPR: + case VIEW_CONVERT_EXPR: + case NON_LVALUE_EXPR: + kind = DK_ERROR; + break; + case OVERLOAD: + /* Don't emit any diagnostic for OVERLOADs. */ + kind = DK_IGNORED; + break; + default: + /* Avoid clobbering e.g. DECLs. */ + if (!EXPR_P (*postfix_expression)) + kind = DK_ERROR; + break; + } + + if (kind == DK_IGNORED) + return false; + + location_t exploc = location_of (*postfix_expression); + cxx_incomplete_type_diagnostic (exploc, *postfix_expression, *scope, kind); + if (!MAYBE_CLASS_TYPE_P (*scope)) + return true; + if (kind == DK_ERROR) + *scope = *postfix_expression = error_mark_node; + else if (processing_template_decl) + { + *dependent_p = true; + *scope = TREE_TYPE (*postfix_expression) = NULL_TREE; + } + return false; +} + /* A subroutine of cp_parser_postfix_expression that also gets hijacked by cp_parser_builtin_offsetof. We're looking for @@ -7316,23 +7370,9 @@ { scope = complete_type (scope); if (!COMPLETE_TYPE_P (scope) - /* Avoid clobbering e.g. OVERLOADs or DECLs. */ - && EXPR_P (postfix_expression)) - { - /* In a template, be permissive by treating an object expression - of incomplete type as dependent (after a pedwarn). */ - diagnostic_t kind = (processing_template_decl - ? DK_PEDWARN - : DK_ERROR); - cxx_incomplete_type_diagnostic - (location_of (postfix_expression), - postfix_expression, scope, kind); - if (processing_template_decl) - { - dependent_p = true; - scope = TREE_TYPE (postfix_expression) = NULL_TREE; - } - } + && cp_parser_dot_deref_incomplete (&scope, &postfix_expression, + &dependent_p)) + return error_mark_node; } if (!dependent_p) @@ -9030,12 +9070,20 @@ if (no_toplevel_fold_p && lookahead_prec <= current.prec && sp == stack) - current.lhs = build2_loc (combined_loc, - current.tree_type, - TREE_CODE_CLASS (current.tree_type) - == tcc_comparison - ? boolean_type_node : TREE_TYPE (current.lhs), - current.lhs, rhs); + { + if (current.lhs == error_mark_node || rhs == error_mark_node) + current.lhs = error_mark_node; + else + { + current.lhs + = build_min (current.tree_type, + TREE_CODE_CLASS (current.tree_type) + == tcc_comparison + ? boolean_type_node : TREE_TYPE (current.lhs), + current.lhs.get_value (), rhs.get_value ()); + SET_EXPR_LOCATION (current.lhs, combined_loc); + } + } else { current.lhs = build_x_binary_op (combined_loc, current.tree_type, @@ -10743,6 +10791,18 @@ "attributes at the beginning of statement are ignored"); } +/* Append ATTR to attribute list ATTRS. */ + +static tree +attr_chainon (tree attrs, tree attr) +{ + if (attrs == error_mark_node) + return error_mark_node; + if (attr == error_mark_node) + return error_mark_node; + return chainon (attrs, attr); +} + /* Parse the label for a labeled-statement, i.e. identifier : @@ -10862,7 +10922,7 @@ else if (!cp_parser_parse_definitely (parser)) ; else - attributes = chainon (attributes, attrs); + attributes = attr_chainon (attributes, attrs); } if (attributes != NULL_TREE) @@ -11798,7 +11858,7 @@ /*protect=*/2, /*want_type=*/false, tf_warning_or_error); - if (member_begin != NULL_TREE || member_end != NULL_TREE) + if (member_begin != NULL_TREE && member_end != NULL_TREE) { /* Use the member functions. */ if (member_begin != NULL_TREE) @@ -13194,8 +13254,7 @@ else { decl_specs->std_attributes - = chainon (decl_specs->std_attributes, - attrs); + = attr_chainon (decl_specs->std_attributes, attrs); if (decl_specs->locations[ds_std_attribute] == 0) decl_specs->locations[ds_std_attribute] = token->location; } @@ -13203,9 +13262,8 @@ } } - decl_specs->attributes - = chainon (decl_specs->attributes, - attrs); + decl_specs->attributes + = attr_chainon (decl_specs->attributes, attrs); if (decl_specs->locations[ds_attribute] == 0) decl_specs->locations[ds_attribute] = token->location; continue; @@ -13688,6 +13746,10 @@ expr = cp_parser_lookup_name_simple (parser, expr, id_expr_start_token->location); + if (expr && TREE_CODE (expr) == TEMPLATE_DECL) + /* A template without args is not a complete id-expression. */ + expr = error_mark_node; + if (expr && expr != error_mark_node && TREE_CODE (expr) != TYPE_DECL @@ -13753,6 +13815,9 @@ expression. */ cp_parser_abort_tentative_parse (parser); + /* Commit to the tentative_firewall so we get syntax errors. */ + cp_parser_commit_to_tentative_parse (parser); + /* Parse a full expression. */ expr = cp_parser_expression (parser, /*pidk=*/NULL, /*cast_p=*/false, /*decltype_p=*/true); @@ -18220,7 +18285,7 @@ if (post_ident_attribs) { if (attribs) - attribs = chainon (attribs, post_ident_attribs); + attribs = attr_chainon (attribs, post_ident_attribs); else attribs = post_ident_attribs; } @@ -19394,7 +19459,7 @@ decl = grokfield (declarator, decl_specifiers, initializer, !is_non_constant_init, /*asmspec=*/NULL_TREE, - chainon (attributes, prefix_attributes)); + attr_chainon (attributes, prefix_attributes)); if (decl && TREE_CODE (decl) == FUNCTION_DECL) cp_parser_save_default_args (parser, decl); cp_finalize_omp_declare_simd (parser, decl); @@ -20789,9 +20854,9 @@ /* Check for attributes first. */ if (cp_next_tokens_can_be_attribute_p (parser)) { - type_specifier_seq->attributes = - chainon (type_specifier_seq->attributes, - cp_parser_attributes_opt (parser)); + type_specifier_seq->attributes + = attr_chainon (type_specifier_seq->attributes, + cp_parser_attributes_opt (parser)); continue; } @@ -20904,7 +20969,10 @@ if (!processing_specialization && !processing_template_parmlist - && !processing_explicit_instantiation) + && !processing_explicit_instantiation + /* default_arg_ok_p tracks whether this is a parameter-clause for an + actual function or a random abstract declarator. */ + && parser->default_arg_ok_p) if (!current_function_decl || (current_class_type && LAMBDA_TYPE_P (current_class_type))) parser->auto_is_implicit_function_template_parm_p = true; @@ -21013,9 +21081,6 @@ cp_parameter_declarator *parameter; tree decl = error_mark_node; bool parenthesized_p = false; - int template_parm_idx = (function_being_declared_is_template_p (parser)? - TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS - (current_template_parms)) : 0); /* Parse the parameter. */ parameter @@ -21029,22 +21094,6 @@ if (parameter) { - /* If a function parameter pack was specified and an implicit template - parameter was introduced during cp_parser_parameter_declaration, - change any implicit parameters introduced into packs. */ - if (parser->implicit_template_parms - && parameter->declarator - && parameter->declarator->parameter_pack_p) - { - int latest_template_parm_idx = TREE_VEC_LENGTH - (INNERMOST_TEMPLATE_PARMS (current_template_parms)); - - if (latest_template_parm_idx != template_parm_idx) - parameter->decl_specifiers.type = convert_generic_types_to_packs - (parameter->decl_specifiers.type, - template_parm_idx, latest_template_parm_idx); - } - decl = grokdeclarator (parameter->declarator, ¶meter->decl_specifiers, PARM, @@ -21202,6 +21251,10 @@ parser->type_definition_forbidden_message = G_("types may not be defined in parameter types"); + int template_parm_idx = (function_being_declared_is_template_p (parser) ? + TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS + (current_template_parms)) : 0); + /* Parse the declaration-specifiers. */ cp_parser_decl_specifier_seq (parser, CP_PARSER_FLAGS_NONE, @@ -21270,8 +21323,8 @@ parser->default_arg_ok_p = saved_default_arg_ok_p; /* After the declarator, allow more attributes. */ decl_specifiers.attributes - = chainon (decl_specifiers.attributes, - cp_parser_attributes_opt (parser)); + = attr_chainon (decl_specifiers.attributes, + cp_parser_attributes_opt (parser)); /* If the declarator is a template parameter pack, remember that and clear the flag in the declarator itself so we don't get errors @@ -21290,6 +21343,23 @@ parameter pack expansion expression. Otherwise, leave the ellipsis for a C-style variadic function. */ token = cp_lexer_peek_token (parser->lexer); + + /* If a function parameter pack was specified and an implicit template + parameter was introduced during cp_parser_parameter_declaration, + change any implicit parameters introduced into packs. */ + if (parser->implicit_template_parms + && (token->type == CPP_ELLIPSIS + || (declarator && declarator->parameter_pack_p))) + { + int latest_template_parm_idx = TREE_VEC_LENGTH + (INNERMOST_TEMPLATE_PARMS (current_template_parms)); + + if (latest_template_parm_idx != template_parm_idx) + decl_specifiers.type = convert_generic_types_to_packs + (decl_specifiers.type, + template_parm_idx, latest_template_parm_idx); + } + if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) { tree type = decl_specifiers.type; @@ -23261,7 +23331,7 @@ which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); /* Create the bitfield declaration. */ decl = grokbitfield (identifier @@ -23318,7 +23388,7 @@ which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); /* If it's an `=', then we have a constant-initializer or a pure-specifier. It is not correct to parse the @@ -23432,10 +23502,13 @@ cp_finalize_oacc_routine (parser, decl, false); /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } /* If there is any qualification still in effect, clear it now; we will be starting fresh with the next declarator. */ @@ -24547,7 +24620,7 @@ cp_parser_skip_to_end_of_statement (parser); /* Add these new attributes to the list. */ - attributes = chainon (attributes, attribute_list); + attributes = attr_chainon (attributes, attribute_list); } return attributes; @@ -29725,7 +29798,7 @@ which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); if (width) /* Create the bitfield declaration. */ @@ -29742,10 +29815,13 @@ objc_add_instance_variable (decl); /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } token = cp_lexer_peek_token (parser->lexer); @@ -30275,8 +30351,8 @@ which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); - + attributes = attr_chainon (prefix_attributes, attributes); + decl = grokfield (declarator, &declspecs, NULL_TREE, /*init_const_expr_p=*/false, NULL_TREE, attributes); @@ -30285,10 +30361,13 @@ return error_mark_node; /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } DECL_CHAIN (decl) = decls; decls = decl; @@ -30888,7 +30967,10 @@ if (name == error_mark_node) goto skip_comma; - decl = cp_parser_lookup_name_simple (parser, name, token->location); + if (identifier_p (name)) + decl = cp_parser_lookup_name_simple (parser, name, token->location); + else + decl = name; if (decl == error_mark_node) cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, token->location); @@ -37448,7 +37530,9 @@ /*template_p=*/NULL, /*declarator_p=*/false, /*optional_p=*/false); - tree decl = cp_parser_lookup_name_simple (parser, name, name_loc); + tree decl = (identifier_p (name) + ? cp_parser_lookup_name_simple (parser, name, name_loc) + : name); if (name != error_mark_node && decl == error_mark_node) cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, name_loc); Index: gcc/cp/call.c =================================================================== diff --git a/gcc/cp/call.c b/gcc/cp/call.c --- a/gcc/cp/call.c (revision 257042) +++ b/gcc/cp/call.c (revision 259627) @@ -375,18 +375,10 @@ TREE_HAS_CONSTRUCTOR (function) = (decl && DECL_CONSTRUCTOR_P (decl)); - if (current_function_decl && decl - && flag_new_inheriting_ctors - && DECL_INHERITED_CTOR (current_function_decl) - && (DECL_INHERITED_CTOR (current_function_decl) - == DECL_CLONED_FUNCTION (decl))) - /* Pass arguments directly to the inherited constructor. */ - CALL_FROM_THUNK_P (function) = true; - /* Don't pass empty class objects by value. This is useful for tags in STL, which are used to control overload resolution. We don't need to handle other cases of copying empty classes. */ - else if (! decl || ! DECL_BUILT_IN (decl)) + if (! decl || ! DECL_BUILT_IN (decl)) for (i = 0; i < n; i++) { tree arg = CALL_EXPR_ARG (function, i); @@ -3267,10 +3259,10 @@ tree return_type, tree access_path, tree conversion_path, tsubst_flags_t complain) { - /* Making this work broke PR 71117, so until the committee resolves core - issue 2189, let's disable this candidate if there are any viable call + /* Making this work broke PR 71117 and 85118, so until the committee resolves + core issue 2189, let's disable this candidate if there are any call operators. */ - if (any_strictly_viable (*candidates)) + if (*candidates) return NULL; return @@ -6886,6 +6878,11 @@ && DECL_INHERITED_CTOR (current_function_decl)) return expr; + if (TREE_CODE (expr) == TARGET_EXPR + && TARGET_EXPR_LIST_INIT_P (expr)) + /* Copy-list-initialization doesn't actually involve a copy. */ + return expr; + /* Fall through. */ case ck_base: if (convs->kind == ck_base && !convs->need_temporary_p) @@ -6911,10 +6908,6 @@ flags |= LOOKUP_ONLYCONVERTING; if (convs->rvaluedness_matches_p) flags |= LOOKUP_PREFER_RVALUE; - if (TREE_CODE (expr) == TARGET_EXPR - && TARGET_EXPR_LIST_INIT_P (expr)) - /* Copy-list-initialization doesn't actually involve a copy. */ - return expr; expr = build_temp (expr, totype, flags, &diag_kind, complain); if (diag_kind && complain) { @@ -7525,6 +7518,15 @@ /* build_compound_expr pushes COMPOUND_EXPR inside TARGET_EXPR. */ while (TREE_CODE (init) == COMPOUND_EXPR) init = TREE_OPERAND (init, 1); + if (TREE_CODE (init) == COND_EXPR) + { + /* We'll end up copying from each of the arms of the COND_EXPR directly + into the target, so look at them. */ + if (tree op = TREE_OPERAND (init, 1)) + if (unsafe_copy_elision_p (target, op)) + return true; + return unsafe_copy_elision_p (target, TREE_OPERAND (init, 2)); + } return (TREE_CODE (init) == AGGR_INIT_EXPR && !AGGR_INIT_VIA_CTOR_P (init)); } @@ -8399,6 +8401,9 @@ { if (is_dummy_object (instance)) return arg; + else if (TREE_CODE (arg) == TARGET_EXPR) + TARGET_EXPR_DIRECT_INIT_P (arg) = true; + if ((complain & tf_error) && (flags & LOOKUP_DELEGATING_CONS)) check_self_delegation (arg); @@ -8851,8 +8856,14 @@ if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE && !is_dummy_object (instance) && TREE_SIDE_EFFECTS (instance)) - call = build2 (COMPOUND_EXPR, TREE_TYPE (call), - instance, call); + { + /* But avoid the implicit lvalue-rvalue conversion when 'a' + is volatile. */ + tree a = instance; + if (TREE_THIS_VOLATILE (a)) + a = build_this (a); + call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call); + } else if (call != error_mark_node && DECL_DESTRUCTOR_P (cand->fn) && !VOID_TYPE_P (TREE_TYPE (call))) Index: gcc/cp/lambda.c =================================================================== diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c --- a/gcc/cp/lambda.c (revision 257042) +++ b/gcc/cp/lambda.c (revision 259627) @@ -262,6 +262,7 @@ return (VAR_P (decl) && DECL_HAS_VALUE_EXPR_P (decl) && !DECL_ANON_UNION_VAR_P (decl) + && !DECL_DECOMPOSITION_P (decl) && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl))); } @@ -712,11 +713,14 @@ lambda_stack); if (LAMBDA_EXPR_EXTRA_SCOPE (tlambda) + && !COMPLETE_TYPE_P (LAMBDA_EXPR_CLOSURE (tlambda)) && TREE_CODE (LAMBDA_EXPR_EXTRA_SCOPE (tlambda)) == FIELD_DECL) { /* In an NSDMI, we don't have a function to look up the decl in, but the fake 'this' pointer that we're using for parsing is - in scope_chain. */ + in scope_chain. But if the closure is already complete, we're + in an instantiation of a generic lambda, and the fake 'this' + is gone. */ init = scope_chain->x_current_class_ptr; gcc_checking_assert (init && (TREE_TYPE (TREE_TYPE (init)) @@ -1072,7 +1076,6 @@ } } - if (generic_lambda_p) { if (decltype_call) Index: gcc/cp/cvt.c =================================================================== diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c --- a/gcc/cp/cvt.c (revision 257042) +++ b/gcc/cp/cvt.c (revision 259627) @@ -1053,6 +1053,8 @@ || TREE_TYPE (expr) == error_mark_node) return error_mark_node; + expr = maybe_undo_parenthesized_ref (expr); + if (implicit == ICV_CAST) mark_exp_read (expr); else Index: gcc/cp/search.c =================================================================== diff --git a/gcc/cp/search.c b/gcc/cp/search.c --- a/gcc/cp/search.c (revision 257042) +++ b/gcc/cp/search.c (revision 259627) @@ -2879,7 +2879,7 @@ bool any_dependent_bases_p (tree type) { - if (!type || !CLASS_TYPE_P (type) || !processing_template_decl) + if (!type || !CLASS_TYPE_P (type) || !uses_template_parms (type)) return false; unsigned i; Index: gcc/lto-streamer-out.c =================================================================== diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c --- a/gcc/lto-streamer-out.c (revision 257042) +++ b/gcc/lto-streamer-out.c (revision 259627) @@ -2524,13 +2524,10 @@ const char *comdat; unsigned char c; - /* None of the following kinds of symbols are needed in the - symbol table. */ - if (!TREE_PUBLIC (t) - || is_builtin_fn (t) - || DECL_ABSTRACT_P (t) - || (VAR_P (t) && DECL_HARD_REGISTER (t))) - return; + gcc_checking_assert (TREE_PUBLIC (t) + && !is_builtin_fn (t) + && !DECL_ABSTRACT_P (t) + && (!VAR_P (t) || !DECL_HARD_REGISTER (t))); gcc_assert (VAR_OR_FUNCTION_DECL_P (t)); @@ -2618,45 +2615,6 @@ lto_write_data (&slot_num, 4); } -/* Return true if NODE should appear in the plugin symbol table. */ - -bool -output_symbol_p (symtab_node *node) -{ - struct cgraph_node *cnode; - if (!node->real_symbol_p ()) - return false; - /* We keep external functions in symtab for sake of inlining - and devirtualization. We do not want to see them in symbol table as - references unless they are really used. */ - cnode = dyn_cast (node); - if (cnode && (!node->definition || DECL_EXTERNAL (cnode->decl)) - && cnode->callers) - return true; - - /* Ignore all references from external vars initializers - they are not really - part of the compilation unit until they are used by folding. Some symbols, - like references to external construction vtables can not be referred to at all. - We decide this at can_refer_decl_in_current_unit_p. */ - if (!node->definition || DECL_EXTERNAL (node->decl)) - { - int i; - struct ipa_ref *ref; - for (i = 0; node->iterate_referring (i, ref); i++) - { - if (ref->use == IPA_REF_ALIAS) - continue; - if (is_a (ref->referring)) - return true; - if (!DECL_EXTERNAL (ref->referring->decl)) - return true; - } - return false; - } - return true; -} - - /* Write an IL symbol table to OB. SET and VSET are cgraph/varpool node sets we are outputting. */ @@ -2681,7 +2639,7 @@ { symtab_node *node = lsei_node (lsei); - if (!output_symbol_p (node) || DECL_EXTERNAL (node->decl)) + if (DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ()) continue; write_symbol (cache, node->decl, &seen, false); } @@ -2690,7 +2648,7 @@ { symtab_node *node = lsei_node (lsei); - if (!output_symbol_p (node) || !DECL_EXTERNAL (node->decl)) + if (!DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ()) continue; write_symbol (cache, node->decl, &seen, false); } Index: gcc/ipa-utils.c =================================================================== diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c --- a/gcc/ipa-utils.c (revision 257042) +++ b/gcc/ipa-utils.c (revision 259627) @@ -404,6 +404,8 @@ if (!dst->count) return; + if (!src->count || src->alias) + return; if (symtab->dump_file) { fprintf (symtab->dump_file, "Merging profiles of %s/%i to %s/%i\n", Index: gcc/ipa-inline.c =================================================================== diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c --- a/gcc/ipa-inline.c (revision 257042) +++ b/gcc/ipa-inline.c (revision 259627) @@ -1773,7 +1773,7 @@ struct cgraph_node *n2; int id = dfs->scc_no + 1; for (n2 = node; n2; - n2 = ((struct ipa_dfs_info *) node->aux)->next_cycle) + n2 = ((struct ipa_dfs_info *) n2->aux)->next_cycle) { struct inline_summary *info2 = inline_summaries->get (n2); if (info2->scc_no) Index: gcc/machmode.def =================================================================== diff --git a/gcc/machmode.def b/gcc/machmode.def --- a/gcc/machmode.def (revision 257042) +++ b/gcc/machmode.def (revision 259627) @@ -243,6 +243,7 @@ /* Complex modes. */ COMPLEX_MODES (INT); +COMPLEX_MODES (PARTIAL_INT); COMPLEX_MODES (FLOAT); /* Decimal floating point modes. */ Index: gcc/expr.c =================================================================== diff --git a/gcc/expr.c b/gcc/expr.c --- a/gcc/expr.c (revision 257042) +++ b/gcc/expr.c (revision 259627) @@ -6893,8 +6893,9 @@ if (GET_CODE (temp) == PARALLEL) { HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp)); - machine_mode temp_mode - = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT); + machine_mode temp_mode = GET_MODE (temp); + if (temp_mode == BLKmode || temp_mode == VOIDmode) + temp_mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT); rtx temp_target = gen_reg_rtx (temp_mode); emit_group_store (temp_target, temp, TREE_TYPE (exp), size); temp = temp_target; @@ -10862,18 +10863,30 @@ tree fndecl = get_callee_fndecl (exp), attr; if (fndecl + /* Don't diagnose the error attribute in thunks, those are + artificially created. */ + && !CALL_FROM_THUNK_P (exp) && (attr = lookup_attribute ("error", DECL_ATTRIBUTES (fndecl))) != NULL) - error ("%Kcall to %qs declared with attribute error: %s", - exp, identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 1)), - TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + { + const char *ident = lang_hooks.decl_printable_name (fndecl, 1); + error ("%Kcall to %qs declared with attribute error: %s", exp, + identifier_to_locale (ident), + TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + } if (fndecl + /* Don't diagnose the warning attribute in thunks, those are + artificially created. */ + && !CALL_FROM_THUNK_P (exp) && (attr = lookup_attribute ("warning", DECL_ATTRIBUTES (fndecl))) != NULL) - warning_at (tree_nonartificial_location (exp), - 0, "%Kcall to %qs declared with attribute warning: %s", - exp, identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 1)), - TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + { + const char *ident = lang_hooks.decl_printable_name (fndecl, 1); + warning_at (tree_nonartificial_location (exp), 0, + "%Kcall to %qs declared with attribute warning: %s", + exp, identifier_to_locale (ident), + TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + } /* Check for a built-in function. */ if (fndecl && DECL_BUILT_IN (fndecl)) Index: gcc/opts.c =================================================================== diff --git a/gcc/opts.c b/gcc/opts.c --- a/gcc/opts.c (revision 257042) +++ b/gcc/opts.c (revision 259627) @@ -1014,6 +1014,26 @@ if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm) sorry ("transactional memory is not supported with " "%<-fsanitize=kernel-address%>"); + + /* Comes from final.c -- no real reason to change it. */ +#define MAX_CODE_ALIGN 16 +#define MAX_CODE_ALIGN_VALUE (1 << MAX_CODE_ALIGN) + + if (opts->x_align_loops > MAX_CODE_ALIGN_VALUE) + error_at (loc, "-falign-loops=%d is not between 0 and %d", + opts->x_align_loops, MAX_CODE_ALIGN_VALUE); + + if (opts->x_align_jumps > MAX_CODE_ALIGN_VALUE) + error_at (loc, "-falign-jumps=%d is not between 0 and %d", + opts->x_align_jumps, MAX_CODE_ALIGN_VALUE); + + if (opts->x_align_functions > MAX_CODE_ALIGN_VALUE) + error_at (loc, "-falign-functions=%d is not between 0 and %d", + opts->x_align_functions, MAX_CODE_ALIGN_VALUE); + + if (opts->x_align_labels > MAX_CODE_ALIGN_VALUE) + error_at (loc, "-falign-labels=%d is not between 0 and %d", + opts->x_align_labels, MAX_CODE_ALIGN_VALUE); } #define LEFT_COLUMN 27 Index: gcc/lra-lives.c =================================================================== diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c --- a/gcc/lra-lives.c (revision 257042) +++ b/gcc/lra-lives.c (revision 259627) @@ -593,7 +593,9 @@ reg_early_clobber_p (const struct lra_insn_reg *reg, int n_alt) { return (reg->early_clobber - && (n_alt < 0 || TEST_BIT (reg->early_clobber_alts, n_alt))); + && (n_alt == LRA_UNKNOWN_ALT + || (n_alt != LRA_NON_CLOBBERED_ALT + && TEST_BIT (reg->early_clobber_alts, n_alt)))); } /* Process insns of the basic block BB to update pseudo live ranges, Index: gcc/ada/ChangeLog =================================================================== diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog --- a/gcc/ada/ChangeLog (revision 257042) +++ b/gcc/ada/ChangeLog (revision 259627) @@ -1,3 +1,29 @@ +2018-04-12 Sebastian Huber + + Backport from mainline + 2018-03-07 Sebastian Huber + + * gcc-interface/Makefile.in (OSCONS_CPP): Remove redundant + $(GNATLIBCFLAGS). + (OSCONS_EXTRACT): Add $(GNATLIBCFLAGS_FOR_C). + +2018-03-12 Eric Botcazou + + PR ada/82813 + * gcc-interface/misc.c (gnat_post_options): Disable string overflow + warnings. + +2018-03-10 Eric Botcazou + + * gcc-interface/trans.c (node_has_volatile_full_access) : + Consider only entities for objects. + +2018-03-06 Eric Botcazou + + * gcc-interface/trans.c (convert_with_check): Fix typo in the condition + guarding the overflow check emitted for the upper bound of a floating- + point conversion. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: gcc/ada/gcc-interface/Makefile.in =================================================================== diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in --- a/gcc/ada/gcc-interface/Makefile.in (revision 257042) +++ b/gcc/ada/gcc-interface/Makefile.in (revision 259627) @@ -2756,9 +2756,9 @@ # ada/types.h does not conflict with a same-named system header (VxWorks # has a header). -OSCONS_CPP=$(OSCONS_CC) $(GNATLIBCFLAGS) $(GNATLIBCFLAGS_FOR_C) -E -C \ +OSCONS_CPP=$(OSCONS_CC) $(GNATLIBCFLAGS_FOR_C) -E -C \ -DTARGET=\"$(target)\" -iquote $(fsrcpfx)ada $(fsrcpfx)ada/s-oscons-tmplt.c > s-oscons-tmplt.i -OSCONS_EXTRACT=$(OSCONS_CC) -S s-oscons-tmplt.i +OSCONS_EXTRACT=$(OSCONS_CC) $(GNATLIBCFLAGS_FOR_C) -S s-oscons-tmplt.i # Note: if you need to build with a non-GNU compiler, you could adapt the # following definitions (written for VMS DEC-C) Index: gcc/ada/gcc-interface/trans.c =================================================================== diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c --- a/gcc/ada/gcc-interface/trans.c (revision 257042) +++ b/gcc/ada/gcc-interface/trans.c (revision 259627) @@ -4059,6 +4059,8 @@ case N_Identifier: case N_Expanded_Name: gnat_entity = Entity (gnat_node); + if (!Is_Object (gnat_entity)) + break; return Is_Volatile_Full_Access (gnat_entity) || Is_Volatile_Full_Access (Etype (gnat_entity)); @@ -9272,7 +9274,7 @@ ? tree_int_cst_lt (gnu_out_ub, gnu_in_ub) : (FLOAT_TYPE_P (gnu_base_type) ? real_less (&TREE_REAL_CST (gnu_out_ub), - &TREE_REAL_CST (gnu_in_lb)) + &TREE_REAL_CST (gnu_in_ub)) : 1)) gnu_cond = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, gnu_cond, Index: gcc/ada/gcc-interface/misc.c =================================================================== diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c --- a/gcc/ada/gcc-interface/misc.c (revision 257042) +++ b/gcc/ada/gcc-interface/misc.c (revision 259627) @@ -262,6 +262,9 @@ /* No psABI change warnings for Ada. */ warn_psabi = 0; + /* No string overflow warnings for Ada. */ + warn_stringop_overflow = 0; + /* No caret by default for Ada. */ if (!global_options_set.x_flag_diagnostics_show_caret) global_dc->show_caret = false; Index: gcc/gimple-ssa-strength-reduction.c =================================================================== diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c --- a/gcc/gimple-ssa-strength-reduction.c (revision 257042) +++ b/gcc/gimple-ssa-strength-reduction.c (revision 259627) @@ -55,6 +55,7 @@ #include "params.h" #include "tree-ssa-address.h" #include "tree-affine.h" +#include "tree-eh.h" #include "builtins.h" /* Information about a strength reduction candidate. Each statement @@ -1699,6 +1700,9 @@ { gimple *gs = gsi_stmt (gsi); + if (stmt_could_throw_p (gs)) + continue; + if (gimple_vuse (gs) && gimple_assign_single_p (gs)) slsr_process_ref (gs); Index: gcc/tree-eh.c =================================================================== diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c --- a/gcc/tree-eh.c (revision 257042) +++ b/gcc/tree-eh.c (revision 259627) @@ -44,6 +44,7 @@ #include "cfgloop.h" #include "gimple-low.h" #include "asan.h" +#include "gimplify.h" /* In some instances a tree and a gimple need to be stored in a same table, i.e. in hash tables. This is a structure to do this. */ @@ -2438,7 +2439,7 @@ case ROUND_MOD_EXPR: case TRUNC_MOD_EXPR: case RDIV_EXPR: - if (honor_snans || honor_trapv) + if (honor_snans) return true; if (fp_operation) return flag_trapping_math; @@ -2722,7 +2723,92 @@ } } +/* Return non-NULL if there is an integer operation with trapping overflow + we can rewrite into non-trapping. Called via walk_tree from + rewrite_to_non_trapping_overflow. */ +static tree +find_trapping_overflow (tree *tp, int *walk_subtrees, void *data) +{ + if (EXPR_P (*tp) + && !operation_no_trapping_overflow (TREE_TYPE (*tp), TREE_CODE (*tp))) + return *tp; + if (IS_TYPE_OR_DECL_P (*tp) + || (TREE_CODE (*tp) == SAVE_EXPR && data == NULL)) + *walk_subtrees = 0; + return NULL_TREE; +} + +/* Rewrite selected operations into unsigned arithmetics, so that they + don't trap on overflow. */ + +static tree +replace_trapping_overflow (tree *tp, int *walk_subtrees, void *data) +{ + if (find_trapping_overflow (tp, walk_subtrees, data)) + { + tree type = TREE_TYPE (*tp); + tree utype = unsigned_type_for (type); + *walk_subtrees = 0; + int len = TREE_OPERAND_LENGTH (*tp); + for (int i = 0; i < len; ++i) + walk_tree (&TREE_OPERAND (*tp, i), replace_trapping_overflow, + data, (hash_set *) data); + + if (TREE_CODE (*tp) == ABS_EXPR) + { + tree op = TREE_OPERAND (*tp, 0); + op = save_expr (op); + /* save_expr skips simple arithmetics, which is undesirable + here, if it might trap due to flag_trapv. We need to + force a SAVE_EXPR in the COND_EXPR condition, to evaluate + it before the comparison. */ + if (EXPR_P (op) + && TREE_CODE (op) != SAVE_EXPR + && walk_tree (&op, find_trapping_overflow, NULL, NULL)) + { + op = build1_loc (EXPR_LOCATION (op), SAVE_EXPR, type, op); + TREE_SIDE_EFFECTS (op) = 1; + } + /* Change abs (op) to op < 0 ? -op : op and handle the NEGATE_EXPR + like other signed integer trapping operations. */ + tree cond = fold_build2 (LT_EXPR, boolean_type_node, + op, build_int_cst (type, 0)); + tree neg = fold_build1 (NEGATE_EXPR, utype, + fold_convert (utype, op)); + *tp = fold_build3 (COND_EXPR, type, cond, + fold_convert (type, neg), op); + } + else + { + TREE_TYPE (*tp) = utype; + len = TREE_OPERAND_LENGTH (*tp); + for (int i = 0; i < len; ++i) + TREE_OPERAND (*tp, i) + = fold_convert (utype, TREE_OPERAND (*tp, i)); + *tp = fold_convert (type, *tp); + } + } + return NULL_TREE; +} + +/* If any subexpression of EXPR can trap due to -ftrapv, rewrite it + using unsigned arithmetics to avoid traps in it. */ + +tree +rewrite_to_non_trapping_overflow (tree expr) +{ + if (!flag_trapv) + return expr; + hash_set pset; + if (!walk_tree (&expr, find_trapping_overflow, &pset, &pset)) + return expr; + expr = unshare_expr (expr); + hash_set pset2; + walk_tree (&expr, replace_trapping_overflow, &pset2, &pset2); + return expr; +} + /* Helper for stmt_could_throw_p. Return true if STMT (assumed to be a an assignment or a conditional) may throw. */ Index: gcc/fortran/openmp.c =================================================================== diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c --- a/gcc/fortran/openmp.c (revision 257042) +++ b/gcc/fortran/openmp.c (revision 259627) @@ -1312,23 +1312,21 @@ else if (gfc_match_omp_variable_list (" val (", &c->lists[OMP_LIST_LINEAR], false, NULL, &head) - == MATCH_YES) + == MATCH_YES) linear_op = OMP_LINEAR_VAL; else if (gfc_match_omp_variable_list (" uval (", &c->lists[OMP_LIST_LINEAR], false, NULL, &head) - == MATCH_YES) + == MATCH_YES) linear_op = OMP_LINEAR_UVAL; else if (gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_LINEAR], false, &end_colon, &head) - == MATCH_YES) + == MATCH_YES) linear_op = OMP_LINEAR_DEFAULT; else { - gfc_free_omp_namelist (*head); gfc_current_locus = old_loc; - *head = NULL; break; } if (linear_op != OMP_LINEAR_DEFAULT) Index: gcc/fortran/interface.c =================================================================== diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c --- a/gcc/fortran/interface.c (revision 257042) +++ b/gcc/fortran/interface.c (revision 259627) @@ -1263,7 +1263,7 @@ { gfc_array_spec *as = NULL; - if (sym->ts.type == BT_CLASS && CLASS_DATA (sym) && CLASS_DATA (sym)->as) + if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)) as = CLASS_DATA (sym)->as; else as = sym->as; @@ -2791,7 +2791,8 @@ static bool compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, - int ranks_must_agree, int is_elemental, locus *where) + int ranks_must_agree, int is_elemental, + bool in_statement_function, locus *where) { gfc_actual_arglist **new_arg, *a, *actual; gfc_formal_arglist *f; @@ -2820,6 +2821,13 @@ for (a = actual; a; a = a->next, f = f->next) { + if (a->name != NULL && in_statement_function) + { + gfc_error ("Keyword argument %qs at %L is invalid in " + "a statement function", a->name, &a->expr->where); + return false; + } + /* Look for keywords but ignore g77 extensions like %VAL. */ if (a->name != NULL && a->name[0] != '%') { @@ -3143,8 +3151,9 @@ } /* Check intent = OUT/INOUT for definable actual argument. */ - if ((f->sym->attr.intent == INTENT_OUT - || f->sym->attr.intent == INTENT_INOUT)) + if (!in_statement_function + && (f->sym->attr.intent == INTENT_OUT + || f->sym->attr.intent == INTENT_INOUT)) { const char* context = (where ? _("actual argument to INTENT = OUT/INOUT") @@ -3249,7 +3258,8 @@ "at %L", where); return false; } - if (!f->sym->attr.optional) + if (!f->sym->attr.optional + || (in_statement_function && f->sym->attr.optional)) { if (where) gfc_error ("Missing actual argument for argument %qs at %L", @@ -3535,6 +3545,7 @@ bool gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where) { + gfc_actual_arglist *a; gfc_formal_arglist *dummy_args; /* Warn about calls with an implicit interface. Special case @@ -3561,8 +3572,6 @@ if (sym->attr.if_source == IFSRC_UNKNOWN) { - gfc_actual_arglist *a; - if (sym->attr.pointer) { gfc_error ("The pointer object %qs at %L must have an explicit " @@ -3654,9 +3663,12 @@ dummy_args = gfc_sym_get_dummy_args (sym); - if (!compare_actual_formal (ap, dummy_args, 0, sym->attr.elemental, where)) + /* For a statement function, check that types and type parameters of actual + arguments and dummy arguments match. */ + if (!compare_actual_formal (ap, dummy_args, 0, sym->attr.elemental, + sym->attr.proc == PROC_ST_FUNCTION, where)) return false; - + if (!check_intents (dummy_args, *ap)) return false; @@ -3703,7 +3715,7 @@ } if (!compare_actual_formal (ap, comp->ts.interface->formal, 0, - comp->attr.elemental, where)) + comp->attr.elemental, false, where)) return; check_intents (comp->ts.interface->formal, *ap); @@ -3728,7 +3740,7 @@ dummy_args = gfc_sym_get_dummy_args (sym); r = !sym->attr.elemental; - if (compare_actual_formal (args, dummy_args, r, !r, NULL)) + if (compare_actual_formal (args, dummy_args, r, !r, false, NULL)) { check_intents (dummy_args, *args); if (warn_aliasing) Index: gcc/fortran/trans-expr.c =================================================================== diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c --- a/gcc/fortran/trans-expr.c (revision 257042) +++ b/gcc/fortran/trans-expr.c (revision 259627) @@ -960,6 +960,7 @@ } if ((ref == NULL || class_ref == ref) + && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE) && (!class_ts.u.derived->components->as || class_ts.u.derived->components->as->rank != -1)) return; @@ -1030,8 +1031,11 @@ First we have to find the corresponding class reference. */ tmp = NULL_TREE; - if (class_ref == NULL - && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS) + if (gfc_is_class_array_function (e) + && parmse->class_vptr != NULL_TREE) + tmp = parmse->class_vptr; + else if (class_ref == NULL + && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS) { tmp = e->symtree->n.sym->backend_decl; @@ -1063,7 +1067,11 @@ if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE) tmp = build_fold_indirect_ref_loc (input_location, tmp); - vptr = gfc_class_vptr_get (tmp); + if (!(gfc_is_class_array_function (e) && parmse->class_vptr)) + vptr = gfc_class_vptr_get (tmp); + else + vptr = tmp; + gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), vptr)); @@ -4307,6 +4315,8 @@ if (expr->value.function.esym == NULL && expr->value.function.isym != NULL + && expr->value.function.actual + && expr->value.function.actual->expr && expr->value.function.actual->expr->symtree && gfc_map_intrinsic_function (expr, mapping)) break; @@ -4435,7 +4445,7 @@ /* Reset the offset for the function call since the loop is zero based on the data pointer. Note that the temp comes first in the loop chain since it is added second. */ - if (gfc_is_alloc_class_array_function (expr)) + if (gfc_is_class_array_function (expr)) { tmp = loop.ss->loop_chain->info->data.array.descriptor; gfc_conv_descriptor_offset_set (&loop.pre, tmp, @@ -4484,7 +4494,7 @@ dimen = rse.ss->dimen; /* Skip the write-out loop for this case. */ - if (gfc_is_alloc_class_array_function (expr)) + if (gfc_is_class_array_function (expr)) goto class_array_fcn; /* Calculate the bounds of the scalarization. */ @@ -4778,7 +4788,7 @@ gcc_assert ((!comp && gfc_return_by_reference (sym) && sym->result->attr.dimension) || (comp && comp->attr.dimension) - || gfc_is_alloc_class_array_function (expr)); + || gfc_is_class_array_function (expr)); gcc_assert (se->loop != NULL); /* Access the previously obtained result. */ gfc_conv_tmp_array_ref (se); @@ -5461,7 +5471,7 @@ fsym ? fsym->attr.intent : INTENT_INOUT, fsym && fsym->attr.pointer); - else if (gfc_is_alloc_class_array_function (e) + else if (gfc_is_class_array_function (e) && fsym && fsym->ts.type == BT_DERIVED) /* See previous comment. For function actual argument, the write out is not needed so the intent is set as @@ -6302,7 +6312,7 @@ call the finalization function of the temporary. Note that the nullification of allocatable components needed by the result is done in gfc_trans_assignment_1. */ - if (expr && ((gfc_is_alloc_class_array_function (expr) + if (expr && ((gfc_is_class_array_function (expr) && se->ss && se->ss->loop) || gfc_is_alloc_class_scalar_function (expr)) && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr)) @@ -6313,6 +6323,7 @@ int n; if (se->ss && se->ss->loop) { + gfc_add_block_to_block (&se->ss->loop->pre, &se->pre); se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre); tmp = gfc_class_data_get (se->expr); info->descriptor = tmp; @@ -6335,6 +6346,11 @@ CLASS_DATA (expr->value.function.esym->result)->attr); } + if ((gfc_is_class_array_function (expr) + || gfc_is_alloc_class_scalar_function (expr)) + && CLASS_DATA (expr->value.function.esym->result)->attr.pointer) + goto no_finalization; + final_fndecl = gfc_class_vtab_final_get (se->expr); is_final = fold_build2_loc (input_location, NE_EXPR, logical_type_node, @@ -6365,6 +6381,8 @@ tmp = gfc_call_free (tmp); gfc_add_expr_to_block (&se->post, tmp); } + +no_finalization: expr->must_finalize = 0; } @@ -8835,7 +8853,7 @@ gfc_add_expr_to_block (&block, tmp); } } - else if (gfc_bt_struct (ts.type) || ts.type == BT_CLASS) + else if (gfc_bt_struct (ts.type) || ts.type == BT_CLASS || ts.type == BT_COMPLEX) { gfc_add_block_to_block (&block, &lse->pre); gfc_add_block_to_block (&block, &rse->pre); @@ -8871,7 +8889,7 @@ gfc_symbol *sym = expr1->symtree->n.sym; /* Play it safe with class functions assigned to a derived type. */ - if (gfc_is_alloc_class_array_function (expr2) + if (gfc_is_class_array_function (expr2) && expr1->ts.type == BT_DERIVED) return true; @@ -9878,7 +9896,7 @@ rss = NULL; if ((expr1->ts.type == BT_DERIVED) - && (gfc_is_alloc_class_array_function (expr2) + && (gfc_is_class_array_function (expr2) || gfc_is_alloc_class_scalar_function (expr2))) expr2->must_finalize = 1; @@ -10085,7 +10103,7 @@ a scalar to array assignment, this is done in gfc_trans_scalar_assign as part of the deep copy. */ if (!scalar_to_array && expr1->ts.type == BT_DERIVED - && (gfc_is_alloc_class_array_function (expr2) + && (gfc_is_class_array_function (expr2) || gfc_is_alloc_class_scalar_function (expr2))) { tmp = rse.expr; Index: gcc/fortran/trans-array.c =================================================================== diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c --- a/gcc/fortran/trans-array.c (revision 257042) +++ b/gcc/fortran/trans-array.c (revision 259627) @@ -2652,6 +2652,8 @@ gfc_init_se (&se, NULL); se.loop = loop; se.ss = ss; + if (gfc_is_class_array_function (expr)) + expr->must_finalize = 1; gfc_conv_expr (&se, expr); gfc_add_block_to_block (&outer_loop->pre, &se.pre); gfc_add_block_to_block (&outer_loop->post, &se.post); @@ -3102,7 +3104,7 @@ { if (expr == NULL || (expr->ts.type != BT_CLASS - && !gfc_is_alloc_class_array_function (expr) + && !gfc_is_class_array_function (expr) && !gfc_is_class_array_ref (expr, NULL))) return false; @@ -3132,12 +3134,12 @@ } if (class_ref == NULL && expr && expr->symtree->n.sym->attr.function - && expr->symtree->n.sym == expr->symtree->n.sym->result) + && expr->symtree->n.sym == expr->symtree->n.sym->result + && expr->symtree->n.sym->backend_decl == current_function_decl) { - gcc_assert (expr->symtree->n.sym->backend_decl == current_function_decl); decl = gfc_get_fake_result_decl (expr->symtree->n.sym, 0); } - else if (expr && gfc_is_alloc_class_array_function (expr)) + else if (expr && gfc_is_class_array_function (expr)) { size = NULL_TREE; decl = NULL_TREE; @@ -3160,6 +3162,8 @@ if (decl == NULL_TREE) return false; + + se->class_vptr = gfc_evaluate_now (gfc_class_vptr_get (decl), &se->pre); } else if (class_ref == NULL) { @@ -7125,7 +7129,11 @@ else { /* Otherwise make a new one. */ - parmtype = gfc_get_element_type (TREE_TYPE (desc)); + if (expr->ts.type == BT_CHARACTER && expr->ts.deferred) + parmtype = gfc_typenode_for_spec (&expr->ts); + else + parmtype = gfc_get_element_type (TREE_TYPE (desc)); + parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, codim, loop.from, loop.to, 0, GFC_ARRAY_UNKNOWN, false); @@ -10007,7 +10015,7 @@ if (!sym) sym = expr->symtree->n.sym; - if (gfc_is_alloc_class_array_function (expr)) + if (gfc_is_class_array_function (expr)) return gfc_get_array_ss (ss, expr, CLASS_DATA (expr->value.function.esym->result)->as->rank, GFC_SS_FUNCTION); Index: gcc/fortran/decl.c =================================================================== diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c --- a/gcc/fortran/decl.c (revision 257042) +++ b/gcc/fortran/decl.c (revision 259627) @@ -573,6 +573,20 @@ if (m != MATCH_YES) goto cleanup; + if (new_data->var->iter.var + && new_data->var->iter.var->ts.type == BT_INTEGER + && new_data->var->iter.var->symtree->n.sym->attr.implied_index == 1 + && new_data->var->list + && new_data->var->list->expr + && new_data->var->list->expr->ts.type == BT_CHARACTER + && new_data->var->list->expr->ref + && new_data->var->list->expr->ref->type == REF_SUBSTRING) + { + gfc_error ("Invalid substring in data-implied-do at %L in DATA " + "statement", &new_data->var->list->expr->where); + goto cleanup; + } + m = top_val_list (new_data); if (m != MATCH_YES) goto cleanup; @@ -1115,14 +1129,12 @@ if (sym->attr.proc == PROC_ST_FUNCTION) return rc; - if (sym->attr.module_procedure - && sym->attr.if_source == IFSRC_IFBODY) + if (sym->attr.module_procedure && sym->attr.if_source == IFSRC_IFBODY) { /* Create a partially populated interface symbol to carry the characteristics of the procedure and the result. */ sym->tlink = gfc_new_symbol (name, sym->ns); - gfc_add_type (sym->tlink, &(sym->ts), - &gfc_current_locus); + gfc_add_type (sym->tlink, &(sym->ts), &gfc_current_locus); gfc_copy_attr (&sym->tlink->attr, &sym->attr, NULL); if (sym->attr.dimension) sym->tlink->as = gfc_copy_array_spec (sym->as); @@ -1152,11 +1164,22 @@ accessible names. */ if (sym->attr.flavor != 0 && sym->attr.proc != 0 - && (sym->attr.subroutine || sym->attr.function) + && (sym->attr.subroutine || sym->attr.function || sym->attr.entry) && sym->attr.if_source != IFSRC_UNKNOWN) gfc_error_now ("Procedure %qs at %C is already defined at %L", name, &sym->declared_at); + if (sym->attr.flavor != 0 + && sym->attr.entry && sym->attr.if_source != IFSRC_UNKNOWN) + gfc_error_now ("Procedure %qs at %C is already defined at %L", + name, &sym->declared_at); + + if (sym->attr.external && sym->attr.procedure + && gfc_current_state () == COMP_CONTAINS) + gfc_error_now ("Contained procedure %qs at %C clashes with " + "procedure defined at %L", + name, &sym->declared_at); + /* Trap a procedure with a name the same as interface in the encompassing scope. */ if (sym->attr.generic != 0 @@ -1176,7 +1199,16 @@ && sym->attr.access == 0 && !module_fcn_entry) gfc_error_now ("Procedure %qs at %C has an explicit interface " - "and must not have attributes declared at %L", + "from a previous declaration", name); + } + + if (sym && !sym->gfc_new + && sym->attr.flavor != FL_UNKNOWN + && sym->attr.referenced == 0 && sym->attr.subroutine == 1 + && gfc_state_stack->state == COMP_CONTAINS + && gfc_state_stack->previous->state == COMP_SUBROUTINE) + { + gfc_error_now ("Procedure %qs at %C is already defined at %L", name, &sym->declared_at); } @@ -1201,10 +1233,10 @@ /* See if the procedure should be a module procedure. */ if (((sym->ns->proc_name != NULL - && sym->ns->proc_name->attr.flavor == FL_MODULE - && sym->attr.proc != PROC_MODULE) - || (module_fcn_entry && sym->attr.proc != PROC_MODULE)) - && !gfc_add_procedure (&sym->attr, PROC_MODULE, sym->name, NULL)) + && sym->ns->proc_name->attr.flavor == FL_MODULE + && sym->attr.proc != PROC_MODULE) + || (module_fcn_entry && sym->attr.proc != PROC_MODULE)) + && !gfc_add_procedure (&sym->attr, PROC_MODULE, sym->name, NULL)) rc = 2; return rc; @@ -2183,7 +2215,10 @@ /* At this point, we know for sure if the symbol is PARAMETER and can thus determine (and check) whether it can be implied-shape. If it was parsed as assumed-size, change it because PARAMETERs can not - be assumed-size. */ + be assumed-size. + + An explicit-shape-array cannot appear under several conditions. + That check is done here as well. */ if (as) { if (as->type == AS_IMPLIED_SHAPE && current_attr.flavor != FL_PARAMETER) @@ -2205,6 +2240,50 @@ m = MATCH_ERROR; goto cleanup; } + + /* F2018:C830 (R816) An explicit-shape-spec whose bounds are not + constant expressions shall appear only in a subprogram, derived + type definition, BLOCK construct, or interface body. */ + if (as->type == AS_EXPLICIT + && gfc_current_state () != COMP_BLOCK + && gfc_current_state () != COMP_DERIVED + && gfc_current_state () != COMP_FUNCTION + && gfc_current_state () != COMP_INTERFACE + && gfc_current_state () != COMP_SUBROUTINE) + { + gfc_expr *e; + bool not_constant = false; + + for (int i = 0; i < as->rank; i++) + { + e = gfc_copy_expr (as->lower[i]); + gfc_resolve_expr (e); + gfc_simplify_expr (e, 0); + if (e && (e->expr_type != EXPR_CONSTANT)) + { + not_constant = true; + break; + } + gfc_free_expr (e); + + e = gfc_copy_expr (as->upper[i]); + gfc_resolve_expr (e); + gfc_simplify_expr (e, 0); + if (e && (e->expr_type != EXPR_CONSTANT)) + { + not_constant = true; + break; + } + gfc_free_expr (e); + } + + if (not_constant) + { + gfc_error ("Explicit shaped array with nonconstant bounds at %C"); + m = MATCH_ERROR; + goto cleanup; + } + } } char_len = NULL; @@ -2918,7 +2997,28 @@ if (seen_length == 0) cl->length = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1); else - cl->length = len; + { + /* If gfortran ends up here, then the len may be reducible to a + constant. Try to do that here. If it does not reduce, simply + assign len to the charlen. */ + if (len && len->expr_type != EXPR_CONSTANT) + { + gfc_expr *e; + e = gfc_copy_expr (len); + gfc_reduce_init_expr (e); + if (e->expr_type == EXPR_CONSTANT) + { + gfc_replace_expr (len, e); + if (mpz_cmp_si (len->value.integer, 0) < 0) + mpz_set_ui (len->value.integer, 0); + } + else + gfc_free_expr (e); + cl->length = len; + } + else + cl->length = len; + } ts->u.cl = cl; ts->kind = kind == 0 ? gfc_default_character_kind : kind; Index: gcc/fortran/trans-openmp.c =================================================================== diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c --- a/gcc/fortran/trans-openmp.c (revision 257042) +++ b/gcc/fortran/trans-openmp.c (revision 259627) @@ -1949,9 +1949,32 @@ } else { - tree type = gfc_typenode_for_spec (&n->sym->ts); - OMP_CLAUSE_LINEAR_STEP (node) - = fold_convert (type, last_step); + if (kind == OMP_CLAUSE_LINEAR_REF) + { + tree type; + if (n->sym->attr.flavor == FL_PROCEDURE) + { + type = gfc_get_function_type (n->sym); + type = build_pointer_type (type); + } + else + type = gfc_sym_type (n->sym); + if (POINTER_TYPE_P (type)) + type = TREE_TYPE (type); + /* Otherwise to be determined what exactly + should be done. */ + tree t = fold_convert (sizetype, last_step); + t = size_binop (MULT_EXPR, t, + TYPE_SIZE_UNIT (type)); + OMP_CLAUSE_LINEAR_STEP (node) = t; + } + else + { + tree type + = gfc_typenode_for_spec (&n->sym->ts); + OMP_CLAUSE_LINEAR_STEP (node) + = fold_convert (type, last_step); + } } if (n->sym->attr.dimension || n->sym->attr.allocatable) OMP_CLAUSE_LINEAR_ARRAY (node) = 1; Index: gcc/fortran/gfortran.h =================================================================== diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h --- a/gcc/fortran/gfortran.h (revision 257042) +++ b/gcc/fortran/gfortran.h (revision 259627) @@ -863,7 +863,7 @@ unsigned alloc_comp:1, pointer_comp:1, proc_pointer_comp:1, private_comp:1, zero_comp:1, coarray_comp:1, lock_comp:1, event_comp:1, defined_assign_comp:1, unlimited_polymorphic:1, - has_dtio_procs:1; + has_dtio_procs:1, caf_token:1; /* This is a temporary selector for SELECT TYPE or an associate variable for SELECT_TYPE or ASSOCIATE. */ @@ -2856,6 +2856,8 @@ extern int gfc_numeric_storage_size; extern int gfc_character_storage_size; +#define gfc_integer_4_kind 4 + /* symbol.c */ void gfc_clear_new_implicit (void); bool gfc_add_new_implicit_range (int, int); @@ -3145,7 +3147,7 @@ gfc_component * gfc_get_proc_ptr_comp (gfc_expr *); bool gfc_is_proc_ptr_comp (gfc_expr *); bool gfc_is_alloc_class_scalar_function (gfc_expr *); -bool gfc_is_alloc_class_array_function (gfc_expr *); +bool gfc_is_class_array_function (gfc_expr *); bool gfc_ref_this_image (gfc_ref *ref); bool gfc_is_coindexed (gfc_expr *); Index: gcc/fortran/ChangeLog =================================================================== diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog --- a/gcc/fortran/ChangeLog (revision 257042) +++ b/gcc/fortran/ChangeLog (revision 259627) @@ -1,3 +1,253 @@ +2018-04-24 Steven G. Kargl + + PR fortran/85520 + * decl.c (gfc_match_char_spec): Check for negative length and set to 0. + +2018-03-28 Thomas Koenig + + PR fortran/85084 + Backport from trunk. + * frontend-passes.c (gfc_run_passes): Do not run front-end + optimizations if a previous error occurred. + +2018-03-20 Steven G. Kargl + + PR fortran/85001 + * interface.c (symbol_rank): Remove bogus null pointer check that + crept in when translating a ternary operator into an if-else + constructor. + +2018-03-19 Thomas Koenig + + PR fortran/84931 + Backport from trunk + * simplify.c (gfc_convert_constant): Correctly handle iterators + for type conversion. + +2018-03-19 Steven G. Kargl + + PR fortran/77414 + * decl.c (get_proc_name): Check for a subroutine re-defined in + the contain portion of a subroutine. Change language of existing + error message to better describe the issue. While here fix whitespace + issues. + +2018-03-19 Steven G. Kargl + + PR fortran/65453 + * decl.c (get_proc_name): Catch clash between a procedure statement + and a contained subprogram + +2018-03-15 Steven G. Kargl + + PR fortran/78741 + * decl.c (get_proc_name): Check for clash of entry name with + subroutine name. + +2018-03-12 Steven G. Kargl + + PR fortran/83939 + * resolve.c (resolve_fl_procedure): Enforce F2018:C15100. + +2018-03-10 Steven G. Kargl + + PR fortran/84734 + * arith.c (check_result, eval_intrinsic): If result overflows, pass + the expression up the chain instead of a NULL pointer. + +2018-03-08 Steven G. Kargl + + PR fortran/64124 + PR fortran/70409 + * decl.c (gfc_match_char_spec): Try to reduce a charlen to a constant. + +2018-03-06 Steven G. Kargl + + PR fortran/56667 + * primary.c (match_sym_complex_part): Give the matcher for an implied + do-loop a chance to run. + +2018-03-04 Paul Thomas + + PR fortran/83076 + * resolve.c (resolve_fl_derived0): Add caf_token fields for + allocatable and pointer scalars, when -fcoarray selected. + * trans-types.c (gfc_copy_dt_decls_ifequal): Copy the token + field as well as the backend_decl. + (gfc_get_derived_type): Flag GFC_FCOARRAY_LIB for module + derived types that are not vtypes. Components with caf_token + attribute are pvoid types. For a component requiring it, find + the caf_token field and have the component token field point to + its backend_decl. + +2018-03-03 Harald Anlauf + + PR fortran/71085 + * trans-expr.c (gfc_apply_interface_mapping_to_expr): Do not + dereference NULL pointer. + +2018-03-03 Steven G. Kargl + + PR fortran/51434 + * simplify.c (gfc_simplify_transfer): Resolve mold. + +2018-03-03 Paul Thomas + + PR fortran/80965 + * resolve.c (build_loc_call): Change symtree name from 'loc' to + '_loc'. + +2018-03-03 Paul Thomas + + Backported from trunk. + PR fortran/78990 + * expr.c (gfc_is_class_array_function): Renamed from + 'gfc_is_alloc_class_array_function' and modified to return true + for pointers as well as allocatable results. + * gfortran.h : Change of name for prototype of above function. + * trans-array.c (gfc_add_loop_ss_code): Force finalization of + class array results. + (build_class_array_ref): Change assertion into a condition. + (build_class_array_ref): Set the se class_vptr for class array + function results. + (gfc_walk_function_expr): Reference gfc_is_class_array_function + as above. + * trans-decl.c (get_proc_result): Move it up before + gfc_trans_deferred_vars. + (gfc_trans_deferred_vars): Nullify explicit return class arrays + on entry. + * trans-expr.c (gfc_conv_class_to_class): Allow conversion of + class array functions that have an se class_vptr and use it + for the result vptr. + (gfc_conv_subref_array_arg): Rename reference to the above + function. + (gfc_conv_procedure_call): Ditto. Add the se pre block to the + loop pre block before the function is evaluated. Do not + finalize class pointer results. + (arrayfunc_assign_needs_temporary, gfc_trans_assignment_1) More + renamed references. + * trans-intrinsic.c (gfc_conv_intrinsic_size): Ditto. + +2018-03-03 Jakub Jelinek + + Backported from mainline + 2018-02-16 Jakub Jelinek + + PR fortran/84418 + * trans-openmp.c (gfc_trans_omp_clauses): For OMP_CLAUSE_LINEAR_REF + kind set OMP_CLAUSE_LINEAR_STEP to TYPE_SIZE_UNIT times last_step. + + 2018-01-31 Jakub Jelinek + + PR fortran/84116 + * openmp.c (gfc_match_omp_clauses): If all the linear + gfc_match_omp_variable_list calls failed, don't gfc_free_omp_namelist + nor set *head = NULL. Formatting fixes. + +2018-02-25 Steven G. Kargl + + ChangeLog for r257972 + PR fortran/83633 + * decl.c (variable_decl): Check that an explicit-shape-array with + nonconstant bounds is allowed. + +2018-02-25 Thomas Koenig + + PR fortran/78238 + Backport from trunk + * gfortran.h (gfc_integer_4_kind): Define. + * resolve.c (resolve_select_type): Make sure that the + kind of c->high is gfc_integer_4_kind. + +2018-02-24 Steven G. Kargl + + PR fortran/30792 + * decl.c (gfc_match_data): Check for invalid substring in + data-implied-do + +2018-02-23 Steven G. Kargl + + PR fortran/84511 + * trans-io.c (transfer_expr): Deal with C_LOC in transfer statement. + +2018-02-23 Steven G. Kargl + + PR fortran/84346 + * interface.c (compare_actual_formal): Issue error if keyword is + used in a statement function. + +2018-02-23 Jerry DeLisle + + Backport from trunk + PR fortran/84506 + * trans-io.c (set_parameter_value_inquire): Adjust range check of + negative unit values for kind=8 units to the kind=4 negative limit. + +2018-02-22 Thomas Koenig + + PR fortran/81116 + PR fortran/84495 + * gfortran.dg/realloc_on_assignment_29.f90: New test. + +2018-02-19 Jerry DeLisle + + Backport from trunk + PR fortran/82007 + * resolve.c (resolve_transfer): Delete code looking for 'DT' + format specifiers in format strings. Set formatted to true if a + format string or format label is present. + * trans-io.c (get_dtio_proc): Likewise. (transfer_expr): Fix + whitespace. + +2018-02-17 Thomas Koenig + + Backport from trunk + PR fortran/84270 + * frontend-passes (scalarized_expr): If the expression + is an assumed size array, leave in the last reference + and pass AR_SECTION instead of AR_FULL to gfc_resolve + in order to avoid an error. + +2018-02-13 Alastair McKinstry + Janne Blomqvist + + * module.c (dump_module): Use lbasename to ensure that module + files are reproducible. + +2018-02-12 Thomas Koenig + + PR fortran/68560 + * trans-intrinsic.c (gfc_conv_intrinsic_shape): New function. + (gfc_conv_intrinsic_function): Call it. + +2018-02-12 Francois-Xavier Coudert + + PR fortran/35299 + ChangeLog for r257566 + * resolve.c (resolve_formal_arglist): Update error message. + +2018-02-12 Steven G. Kargl + + PR fortran/54223 + PR fortran/84276 + * interface.c (compare_actual_formal): Add in_statement_function + bool parameter. Skip check of INTENT attribute for statement + functions. Arguments to a statement function cannot be optional, + issue error for missing argument. + (gfc_procedure_use, gfc_ppc_use, gfc_arglist_matches_symbol): Use + in_statement_function. + +2018-02-07 Steven G. Kargl + + PR fortran/82994 + * match.c (gfc_match_deallocate): Check for NULL pointer. + +2018-02-07 Steven G. Kargl + + PR fortran/82049 + * match.c (gfc_match_type_spec): If the charlen is non-NULL, then + try to resolve it. While here return early if possible. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: gcc/fortran/expr.c =================================================================== diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c --- a/gcc/fortran/expr.c (revision 257042) +++ b/gcc/fortran/expr.c (revision 259627) @@ -4762,7 +4762,7 @@ /* Determine if an expression is a function with an allocatable class array result. */ bool -gfc_is_alloc_class_array_function (gfc_expr *expr) +gfc_is_class_array_function (gfc_expr *expr) { if (expr->expr_type == EXPR_FUNCTION && expr->value.function.esym @@ -4769,7 +4769,8 @@ && expr->value.function.esym->result && expr->value.function.esym->result->ts.type == BT_CLASS && CLASS_DATA (expr->value.function.esym->result)->attr.dimension - && CLASS_DATA (expr->value.function.esym->result)->attr.allocatable) + && (CLASS_DATA (expr->value.function.esym->result)->attr.allocatable + || CLASS_DATA (expr->value.function.esym->result)->attr.pointer)) return true; return false; Index: gcc/fortran/module.c =================================================================== diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c --- a/gcc/fortran/module.c (revision 257042) +++ b/gcc/fortran/module.c (revision 259627) @@ -6063,8 +6063,10 @@ gfc_fatal_error ("Can't open module file %qs for writing at %C: %s", filename_tmp, xstrerror (errno)); + /* Use lbasename to ensure module files are reproducible regardless + of the build path (see the reproducible builds project). */ gzprintf (module_fp, "GFORTRAN module version '%s' created from %s\n", - MOD_VERSION, gfc_source_file); + MOD_VERSION, lbasename (gfc_source_file)); /* Write the module itself. */ iomode = IO_OUTPUT; Index: gcc/fortran/trans-types.c =================================================================== diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c --- a/gcc/fortran/trans-types.c (revision 257042) +++ b/gcc/fortran/trans-types.c (revision 259627) @@ -1804,7 +1804,7 @@ TREE_NO_WARNING (decl) = 1; } - if (flag_coarray == GFC_FCOARRAY_LIB && codimen) + if (flag_coarray == GFC_FCOARRAY_LIB) { decl = gfc_add_field_to_struct_1 (fat_type, get_identifier ("token"), @@ -2334,6 +2334,7 @@ for (; to_cm; to_cm = to_cm->next, from_cm = from_cm->next) { to_cm->backend_decl = from_cm->backend_decl; + to_cm->caf_token = from_cm->caf_token; if (from_cm->ts.type == BT_UNION) gfc_get_union_type (to_cm->ts.u.derived); else if (from_cm->ts.type == BT_DERIVED @@ -2444,7 +2445,11 @@ gfc_dt_list *dt; gfc_namespace *ns; tree tmp; + bool coarray_flag; + coarray_flag = flag_coarray == GFC_FCOARRAY_LIB + && derived->module && !derived->attr.vtype; + if (derived->attr.unlimited_polymorphic || (flag_coarray == GFC_FCOARRAY_LIB && derived->from_intmod == INTMOD_ISO_FORTRAN_ENV @@ -2636,7 +2641,9 @@ field_type = build_pointer_type (tmp); } else if (c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS) - field_type = c->ts.u.derived->backend_decl; + field_type = c->ts.u.derived->backend_decl; + else if (c->attr.caf_token) + field_type = pvoid_type_node; else { if (c->ts.type == BT_CHARACTER && !c->ts.deferred) @@ -2715,19 +2722,6 @@ gcc_assert (field); if (!c->backend_decl) c->backend_decl = field; - - /* Do not add a caf_token field for classes' data components. */ - if (codimen && !c->attr.dimension && !c->attr.codimension - && (c->attr.allocatable || c->attr.pointer) - && c->caf_token == NULL_TREE && strcmp ("_data", c->name) != 0) - { - char caf_name[GFC_MAX_SYMBOL_LEN]; - snprintf (caf_name, GFC_MAX_SYMBOL_LEN, "_caf_%s", c->name); - c->caf_token = gfc_add_field_to_struct (typenode, - get_identifier (caf_name), - pvoid_type_node, &chain); - TREE_NO_WARNING (c->caf_token) = 1; - } } /* Now lay out the derived type, including the fields. */ @@ -2753,6 +2747,24 @@ copy_derived_types: + for (c = derived->components; c; c = c->next) + { + /* Do not add a caf_token field for class container components. */ + if ((codimen || coarray_flag) + && !c->attr.dimension && !c->attr.codimension + && (c->attr.allocatable || c->attr.pointer) + && !derived->attr.is_class) + { + char caf_name[GFC_MAX_SYMBOL_LEN]; + gfc_component *token; + snprintf (caf_name, GFC_MAX_SYMBOL_LEN, "_caf_%s", c->name); + token = gfc_find_component (derived, caf_name, true, true, NULL); + gcc_assert (token); + c->caf_token = token->backend_decl; + TREE_NO_WARNING (c->caf_token) = 1; + } + } + for (dt = gfc_derived_types; dt; dt = dt->next) gfc_copy_dt_decls_ifequal (derived, dt->derived, false); Index: gcc/fortran/frontend-passes.c =================================================================== diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c --- a/gcc/fortran/frontend-passes.c (revision 257042) +++ b/gcc/fortran/frontend-passes.c (revision 259627) @@ -135,6 +135,10 @@ check_locus (ns); #endif + gfc_get_errors (&w, &e); + if (e > 0) + return; + if (flag_frontend_optimize) { optimize_namespace (ns); @@ -145,10 +149,6 @@ expr_array.release (); } - gfc_get_errors (&w, &e); - if (e > 0) - return; - if (flag_realloc_lhs) realloc_strings (ns); } @@ -232,21 +232,25 @@ return 0; expr2 = gfc_discard_nops (co->expr2); - if (expr2->expr_type != EXPR_VARIABLE) - return 0; - found_substr = false; - for (ref = expr2->ref; ref; ref = ref->next) + if (expr2->expr_type == EXPR_VARIABLE) { - if (ref->type == REF_SUBSTRING) + found_substr = false; + for (ref = expr2->ref; ref; ref = ref->next) { - found_substr = true; - break; + if (ref->type == REF_SUBSTRING) + { + found_substr = true; + break; + } } + if (!found_substr) + return 0; } - if (!found_substr) + else if (expr2->expr_type != EXPR_OP + || expr2->value.op.op != INTRINSIC_CONCAT) return 0; - + if (!gfc_check_dependency (expr1, expr2, true)) return 0; @@ -619,7 +623,8 @@ /* Return length of char symbol, if constant. */ - if (e->symtree->n.sym->ts.u.cl && e->symtree->n.sym->ts.u.cl->length + if (e->symtree && e->symtree->n.sym->ts.u.cl + && e->symtree->n.sym->ts.u.cl->length && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT) return gfc_copy_expr (e->symtree->n.sym->ts.u.cl->length); @@ -2750,11 +2755,27 @@ is the lbound of a full ref. */ int j; gfc_array_ref *ar; + int to; ar = &ref->u.ar; - ar->type = AR_FULL; - for (j = 0; j < ar->dimen; j++) + + /* For assumed size, we need to keep around the final + reference in order not to get an error on resolution + below, and we cannot use AR_FULL. */ + + if (ar->as->type == AS_ASSUMED_SIZE) { + ar->type = AR_SECTION; + to = ar->dimen - 1; + } + else + { + to = ar->dimen; + ar->type = AR_FULL; + } + + for (j = 0; j < to; j++) + { gfc_free_expr (ar->start[j]); ar->start[j] = NULL; gfc_free_expr (ar->end[j]); Index: gcc/fortran/resolve.c =================================================================== diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c --- a/gcc/fortran/resolve.c (revision 257042) +++ b/gcc/fortran/resolve.c (revision 259627) @@ -512,8 +512,11 @@ { if (sym->as != NULL) { - gfc_error ("Argument %qs of statement function at %L must " - "be scalar", sym->name, &sym->declared_at); + /* F03:C1263 (R1238) The function-name and each dummy-arg-name + shall be specified, explicitly or implicitly, to be scalar. */ + gfc_error ("Argument '%s' of statement function '%s' at %L " + "must be scalar", sym->name, proc->name, + &proc->declared_at); continue; } @@ -8495,7 +8498,7 @@ gfc_expr *loc_call; loc_call = gfc_get_expr (); loc_call->expr_type = EXPR_FUNCTION; - gfc_get_sym_tree ("loc", gfc_current_ns, &loc_call->symtree, false); + gfc_get_sym_tree ("_loc", gfc_current_ns, &loc_call->symtree, false); loc_call->symtree->n.sym->attr.flavor = FL_PROCEDURE; loc_call->symtree->n.sym->attr.intrinsic = 1; loc_call->symtree->n.sym->result = loc_call->symtree->n.sym; @@ -8548,6 +8551,9 @@ code->expr1->symtree->n.sym->ts = code->expr2->ts; selector_type = CLASS_DATA (code->expr2)->ts.u.derived; + if (code->expr2->rank && CLASS_DATA (code->expr1)->as) + CLASS_DATA (code->expr1)->as->rank = code->expr2->rank; + /* F2008: C803 The selector expression must not be coindexed. */ if (gfc_is_coindexed (code->expr2)) { @@ -8742,7 +8748,7 @@ { vtab = gfc_find_derived_vtab (c->ts.u.derived); gcc_assert (vtab); - c->high = gfc_get_int_expr (gfc_default_integer_kind, NULL, + c->high = gfc_get_int_expr (gfc_integer_4_kind, NULL, c->ts.u.derived->hash_value); } else @@ -8751,6 +8757,13 @@ gcc_assert (vtab && CLASS_DATA (vtab)->initializer); e = CLASS_DATA (vtab)->initializer; c->high = gfc_copy_expr (e); + if (c->high->ts.kind != gfc_integer_4_kind) + { + gfc_typespec ts; + ts.kind = gfc_integer_4_kind; + ts.type = BT_INTEGER; + gfc_convert_type_warn (c->high, &ts, 2, 0); + } } e = gfc_lval_expr_from_sym (vtab); @@ -8996,19 +9009,9 @@ else derived = ts->u.derived->components->ts.u.derived; - if (dt->format_expr) - { - char *fmt; - fmt = gfc_widechar_to_char (dt->format_expr->value.character.string, - -1); - if (strtok (fmt, "DT") != NULL) - formatted = true; - } - else if (dt->format_label == &format_asterisk) - { - /* List directed io must call the formatted DTIO procedure. */ - formatted = true; - } + /* Determine when to use the formatted DTIO procedure. */ + if (dt && (dt->format_expr || dt->format_label)) + formatted = true; write = dt->dt_io_kind->value.iokind == M_WRITE || dt->dt_io_kind->value.iokind == M_PRINT; @@ -12225,6 +12228,19 @@ } } + /* F2018, C15100: "The result of an elemental function shall be scalar, + and shall not have the POINTER or ALLOCATABLE attribute." The scalar + pointer is tested and caught elsewhere. */ + if (sym->attr.elemental && sym->result + && (sym->result->attr.allocatable || sym->result->attr.pointer)) + { + gfc_error ("Function result variable %qs at %L of elemental " + "function %qs shall not have an ALLOCATABLE or POINTER " + "attribute", sym->result->name, + &sym->result->declared_at, sym->name); + return false; + } + if (sym->attr.is_bind_c && sym->attr.is_c_interop != 1) { gfc_formal_arglist *curr_arg; @@ -13799,6 +13815,31 @@ if (!success) return false; + /* Now add the caf token field, where needed. */ + if (flag_coarray != GFC_FCOARRAY_NONE + && !sym->attr.is_class && !sym->attr.vtype) + { + for (c = sym->components; c; c = c->next) + if (!c->attr.dimension && !c->attr.codimension + && (c->attr.allocatable || c->attr.pointer)) + { + char name[GFC_MAX_SYMBOL_LEN+9]; + gfc_component *token; + sprintf (name, "_caf_%s", c->name); + token = gfc_find_component (sym, name, true, true, NULL); + if (token == NULL) + { + if (!gfc_add_component (sym, name, &token)) + return false; + token->ts.type = BT_VOID; + token->ts.kind = gfc_default_integer_kind; + token->attr.access = ACCESS_PRIVATE; + token->attr.artificial = 1; + token->attr.caf_token = 1; + } + } + } + check_defined_assignments (sym); if (!sym->attr.defined_assign_comp && super_type) Index: gcc/fortran/trans-decl.c =================================================================== diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c --- a/gcc/fortran/trans-decl.c (revision 257042) +++ b/gcc/fortran/trans-decl.c (revision 259627) @@ -4142,6 +4142,24 @@ return tmp; } + +/* Get the result expression for a procedure. */ + +static tree +get_proc_result (gfc_symbol* sym) +{ + if (sym->attr.subroutine || sym == sym->result) + { + if (current_fake_result_decl != NULL) + return TREE_VALUE (current_fake_result_decl); + + return NULL_TREE; + } + + return sym->result->backend_decl; +} + + /* Generate function entry and exit code, and add it to the function body. This includes: Allocation and initialization of array variables. @@ -4251,7 +4269,22 @@ else gcc_assert (flag_f2c && proc_sym->ts.type == BT_COMPLEX); } + else if (proc_sym == proc_sym->result && IS_CLASS_ARRAY (proc_sym)) + { + /* Nullify explicit return class arrays on entry. */ + tree type; + tmp = get_proc_result (proc_sym); + if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp))) + { + gfc_start_block (&init); + tmp = gfc_class_data_get (tmp); + type = TREE_TYPE (gfc_conv_descriptor_data_get (tmp)); + gfc_conv_descriptor_data_set (&init, tmp, build_int_cst (type, 0)); + gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE); + } + } + /* Initialize the INTENT(OUT) derived type dummy arguments. This should be done here so that the offsets and lbounds of arrays are available. */ @@ -5981,23 +6014,6 @@ } -/* Get the result expression for a procedure. */ - -static tree -get_proc_result (gfc_symbol* sym) -{ - if (sym->attr.subroutine || sym == sym->result) - { - if (current_fake_result_decl != NULL) - return TREE_VALUE (current_fake_result_decl); - - return NULL_TREE; - } - - return sym->result->backend_decl; -} - - /* Generate an appropriate return-statement for a procedure. */ tree Index: gcc/fortran/match.c =================================================================== diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c --- a/gcc/fortran/match.c (revision 257042) +++ b/gcc/fortran/match.c (revision 259627) @@ -2001,12 +2001,17 @@ { match m; locus old_locus; - char name[GFC_MAX_SYMBOL_LEN + 1]; + char c, name[GFC_MAX_SYMBOL_LEN + 1]; gfc_clear_ts (ts); gfc_gobble_whitespace (); old_locus = gfc_current_locus; + /* If c isn't [a-z], then return immediately. */ + c = gfc_peek_ascii_char (); + if (!ISALPHA(c)) + return MATCH_NO; + if (match_derived_type_spec (ts) == MATCH_YES) { /* Enforce F03:C401. */ @@ -2045,6 +2050,8 @@ ts->type = BT_CHARACTER; m = gfc_match_char_spec (ts); + if (ts->u.cl && ts->u.cl->length) + gfc_resolve_expr (ts->u.cl->length); if (m == MATCH_NO) m = MATCH_YES; @@ -4404,8 +4411,8 @@ && (tail->expr->ref->type == REF_COMPONENT || tail->expr->ref->type == REF_ARRAY)); if (sym && sym->ts.type == BT_CLASS) - b2 = !(CLASS_DATA (sym)->attr.allocatable - || CLASS_DATA (sym)->attr.class_pointer); + b2 = !(CLASS_DATA (sym) && (CLASS_DATA (sym)->attr.allocatable + || CLASS_DATA (sym)->attr.class_pointer)); else b2 = sym && !(sym->attr.allocatable || sym->attr.pointer || sym->attr.proc_pointer); Index: gcc/fortran/trans-io.c =================================================================== diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c --- a/gcc/fortran/trans-io.c (revision 257042) +++ b/gcc/fortran/trans-io.c (revision 259627) @@ -639,12 +639,12 @@ /* Don't evaluate the UNIT number multiple times. */ se.expr = gfc_evaluate_now (se.expr, &se.pre); - /* UNIT numbers should be greater than zero. */ + /* UNIT numbers should be greater than the min. */ i = gfc_validate_kind (BT_INTEGER, 4, false); + val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].pedantic_min_int, 4); cond1 = build2_loc (input_location, LT_EXPR, logical_type_node, se.expr, - fold_convert (TREE_TYPE (se.expr), - integer_zero_node)); + fold_convert (TREE_TYPE (se.expr), val)); /* UNIT numbers should be less than the max. */ val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4); cond2 = build2_loc (input_location, GT_EXPR, logical_type_node, @@ -2214,26 +2214,10 @@ bool formatted = false; gfc_dt *dt = code->ext.dt; - if (dt) - { - char *fmt = NULL; + /* Determine when to use the formatted DTIO procedure. */ + if (dt && (dt->format_expr || dt->format_label)) + formatted = true; - if (dt->format_label == &format_asterisk) - { - /* List directed io must call the formatted DTIO procedure. */ - formatted = true; - } - else if (dt->format_expr) - fmt = gfc_widechar_to_char (dt->format_expr->value.character.string, - -1); - else if (dt->format_label) - fmt = gfc_widechar_to_char (dt->format_label->format->value.character.string, - -1); - if (fmt && strtok (fmt, "DT") != NULL) - formatted = true; - - } - if (ts->type == BT_CLASS) derived = ts->u.derived->components->ts.u.derived; else @@ -2293,6 +2277,16 @@ ts->kind = gfc_index_integer_kind; } + /* gfortran reaches here for "print *, c_loc(xxx)". */ + if (ts->type == BT_VOID + && code->expr1 && code->expr1->ts.type == BT_VOID + && code->expr1->symtree + && strcmp (code->expr1->symtree->name, "c_loc") == 0) + { + ts->type = BT_INTEGER; + ts->kind = gfc_index_integer_kind; + } + kind = ts->kind; function = NULL; arg2 = NULL; @@ -2442,8 +2436,7 @@ { /* Recurse into the elements of the derived type. */ expr = gfc_evaluate_now (addr_expr, &se->pre); - expr = build_fold_indirect_ref_loc (input_location, - expr); + expr = build_fold_indirect_ref_loc (input_location, expr); /* Make sure that the derived type has been built. An external function, if only referenced in an io statement, requires this Index: gcc/fortran/arith.c =================================================================== diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c --- a/gcc/fortran/arith.c (revision 257042) +++ b/gcc/fortran/arith.c (revision 259627) @@ -555,10 +555,10 @@ val = ARITH_OK; } - if (val != ARITH_OK) + if (val == ARITH_OK || val == ARITH_OVERFLOW) + *rp = r; + else gfc_free_expr (r); - else - *rp = r; return val; } @@ -1603,9 +1603,13 @@ if (rc != ARITH_OK) { gfc_error (gfc_arith_error (rc), &op1->where); + if (rc == ARITH_OVERFLOW) + goto done; return NULL; } +done: + gfc_free_expr (op1); gfc_free_expr (op2); return result; Index: gcc/fortran/primary.c =================================================================== diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c --- a/gcc/fortran/primary.c (revision 257042) +++ b/gcc/fortran/primary.c (revision 259627) @@ -1247,8 +1247,22 @@ if (sym->attr.flavor != FL_PARAMETER) { - gfc_error ("Expected PARAMETER symbol in complex constant at %C"); - return MATCH_ERROR; + /* Give the matcher for implied do-loops a chance to run. This yields + a much saner error message for "write(*,*) (i, i=1, 6" where the + right parenthesis is missing. */ + char c; + gfc_gobble_whitespace (); + c = gfc_peek_ascii_char (); + if (c == '=' || c == ',') + { + m = MATCH_NO; + } + else + { + gfc_error ("Expected PARAMETER symbol in complex constant at %C"); + m = MATCH_ERROR; + } + return m; } if (!sym->value) Index: gcc/fortran/trans-intrinsic.c =================================================================== diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c --- a/gcc/fortran/trans-intrinsic.c (revision 257042) +++ b/gcc/fortran/trans-intrinsic.c (revision 259627) @@ -5478,6 +5478,22 @@ } static void +gfc_conv_intrinsic_shape (gfc_se *se, gfc_expr *expr) +{ + gfc_actual_arglist *s, *k; + gfc_expr *e; + + /* Remove the KIND argument, if present. */ + s = expr->value.function.actual; + k = s->next; + e = k->expr; + gfc_free_expr (e); + k->expr = NULL; + + gfc_conv_intrinsic_funcall (se, expr); +} + +static void gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift, bool arithmetic) { @@ -6601,7 +6617,7 @@ gfc_add_class_array_ref (actual->expr); argse.data_not_needed = 1; - if (gfc_is_alloc_class_array_function (actual->expr)) + if (gfc_is_class_array_function (actual->expr)) { /* For functions that return a class array conv_expr_descriptor is not able to get the descriptor right. Therefore this special case. */ @@ -8589,6 +8605,10 @@ conv_generic_with_optional_char_arg (se, expr, 1, 3); break; + case GFC_ISYM_SHAPE: + gfc_conv_intrinsic_shape (se, expr); + break; + default: gfc_conv_intrinsic_funcall (se, expr); break; Index: gcc/fortran/simplify.c =================================================================== diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c --- a/gcc/fortran/simplify.c (revision 257042) +++ b/gcc/fortran/simplify.c (revision 259627) @@ -25,6 +25,7 @@ #include "gfortran.h" #include "arith.h" #include "intrinsic.h" +#include "match.h" #include "target-memory.h" #include "constructor.h" #include "version.h" /* For version_string. */ @@ -6579,11 +6580,13 @@ unsigned char *buffer; size_t result_length; + if (!gfc_is_constant_expr (source) || !gfc_is_constant_expr (size)) + return NULL; - if (!gfc_is_constant_expr (source) - || (gfc_init_expr_flag && !gfc_is_constant_expr (mold)) - || !gfc_is_constant_expr (size)) + if (!gfc_resolve_expr (mold)) return NULL; + if (gfc_init_expr_flag && !gfc_is_constant_expr (mold)) + return NULL; if (!gfc_calculate_transfer_sizes (source, mold, size, &source_size, &result_size, &result_length)) @@ -7172,26 +7175,32 @@ { gfc_expr *tmp; if (c->iterator == NULL) - tmp = f (c->expr, kind); + { + tmp = f (c->expr, kind); + if (tmp == NULL) + { + gfc_free_expr (result); + return NULL; + } + + gfc_constructor_append_expr (&result->value.constructor, + tmp, &c->where); + } else { + gfc_constructor *n; g = gfc_convert_constant (c->expr, type, kind); - if (g == &gfc_bad_expr) + if (g == NULL || g == &gfc_bad_expr) { gfc_free_expr (result); return g; } - tmp = g; + n = gfc_constructor_get (); + n->expr = g; + n->iterator = gfc_copy_iterator (c->iterator); + n->where = c->where; + gfc_constructor_append (&result->value.constructor, n); } - - if (tmp == NULL) - { - gfc_free_expr (result); - return NULL; - } - - gfc_constructor_append_expr (&result->value.constructor, - tmp, &c->where); } break; Index: gcc/tree-eh.h =================================================================== diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h --- a/gcc/tree-eh.h (revision 257042) +++ b/gcc/tree-eh.h (revision 259627) @@ -37,6 +37,7 @@ bool, tree, bool *); extern bool operation_could_trap_p (enum tree_code, bool, bool, tree); extern bool tree_could_trap_p (tree); +extern tree rewrite_to_non_trapping_overflow (tree); extern bool stmt_could_throw_p (gimple *); extern bool tree_could_throw_p (tree); extern bool stmt_can_throw_external (gimple *); Index: gcc/ipa-devirt.c =================================================================== diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c --- a/gcc/ipa-devirt.c (revision 257042) +++ b/gcc/ipa-devirt.c (revision 259627) @@ -1577,8 +1577,15 @@ "in another translation unit")); return false; } - gcc_assert (DECL_NONADDRESSABLE_P (f1) - == DECL_NONADDRESSABLE_P (f2)); + if (DECL_BIT_FIELD (f1) != DECL_BIT_FIELD (f2)) + { + warn_odr (t1, t2, f1, f2, warn, warned, + G_("one field is bitfield while other is not")); + return false; + } + else + gcc_assert (DECL_NONADDRESSABLE_P (f1) + == DECL_NONADDRESSABLE_P (f2)); } /* If one aggregate has more fields than the other, they Index: gcc/configure.ac =================================================================== diff --git a/gcc/configure.ac b/gcc/configure.ac --- a/gcc/configure.ac (revision 257042) +++ b/gcc/configure.ac (revision 259627) @@ -2946,6 +2946,14 @@ [elf,2,12,0], [--fatal-warnings], [.section .rodata.str, "aMS", %progbits, 1]) fi +case "$target" in + i?86-*-solaris2.10* | x86_64-*-solaris2.10*) + # SHF_MERGE support in Solaris 10/x86 ld is broken. + if test x"$gnu_ld" = xno; then + gcc_cv_as_shf_merge=no + fi + ;; +esac AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_MERGE, [`if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`], [Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.]) Index: gcc/BASE-VER =================================================================== diff --git a/gcc/BASE-VER b/gcc/BASE-VER --- a/gcc/BASE-VER (revision 257042) +++ b/gcc/BASE-VER (revision 259627) @@ -1 +1 @@ -7.3.0 +7.3.1 Index: gcc/stor-layout.c =================================================================== diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c --- a/gcc/stor-layout.c (revision 257042) +++ b/gcc/stor-layout.c (revision 259627) @@ -1526,6 +1526,30 @@ = size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field)); rli->bitpos = bitsize_zero_node; rli->offset_align = MIN (rli->offset_align, desired_align); + + if (!multiple_of_p (bitsizetype, DECL_SIZE (field), + bitsize_int (rli->offset_align))) + { + tree type = strip_array_types (TREE_TYPE (field)); + /* The above adjusts offset_align just based on the start of the + field. The field might not have a size that is a multiple of + that offset_align though. If the field is an array of fixed + sized elements, assume there can be any multiple of those + sizes. If it is a variable length aggregate or array of + variable length aggregates, assume worst that the end is + just BITS_PER_UNIT aligned. */ + if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) + { + if (TREE_INT_CST_LOW (TYPE_SIZE (type))) + { + unsigned HOST_WIDE_INT sz + = least_bit_hwi (TREE_INT_CST_LOW (TYPE_SIZE (type))); + rli->offset_align = MIN (rli->offset_align, sz); + } + } + else + rli->offset_align = MIN (rli->offset_align, BITS_PER_UNIT); + } } else if (targetm.ms_bitfield_layout_p (rli->t)) { Index: gcc/genmatch.c =================================================================== diff --git a/gcc/genmatch.c b/gcc/genmatch.c --- a/gcc/genmatch.c (revision 257042) +++ b/gcc/genmatch.c (revision 259627) @@ -2054,7 +2054,11 @@ if (c->what && (e = dyn_cast (c->what))) { - info[where].expr_p = true; + /* Zero-operand expression captures like ADDR_EXPR@0 are + similar as predicates -- if they are not mentioned in + the result we have to force them to have no side-effects. */ + if (e->ops.length () != 0) + info[where].expr_p = true; info[where].force_single_use |= e->force_single_use; } } Index: gcc/tree-if-conv.c =================================================================== diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c --- a/gcc/tree-if-conv.c (revision 257042) +++ b/gcc/tree-if-conv.c (revision 259627) @@ -2248,10 +2248,7 @@ TREE_OPERAND (cond, 0), TREE_OPERAND (cond, 1)); else - { - gcc_assert (TREE_CODE (cond) == SSA_NAME); - mask = cond; - } + mask = cond; if (swap) { Index: gcc/tree-vect-loop.c =================================================================== diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c --- a/gcc/tree-vect-loop.c (revision 257042) +++ b/gcc/tree-vect-loop.c (revision 259627) @@ -50,6 +50,7 @@ #include "cgraph.h" #include "tree-cfg.h" #include "tree-if-conv.h" +#include "tree-eh.h" /* Loop Vectorization Pass. @@ -1055,7 +1056,8 @@ may_be_zero)); else niter = fold_build3 (COND_EXPR, TREE_TYPE (niter), may_be_zero, - build_int_cst (TREE_TYPE (niter), 0), niter); + build_int_cst (TREE_TYPE (niter), 0), + rewrite_to_non_trapping_overflow (niter)); may_be_zero = NULL_TREE; } Index: gcc/loop-unroll.c =================================================================== diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c --- a/gcc/loop-unroll.c (revision 257042) +++ b/gcc/loop-unroll.c (revision 259627) @@ -477,7 +477,7 @@ exit_mod = niter % (max_unroll + 1); - auto_sbitmap wont_exit (max_unroll + 1); + auto_sbitmap wont_exit (max_unroll + 2); bitmap_ones (wont_exit); auto_vec remove_edges; Index: gcc/tree-vect-data-refs.c =================================================================== diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c --- a/gcc/tree-vect-data-refs.c (revision 257042) +++ b/gcc/tree-vect-data-refs.c (revision 259627) @@ -394,6 +394,16 @@ } } + unsigned int step_prec = TYPE_PRECISION (TREE_TYPE (DR_STEP (dra))); + if (loop->safelen < 2 + && !expr_not_equal_to (DR_STEP (dra), wi::zero (step_prec))) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "step could be zero.\n"); + return true; + } + continue; } @@ -2515,7 +2525,7 @@ /* Allow references with zero step for outer loops marked with pragma omp simd only - it guarantees absence of loop-carried dependencies between inner loop iterations. */ - if (!loop->force_vectorize) + if (!loop->force_vectorize || loop->safelen < 2) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, Index: gcc/gimplify.c =================================================================== diff --git a/gcc/gimplify.c b/gcc/gimplify.c --- a/gcc/gimplify.c (revision 257042) +++ b/gcc/gimplify.c (revision 259627) @@ -1125,10 +1125,6 @@ asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it, bool before) { - /* When within an OMP context, do not emit ASAN_MARK internal fns. */ - if (gimplify_omp_ctxp) - return; - tree unit_size = DECL_SIZE_UNIT (decl); tree base = build_fold_addr_expr (decl); @@ -1640,7 +1636,8 @@ && TREE_ADDRESSABLE (decl) && !TREE_STATIC (decl) && !DECL_HAS_VALUE_EXPR_P (decl) - && dbg_cnt (asan_use_after_scope)) + && dbg_cnt (asan_use_after_scope) + && !gimplify_omp_ctxp) { asan_poisoned_variables->add (decl); asan_poison_variable (decl, false, seq_p); @@ -6458,7 +6455,8 @@ clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber); gimple_push_cleanup (temp, clobber, false, pre_p, true); } - if (asan_poisoned_variables && dbg_cnt (asan_use_after_scope)) + if (asan_poisoned_variables && dbg_cnt (asan_use_after_scope) + && !gimplify_omp_ctxp) { tree asan_cleanup = build_asan_poison_call_expr (temp); if (asan_cleanup) Index: gcc/lra-constraints.c =================================================================== diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c --- a/gcc/lra-constraints.c (revision 257042) +++ b/gcc/lra-constraints.c (revision 259627) @@ -3724,7 +3724,13 @@ curr_insn_set = single_set (curr_insn); if (curr_insn_set != NULL_RTX && simple_move_p ()) - return false; + { + /* We assume that the corresponding insn alternative has no + earlier clobbers. If it is not the case, don't define move + cost equal to 2 for the corresponding register classes. */ + lra_set_used_insn_alternative (curr_insn, LRA_NON_CLOBBERED_ALT); + return false; + } no_input_reloads_p = no_output_reloads_p = false; goal_alt_number = -1; @@ -3832,7 +3838,7 @@ if (change_p) /* If we've changed the instruction then any alternative that we chose previously may no longer be valid. */ - lra_set_used_insn_alternative (curr_insn, -1); + lra_set_used_insn_alternative (curr_insn, LRA_UNKNOWN_ALT); if (! check_only_p && curr_insn_set != NULL_RTX && check_and_process_move (&change_p, &sec_mem_p)) @@ -3840,7 +3846,7 @@ try_swapped: - reused_alternative_num = check_only_p ? -1 : curr_id->used_insn_alternative; + reused_alternative_num = check_only_p ? LRA_UNKNOWN_ALT : curr_id->used_insn_alternative; if (lra_dump_file != NULL && reused_alternative_num >= 0) fprintf (lra_dump_file, "Reusing alternative %d for insn #%u\n", reused_alternative_num, INSN_UID (curr_insn)); @@ -6708,7 +6714,7 @@ } lra_push_insn_and_update_insn_regno_info (curr_insn); lra_set_used_insn_alternative_by_uid - (INSN_UID (curr_insn), -1); + (INSN_UID (curr_insn), LRA_UNKNOWN_ALT); done_p = true; if (lra_dump_file != NULL) { @@ -6747,7 +6753,7 @@ constraints pass. */ lra_push_insn_and_update_insn_regno_info (curr_insn); lra_set_used_insn_alternative_by_uid - (INSN_UID (curr_insn), -1); + (INSN_UID (curr_insn), LRA_UNKNOWN_ALT); } else if (restored_regs_p) /* The instruction has been restored to the form that Index: gcc/genmodes.c =================================================================== diff --git a/gcc/genmodes.c b/gcc/genmodes.c --- a/gcc/genmodes.c (revision 257042) +++ b/gcc/genmodes.c (revision 259627) @@ -116,6 +116,7 @@ switch (c) { case MODE_INT: return MODE_COMPLEX_INT; + case MODE_PARTIAL_INT: return MODE_COMPLEX_INT; case MODE_FLOAT: return MODE_COMPLEX_FLOAT; default: error ("no complex class for class %s", mode_class_names[c]); Index: gcc/expmed.c =================================================================== diff --git a/gcc/expmed.c b/gcc/expmed.c --- a/gcc/expmed.c (revision 257042) +++ b/gcc/expmed.c (revision 259627) @@ -5886,6 +5886,18 @@ if (tem != 0) return tem; + /* If one operand is constant, make it the second one. Only do this + if the other operand is not constant as well. */ + + if (swap_commutative_operands_p (op0, op1)) + { + std::swap (op0, op1); + code = swap_condition (code); + } + + if (mode == VOIDmode) + mode = GET_MODE (op0); + if (!target) target = gen_reg_rtx (word_mode); Index: gcc/simplify-rtx.c =================================================================== diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c --- a/gcc/simplify-rtx.c (revision 257042) +++ b/gcc/simplify-rtx.c (revision 259627) @@ -3299,7 +3299,8 @@ if (CONST_INT_P (trueop1) && exact_log2 (UINTVAL (trueop1)) > 0) return simplify_gen_binary (AND, mode, op0, - gen_int_mode (INTVAL (op1) - 1, mode)); + gen_int_mode (UINTVAL (trueop1) - 1, + mode)); break; case MOD: Index: gcc/tree-ssa-pre.c =================================================================== diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c --- a/gcc/tree-ssa-pre.c (revision 257042) +++ b/gcc/tree-ssa-pre.c (revision 259627) @@ -2787,11 +2787,7 @@ unsigned int operand = 1; vn_reference_op_t currop = &ref->operands[0]; tree sc = NULL_TREE; - tree fn; - if (TREE_CODE (currop->op0) == FUNCTION_DECL) - fn = currop->op0; - else - fn = find_or_generate_expression (block, currop->op0, stmts); + tree fn = find_or_generate_expression (block, currop->op0, stmts); if (!fn) return NULL_TREE; if (currop->op1) @@ -2809,14 +2805,27 @@ return NULL_TREE; args.quick_push (arg); } - gcall *call - = gimple_build_call_vec ((TREE_CODE (fn) == FUNCTION_DECL - ? build_fold_addr_expr (fn) : fn), args); + gcall *call = gimple_build_call_vec (fn, args); gimple_call_set_with_bounds (call, currop->with_bounds); if (sc) gimple_call_set_chain (call, sc); tree forcedname = make_ssa_name (currop->type); gimple_call_set_lhs (call, forcedname); + /* There's no CCP pass after PRE which would re-compute alignment + information so make sure we re-materialize this here. */ + if (gimple_call_builtin_p (call, BUILT_IN_ASSUME_ALIGNED) + && args.length () - 2 <= 1 + && tree_fits_uhwi_p (args[1]) + && (args.length () != 3 || tree_fits_uhwi_p (args[2]))) + { + unsigned HOST_WIDE_INT halign = tree_to_uhwi (args[1]); + unsigned HOST_WIDE_INT hmisalign + = args.length () == 3 ? tree_to_uhwi (args[2]) : 0; + if ((halign & (halign - 1)) == 0 + && (hmisalign & ~(halign - 1)) == 0) + set_ptr_info_alignment (get_ptr_info (forcedname), + halign, hmisalign); + } gimple_set_vuse (call, BB_LIVE_VOP_ON_EXIT (block)); gimple_seq_add_stmt_without_update (&forced_stmts, call); folded = forcedname; Index: gcc/lto/lto.c =================================================================== diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c --- a/gcc/lto/lto.c (revision 257042) +++ b/gcc/lto/lto.c (revision 259627) @@ -53,6 +53,7 @@ #include "lto-symtab.h" #include "stringpool.h" #include "fold-const.h" +#include "builtins.h" /* Number of parallel tasks to run, -1 if we want to use GNU Make jobserver. */ @@ -829,12 +830,19 @@ register_resolution (struct lto_file_decl_data *file_data, tree decl, enum ld_plugin_symbol_resolution resolution) { + bool existed; if (resolution == LDPR_UNKNOWN) return; if (!file_data->resolution_map) file_data->resolution_map = new hash_map; - file_data->resolution_map->put (decl, resolution); + ld_plugin_symbol_resolution_t &res + = file_data->resolution_map->get_or_insert (decl, &existed); + if (!existed + || resolution == LDPR_PREVAILING_DEF_IRONLY + || resolution == LDPR_PREVAILING_DEF + || resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + res = resolution; } /* Register DECL with the global symbol table and change its @@ -877,7 +885,19 @@ decl, get_resolution (data_in, ix)); } +/* Check if T is a decl and needs register its resolution info. */ +static void +lto_maybe_register_decl (struct data_in *data_in, tree t, unsigned ix) +{ + if (TREE_CODE (t) == VAR_DECL) + lto_register_var_decl_in_symtab (data_in, t, ix); + else if (TREE_CODE (t) == FUNCTION_DECL + && !DECL_BUILT_IN (t)) + lto_register_function_decl_in_symtab (data_in, t, ix); +} + + /* For the type T re-materialize it in the type variant list and the pointer/reference-to chains. */ @@ -1607,7 +1627,10 @@ /* Fixup the streamer cache with the prevailing nodes according to the tree node mapping computed by compare_tree_sccs. */ if (len == 1) - streamer_tree_cache_replace_tree (cache, pscc->entries[0], from); + { + lto_maybe_register_decl (data_in, pscc->entries[0], from); + streamer_tree_cache_replace_tree (cache, pscc->entries[0], from); + } else { tree *map2 = XALLOCAVEC (tree, 2 * len); @@ -1619,8 +1642,12 @@ qsort (map2, len, 2 * sizeof (tree), cmp_tree); qsort (map, len, 2 * sizeof (tree), cmp_tree); for (unsigned i = 0; i < len; ++i) - streamer_tree_cache_replace_tree (cache, map[2*i], - (uintptr_t)map2[2*i]); + { + lto_maybe_register_decl (data_in, map[2*i], + (uintptr_t)map2[2*i]); + streamer_tree_cache_replace_tree (cache, map[2*i], + (uintptr_t)map2[2*i]); + } } /* Free the tree nodes from the read SCC. */ @@ -1759,13 +1786,7 @@ } if (!flag_ltrans) { - /* Register variables and functions with the - symbol table. */ - if (TREE_CODE (t) == VAR_DECL) - lto_register_var_decl_in_symtab (data_in, t, from + i); - else if (TREE_CODE (t) == FUNCTION_DECL - && !DECL_BUILT_IN (t)) - lto_register_function_decl_in_symtab (data_in, t, from + i); + lto_maybe_register_decl (data_in, t, from + i); /* Scan the tree for references to global functions or variables and record those for later fixup. */ if (mentions_vars_p (t)) @@ -2858,13 +2879,25 @@ /* Store resolutions into the symbol table. */ - ld_plugin_symbol_resolution_t *res; FOR_EACH_SYMBOL (snode) - if (snode->real_symbol_p () - && snode->lto_file_data - && snode->lto_file_data->resolution_map - && (res = snode->lto_file_data->resolution_map->get (snode->decl))) - snode->resolution = *res; + if (snode->externally_visible && snode->real_symbol_p () + && snode->lto_file_data && snode->lto_file_data->resolution_map + && !is_builtin_fn (snode->decl) + && !(VAR_P (snode->decl) && DECL_HARD_REGISTER (snode->decl))) + { + ld_plugin_symbol_resolution_t *res; + + res = snode->lto_file_data->resolution_map->get (snode->decl); + if (!res || *res == LDPR_UNKNOWN) + { + if (snode->output_to_lto_symbol_table_p ()) + fatal_error (input_location, "missing resolution data for %s", + IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (snode->decl))); + } + else + snode->resolution = *res; + } for (i = 0; all_file_decl_data[i]; i++) if (all_file_decl_data[i]->resolution_map) { Index: gcc/lto/lto-partition.c =================================================================== diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c --- a/gcc/lto/lto-partition.c (revision 257042) +++ b/gcc/lto/lto-partition.c (revision 259627) @@ -756,7 +756,8 @@ if (npartitions < n_lto_partitions) partition_size = total_size / (n_lto_partitions - npartitions); else - partition_size = INT_MAX; + /* Watch for overflow. */ + partition_size = INT_MAX / 16; if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE)) partition_size = PARAM_VALUE (MIN_PARTITION_SIZE); Index: gcc/lto/ChangeLog =================================================================== diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog --- a/gcc/lto/ChangeLog (revision 257042) +++ b/gcc/lto/ChangeLog (revision 259627) @@ -1,3 +1,102 @@ +2018-04-24 Martin Liska + + Backport from mainline + 2018-04-19 Martin Liska + + * lto-symtab.c (lto_symtab_resolve_symbols): Do not bail out + for multiple PREVAILING_DEF_IRONLY for common symbols. + +2018-04-24 Martin Liska + + Backport from mainline + 2018-04-10 Martin Liska + + PR lto/85248 + * lto-symtab.c (lto_symtab_merge_p): Do not check for + TREE_VALUES of error attributes. + +2018-04-24 Martin Liska + + Backport from mainline + 2018-04-10 Richard Biener + Martin Liska + + PR lto/85248 + * lto-symtab.c (lto_symtab_merge_p): Handle noreturn attribute. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-01-23 Martin Liska + + PR lto/81440 + * lto-symtab.c (lto_symtab_merge): Handle and do not warn about + trailing arrays at the end of a struct. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-08 Jan Hubicka + + * lto-partition.c (lto_balanced_map): Watch overflow. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-08 Jan Hubicka + + PR ipa/81360 + * lto.c (unify_scc): Register prevailing trees, not trees to be freed. + (read_cgraph_and_symbols): Use + symtab_node::output_to_lto_symbol_table_p. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-01-30 Jan Hubicka + + * lto.c (register_resolution): Remove forgotten sanity check. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-01-30 Jan Hubicka + + PR lto/81004 + * lto.c: Include builtins.h + (register_resolution): Merge resolutions in case trees was + merged across units. + (lto_maybe_register_decl): Break out from ... + (lto_read_decls): ... here. + (unify_scc): Also register decls here. + (read_cgraph_and_symbols): Sanity check that all resolutions was + read. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-02-02 Eric Botcazou + + PR lto/83954 + * lto-symtab.c (warn_type_compatibility_p): Do not recurse into the + component type of array types with non-aliased component. + +2018-03-06 Martin Liska + + Backport from mainline + 2018-01-30 Jan Hubicka + + PR lto/83954 + * lto-symtab.c (warn_type_compatibility_p): Silence false positive + for type match warning on arrays of pointers. + +2018-03-06 Martin Liska + + Backport from mainline + 2017-10-13 Jan Hubicka + + * lto-lang.c (lto_post_options): Clean shlib flag when not doing PIC. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: gcc/lto/lto-lang.c =================================================================== diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c --- a/gcc/lto/lto-lang.c (revision 257042) +++ b/gcc/lto/lto-lang.c (revision 259627) @@ -840,11 +840,13 @@ flag_pie is 2. */ flag_pie = MAX (flag_pie, flag_pic); flag_pic = flag_pie; + flag_shlib = 0; break; case LTO_LINKER_OUTPUT_EXEC: /* Normal executable */ flag_pic = 0; flag_pie = 0; + flag_shlib = 0; break; case LTO_LINKER_OUTPUT_UNKNOWN: Index: gcc/lto/lto-symtab.c =================================================================== diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c --- a/gcc/lto/lto-symtab.c (revision 257042) +++ b/gcc/lto/lto-symtab.c (revision 259627) @@ -283,11 +283,25 @@ alias_set_type set1 = get_alias_set (type); alias_set_type set2 = get_alias_set (prevailing_type); - if (set1 && set2 && set1 != set2 - && (!POINTER_TYPE_P (type) || !POINTER_TYPE_P (prevailing_type) + if (set1 && set2 && set1 != set2) + { + tree t1 = type, t2 = prevailing_type; + + /* Alias sets of arrays with aliased components are the same as alias + sets of the inner types. */ + while (TREE_CODE (t1) == ARRAY_TYPE + && !TYPE_NONALIASED_COMPONENT (t1) + && TREE_CODE (t2) == ARRAY_TYPE + && !TYPE_NONALIASED_COMPONENT (t2)) + { + t1 = TREE_TYPE (t1); + t2 = TREE_TYPE (t2); + } + if ((!POINTER_TYPE_P (t1) || !POINTER_TYPE_P (t2)) || (set1 != TYPE_ALIAS_SET (ptr_type_node) - && set2 != TYPE_ALIAS_SET (ptr_type_node)))) - lev |= 5; + && set2 != TYPE_ALIAS_SET (ptr_type_node))) + lev |= 5; + } } return lev; @@ -351,7 +365,22 @@ return false; if (DECL_SIZE (decl) && DECL_SIZE (prevailing_decl) - && !tree_int_cst_equal (DECL_SIZE (decl), DECL_SIZE (prevailing_decl)) + && !tree_int_cst_equal (DECL_SIZE (decl), DECL_SIZE (prevailing_decl))) + { + if (!DECL_COMMON (decl) && !DECL_EXTERNAL (decl)) + return false; + + tree type = TREE_TYPE (decl); + + /* For record type, check for array at the end of the structure. */ + if (TREE_CODE (type) == RECORD_TYPE) + { + tree field = TYPE_FIELDS (type); + while (DECL_CHAIN (field) != NULL_TREE) + field = DECL_CHAIN (field); + + return TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE; + } /* As a special case do not warn about merging int a[]; and @@ -358,11 +387,9 @@ int a[]={1,2,3}; here the first declaration is COMMON and sizeof(a) == sizeof (int). */ - && ((!DECL_COMMON (decl) && !DECL_EXTERNAL (decl)) - || TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE - || TYPE_SIZE (TREE_TYPE (decl)) - != TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))))) - return false; + else if (TREE_CODE (type) == ARRAY_TYPE) + return (TYPE_SIZE (decl) == TYPE_SIZE (TREE_TYPE (type))); + } return true; } @@ -438,9 +465,14 @@ /* If the chain is already resolved there is nothing else to do. */ if (prevailing) { - /* Assert it's the only one. */ + /* Assert it's the only one. + GCC should silence multiple PREVAILING_DEF_IRONLY defs error + on COMMON symbols since it isn't error. + See: https://sourceware.org/bugzilla/show_bug.cgi?id=23079. */ for (e = prevailing->next_sharing_asm_name; e; e = e->next_sharing_asm_name) if (lto_symtab_symbol_p (e) + && !DECL_COMMON (prevailing->decl) + && !DECL_COMMON (e->decl) && (e->resolution == LDPR_PREVAILING_DEF_IRONLY || e->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP || e->resolution == LDPR_PREVAILING_DEF)) @@ -544,6 +576,9 @@ return false; } } + + /* FIXME: after MPX is removed, use flags_from_decl_or_type + function instead. PR lto/85248. */ if (DECL_ATTRIBUTES (prevailing) != DECL_ATTRIBUTES (decl)) { tree prev_attr = lookup_attribute ("error", DECL_ATTRIBUTES (prevailing)); @@ -571,6 +606,16 @@ "warning attribute mismatch\n"); return false; } + + prev_attr = lookup_attribute ("noreturn", DECL_ATTRIBUTES (prevailing)); + attr = lookup_attribute ("noreturn", DECL_ATTRIBUTES (decl)); + if ((prev_attr == NULL) != (attr == NULL)) + { + if (symtab->dump_file) + fprintf (symtab->dump_file, "Not merging decls; " + "noreturn attribute mismatch\n"); + return false; + } } return true; } Index: gcc/ipa-prop.c =================================================================== diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c --- a/gcc/ipa-prop.c (revision 257042) +++ b/gcc/ipa-prop.c (revision 259627) @@ -111,12 +111,13 @@ typedef value_range *compare_type; static hashval_t hash (const value_range *p) - { - gcc_checking_assert (!p->equiv); - hashval_t t = (hashval_t) p->type; - t = iterative_hash_expr (p->min, t); - return iterative_hash_expr (p->max, t); - } + { + gcc_checking_assert (!p->equiv); + inchash::hash hstate (p->type); + hstate.add_ptr (p->min); + hstate.add_ptr (p->max); + return hstate.end (); + } static bool equal (const value_range *a, const value_range *b) { @@ -4352,8 +4353,7 @@ gcc_checking_assert (adj->offset % BITS_PER_UNIT == 0); base = gimple_call_arg (stmt, adj->base_index); - loc = DECL_P (base) ? DECL_SOURCE_LOCATION (base) - : EXPR_LOCATION (base); + loc = gimple_location (stmt); if (TREE_CODE (base) != ADDR_EXPR && POINTER_TYPE_P (TREE_TYPE (base))) @@ -4445,6 +4445,7 @@ else expr = create_tmp_reg (TREE_TYPE (expr)); gimple_assign_set_lhs (tem, expr); + gimple_set_location (tem, loc); gsi_insert_before (&gsi, tem, GSI_SAME_STMT); } } Index: gcc/gimple-ssa-store-merging.c =================================================================== diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c --- a/gcc/gimple-ssa-store-merging.c (revision 257042) +++ b/gcc/gimple-ssa-store-merging.c (revision 259627) @@ -812,12 +812,14 @@ { struct store_immediate_info *info; unsigned int i; + tree store_lhs + = gimple_store_p (stmt) ? gimple_get_lhs (stmt) : NULL_TREE; FOR_EACH_VEC_ELT ((*chain_info)->m_store_info, i, info) { - if (ref_maybe_used_by_stmt_p (stmt, - gimple_assign_lhs (info->stmt)) - || stmt_may_clobber_ref_p (stmt, - gimple_assign_lhs (info->stmt))) + tree lhs = gimple_assign_lhs (info->stmt); + if (ref_maybe_used_by_stmt_p (stmt, lhs) + || stmt_may_clobber_ref_p (stmt, lhs) + || (store_lhs && refs_output_dependent_p (store_lhs, lhs))) { if (dump_file && (dump_flags & TDF_DETAILS)) { Index: gcc/sched-deps.c =================================================================== diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c --- a/gcc/sched-deps.c (revision 257042) +++ b/gcc/sched-deps.c (revision 259627) @@ -2851,9 +2851,11 @@ { rtx insn_set = single_set (insn); + if (!insn_set) + return; + prev = prev_nonnote_nondebug_insn (insn); if (!prev - || !insn_set || !single_set (prev)) return; @@ -2920,6 +2922,8 @@ = alloc_INSN_LIST (insn, deps->sched_before_next_jump); /* Make sure epilogue insn is scheduled after preceding jumps. */ + add_dependence_list (insn, deps->last_pending_memory_flush, 1, + REG_DEP_ANTI, true); add_dependence_list (insn, deps->pending_jump_insns, 1, REG_DEP_ANTI, true); } Index: gcc/tree-ssa.c =================================================================== diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c --- a/gcc/tree-ssa.c (revision 257042) +++ b/gcc/tree-ssa.c (revision 259627) @@ -1423,7 +1423,8 @@ if (! DECL_P (decl)) return NULL_TREE; if (! is_gimple_reg_type (TREE_TYPE (base)) - || VOID_TYPE_P (TREE_TYPE (base))) + || VOID_TYPE_P (TREE_TYPE (base)) + || TREE_THIS_VOLATILE (decl) != TREE_THIS_VOLATILE (base)) return decl; if ((TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE || TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE) Index: gcc/tree-vect-stmts.c =================================================================== diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c --- a/gcc/tree-vect-stmts.c (revision 257042) +++ b/gcc/tree-vect-stmts.c (revision 259627) @@ -2753,7 +2753,7 @@ if (cfn != CFN_LAST) fndecl = targetm.vectorize.builtin_vectorized_function (cfn, vectype_out, vectype_in); - else + else if (callee) fndecl = targetm.vectorize.builtin_md_vectorized_function (callee, vectype_out, vectype_in); } Index: gcc/tree-inline.c =================================================================== diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c --- a/gcc/tree-inline.c (revision 257042) +++ b/gcc/tree-inline.c (revision 259627) @@ -57,6 +57,7 @@ #include "cfgloop.h" #include "builtins.h" #include "tree-chkp.h" +#include "attribs.h" /* I'm not real happy about this, but we need to handle gimple and @@ -6024,6 +6025,25 @@ = copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id, args_to_skip, &vars); + /* Remove omp declare simd attribute from the new attributes. */ + if (tree a = lookup_attribute ("omp declare simd", + DECL_ATTRIBUTES (new_decl))) + { + while (tree a2 = lookup_attribute ("omp declare simd", TREE_CHAIN (a))) + a = a2; + a = TREE_CHAIN (a); + for (tree *p = &DECL_ATTRIBUTES (new_decl); *p != a;) + if (is_attribute_p ("omp declare simd", get_attribute_name (*p))) + *p = TREE_CHAIN (*p); + else + { + tree chain = TREE_CHAIN (*p); + *p = copy_node (*p); + p = &TREE_CHAIN (*p); + *p = chain; + } + } + DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id); BLOCK_SUPERCONTEXT (DECL_INITIAL (new_decl)) = new_decl; Index: gcc/symtab.c =================================================================== diff --git a/gcc/symtab.c b/gcc/symtab.c --- a/gcc/symtab.c (revision 257042) +++ b/gcc/symtab.c (revision 259627) @@ -35,6 +35,7 @@ #include "output.h" #include "ipa-utils.h" #include "calls.h" +#include "builtins.h" static const char *ipa_ref_use_name[] = {"read","write","addr","alias","chkp"}; @@ -2279,3 +2280,58 @@ return false; } + +/* Return true if symbol should be output to the symbol table. */ + +bool +symtab_node::output_to_lto_symbol_table_p (void) +{ + /* Only externally visible symbols matter. */ + if (!TREE_PUBLIC (decl)) + return false; + if (!real_symbol_p ()) + return false; + /* FIXME: variables probably should not be considered as real symbols at + first place. */ + if (VAR_P (decl) && DECL_HARD_REGISTER (decl)) + return false; + /* FIXME: Builtins corresponding to real functions probably should have + symbol table entries. */ + if (is_builtin_fn (decl)) + return false; + + /* We have real symbol that should be in symbol table. However try to trim + down the refernces to libraries bit more because linker will otherwise + bring unnecesary object files into the final link. + FIXME: The following checks can easily be confused i.e. by self recursive + function or self-referring variable. */ + + /* We keep external functions in symtab for sake of inlining + and devirtualization. We do not want to see them in symbol table as + references unless they are really used. */ + cgraph_node *cnode = dyn_cast (this); + if (cnode && (!definition || DECL_EXTERNAL (decl)) + && cnode->callers) + return true; + + /* Ignore all references from external vars initializers - they are not really + part of the compilation unit until they are used by folding. Some symbols, + like references to external construction vtables can not be referred to at + all. We decide this at can_refer_decl_in_current_unit_p. */ + if (!definition || DECL_EXTERNAL (decl)) + { + int i; + struct ipa_ref *ref; + for (i = 0; iterate_referring (i, ref); i++) + { + if (ref->use == IPA_REF_ALIAS) + continue; + if (is_a (ref->referring)) + return true; + if (!DECL_EXTERNAL (ref->referring->decl)) + return true; + } + return false; + } + return true; +} Index: gcc/tree-ssa-phiprop.c =================================================================== diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c --- a/gcc/tree-ssa-phiprop.c (revision 257042) +++ b/gcc/tree-ssa-phiprop.c (revision 259627) @@ -270,6 +270,7 @@ use_operand_p arg_p, use; ssa_op_iter i; bool phi_inserted; + bool changed; tree type = NULL_TREE; if (!POINTER_TYPE_P (TREE_TYPE (ptr)) @@ -317,6 +318,7 @@ /* Replace the first dereference of *ptr if there is one and if we can move the loads to the place of the ptr phi node. */ phi_inserted = false; + changed = false; FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr) { gimple *def_stmt; @@ -403,7 +405,7 @@ unlink_stmt_vdef (use_stmt); gsi_remove (&gsi, true); - phi_inserted = true; + changed = true; } /* Found a proper dereference. Insert a phi node if this @@ -424,6 +426,7 @@ gsi_remove (&gsi, true); phi_inserted = true; + changed = true; } else { @@ -431,6 +434,7 @@ load. */ gimple_assign_set_rhs1 (use_stmt, res); update_stmt (use_stmt); + changed = true; } next:; @@ -437,7 +441,7 @@ /* Continue searching for a proper dereference. */ } - return phi_inserted; + return changed; } /* Main entry for phiprop pass. */ Index: gcc/combine.c =================================================================== diff --git a/gcc/combine.c b/gcc/combine.c --- a/gcc/combine.c (revision 257042) +++ b/gcc/combine.c (revision 259627) @@ -11322,8 +11322,15 @@ x = gen_rtx_LSHIFTRT (inner_mode, XEXP (x, 0), GEN_INT (start)); else x = XEXP (x, 0); + if (mode != inner_mode) - x = gen_lowpart_SUBREG (mode, x); + { + if (REG_P (x) && HARD_REGISTER_P (x) + && !can_change_dest_mode (x, 0, mode)) + continue; + + x = gen_lowpart_SUBREG (mode, x); + } } else if (GET_CODE (x) == ZERO_EXTEND && SCALAR_INT_MODE_P (mode) @@ -11335,7 +11342,13 @@ size = GET_MODE_PRECISION (GET_MODE (XEXP (x, 0))); x = SUBREG_REG (XEXP (x, 0)); if (GET_MODE (x) != mode) - x = gen_lowpart_SUBREG (mode, x); + { + if (REG_P (x) && HARD_REGISTER_P (x) + && !can_change_dest_mode (x, 0, mode)) + continue; + + x = gen_lowpart_SUBREG (mode, x); + } } else if (GET_CODE (x) == ZERO_EXTEND && SCALAR_INT_MODE_P (mode) @@ -13081,8 +13094,11 @@ if (REG_P (dest)) { /* If we are setting the whole register, we know its value. Otherwise - show that we don't know the value. We can handle SUBREG in - some cases. */ + show that we don't know the value. We can handle a SUBREG if it's + the low part, but we must be careful with paradoxical SUBREGs on + RISC architectures because we cannot strip e.g. an extension around + a load and record the naked load since the RTL middle-end considers + that the upper bits are defined according to LOAD_EXTEND_OP. */ if (GET_CODE (setter) == SET && dest == SET_DEST (setter)) record_value_for_reg (dest, record_dead_insn, SET_SRC (setter)); else if (GET_CODE (setter) == SET @@ -13091,8 +13107,11 @@ && GET_MODE_PRECISION (GET_MODE (dest)) <= BITS_PER_WORD && subreg_lowpart_p (SET_DEST (setter))) record_value_for_reg (dest, record_dead_insn, - gen_lowpart (GET_MODE (dest), - SET_SRC (setter))); + WORD_REGISTER_OPERATIONS + && paradoxical_subreg_p (SET_DEST (setter)) + ? SET_SRC (setter) + : gen_lowpart (GET_MODE (dest), + SET_SRC (setter))); else record_value_for_reg (dest, record_dead_insn, NULL_RTX); } Index: gcc/hsa-gen.c =================================================================== diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c --- a/gcc/hsa-gen.c (revision 257042) +++ b/gcc/hsa-gen.c (revision 259627) @@ -917,9 +917,13 @@ else if (lookup_attribute ("hsa_group_segment", DECL_ATTRIBUTES (decl))) segment = BRIG_SEGMENT_GROUP; - else if (TREE_STATIC (decl) - || lookup_attribute ("hsa_global_segment", - DECL_ATTRIBUTES (decl))) + else if (TREE_STATIC (decl)) + { + segment = BRIG_SEGMENT_GLOBAL; + allocation = BRIG_ALLOCATION_PROGRAM; + } + else if (lookup_attribute ("hsa_global_segment", + DECL_ATTRIBUTES (decl))) segment = BRIG_SEGMENT_GLOBAL; else segment = BRIG_SEGMENT_PRIVATE; Index: gcc/config.gcc =================================================================== diff --git a/gcc/config.gcc b/gcc/config.gcc --- a/gcc/config.gcc (revision 257042) +++ b/gcc/config.gcc (revision 259627) @@ -1461,7 +1461,7 @@ tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h" ;; x86_64-*-rtems*) - tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h i386/rtemself.h" + tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h i386/rtemself.h rtems.h" ;; i[34567]86-*-rdos*) tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/rdos.h" Index: gcc/config/nvptx/nvptx.c =================================================================== diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c --- a/gcc/config/nvptx/nvptx.c (revision 257042) +++ b/gcc/config/nvptx/nvptx.c (revision 259627) @@ -1875,9 +1875,15 @@ if (sym) { - fprintf (asm_out_file, "generic("); + bool function = (SYMBOL_REF_DECL (sym) + && (TREE_CODE (SYMBOL_REF_DECL (sym)) == FUNCTION_DECL)); + if (!function) + fprintf (asm_out_file, "generic("); output_address (VOIDmode, sym); - fprintf (asm_out_file, val ? ") + " : ")"); + if (!function) + fprintf (asm_out_file, ")"); + if (val) + fprintf (asm_out_file, " + "); } if (!sym || val) @@ -2002,6 +2008,9 @@ nvptx_assemble_decl_begin (FILE *file, const char *name, const char *section, const_tree type, HOST_WIDE_INT size, unsigned align) { + bool atype = (TREE_CODE (type) == ARRAY_TYPE) + && (TYPE_DOMAIN (type) == NULL_TREE); + while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); @@ -2041,6 +2050,8 @@ /* We make everything an array, to simplify any initialization emission. */ fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC "]", init_frag.remaining); + else if (atype) + fprintf (file, "[]"); } /* Called when the initializer for a decl has been completely output through Index: gcc/config/alpha/alpha.md =================================================================== diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md --- a/gcc/config/alpha/alpha.md (revision 257042) +++ b/gcc/config/alpha/alpha.md (revision 259627) @@ -4915,7 +4915,7 @@ ;; Subroutine of stack space allocation. Perform a stack probe. -(define_expand "probe_stack" +(define_expand "stack_probe_internal" [(set (match_dup 1) (match_operand:DI 0 "const_int_operand"))] "" { @@ -4950,12 +4950,14 @@ int probed = 4096; - emit_insn (gen_probe_stack (GEN_INT (- probed))); + emit_insn (gen_stack_probe_internal (GEN_INT (- probed))); while (probed + 8192 < INTVAL (operands[1])) - emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192)))); + emit_insn (gen_stack_probe_internal + (GEN_INT (- (probed += 8192)))); if (probed + 4096 < INTVAL (operands[1])) - emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1])))); + emit_insn (gen_stack_probe_internal + (GEN_INT (- INTVAL(operands[1])))); } operands[1] = GEN_INT (- INTVAL (operands[1])); Index: gcc/config/alpha/alpha.c =================================================================== diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c --- a/gcc/config/alpha/alpha.c (revision 257042) +++ b/gcc/config/alpha/alpha.c (revision 259627) @@ -7750,13 +7750,13 @@ int probed; for (probed = 4096; probed < probed_size; probed += 8192) - emit_insn (gen_probe_stack (GEN_INT (-probed))); + emit_insn (gen_stack_probe_internal (GEN_INT (-probed))); /* We only have to do this probe if we aren't saving registers or if we are probing beyond the frame because of -fstack-check. */ if ((sa_size == 0 && probed_size > probed - 4096) || flag_stack_check) - emit_insn (gen_probe_stack (GEN_INT (-probed_size))); + emit_insn (gen_stack_probe_internal (GEN_INT (-probed_size))); } if (frame_size != 0) Index: gcc/config/s390/s390.md =================================================================== diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md --- a/gcc/config/s390/s390.md (revision 257042) +++ b/gcc/config/s390/s390.md (revision 259627) @@ -89,6 +89,7 @@ UNSPEC_LTREF UNSPEC_INSN UNSPEC_EXECUTE + UNSPEC_EXECUTE_JUMP ; Atomic Support UNSPEC_MB @@ -302,6 +303,8 @@ [ ; Sibling call register. (SIBCALL_REGNUM 1) + ; A call-clobbered reg which can be used in indirect branch thunks + (INDIRECT_BRANCH_THUNK_REGNUM 1) ; Literal pool base register. (BASE_REGNUM 13) ; Return address register. @@ -471,7 +474,10 @@ z196_cracked" (const_string "none")) -(define_attr "mnemonic" "bcr_flush,unknown" (const_string "unknown")) +; mnemonics which only get defined through if_then_else currently +; don't get added to the list values automatically and hence need to +; be listed here. +(define_attr "mnemonic" "b,bas,bc,bcr_flush,unknown" (const_string "unknown")) ;; Length in bytes. @@ -9069,7 +9075,7 @@ (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) (match_operand 0 "address_operand" "ZQZR") (pc)))] - "" + "!TARGET_INDIRECT_BRANCH_NOBP_JUMP" { if (get_attr_op_type (insn) == OP_TYPE_RR) return "b%C1r\t%0"; @@ -9079,6 +9085,9 @@ [(set (attr "op_type") (if_then_else (match_operand 0 "register_operand" "") (const_string "RR") (const_string "RX"))) + (set (attr "mnemonic") + (if_then_else (match_operand 0 "register_operand" "") + (const_string "bcr") (const_string "bc"))) (set_attr "type" "branch") (set_attr "atype" "agen")]) @@ -9090,8 +9099,26 @@ (ANY_RETURN) (pc)))] "s390_can_use__insn ()" - "b%C0r\t%%r14" - [(set_attr "op_type" "RR") +{ + if (TARGET_INDIRECT_BRANCH_NOBP_RET) + { + s390_indirect_branch_via_thunk (RETURN_REGNUM, + INVALID_REGNUM, + operands[0], + s390_indirect_branch_type_return); + return ""; + } + else + return "b%C0r\t%%r14"; +} + [(set (attr "op_type") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET") + (const_string "RIL") + (const_string "RR"))) + (set (attr "mnemonic") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET") + (const_string "brcl") + (const_string "bcr"))) (set_attr "type" "jsr") (set_attr "atype" "agen")]) @@ -9144,7 +9171,7 @@ (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) (pc) (match_operand 0 "address_operand" "ZQZR")))] - "" + "!TARGET_INDIRECT_BRANCH_NOBP_JUMP" { if (get_attr_op_type (insn) == OP_TYPE_RR) return "b%D1r\t%0"; @@ -9154,6 +9181,9 @@ [(set (attr "op_type") (if_then_else (match_operand 0 "register_operand" "") (const_string "RR") (const_string "RX"))) + (set (attr "mnemonic") + (if_then_else (match_operand 0 "register_operand" "") + (const_string "bcr") (const_string "bc"))) (set_attr "type" "branch") (set_attr "atype" "agen")]) @@ -9658,22 +9688,145 @@ ; else operands[0] = force_reg (Pmode, operands[0]); + + if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK) + { + operands[0] = force_reg (Pmode, operands[0]); + if (TARGET_CPU_Z10) + { + if (TARGET_64BIT) + emit_jump_insn (gen_indirect_jump_via_thunkdi_z10 (operands[0])); + else + emit_jump_insn (gen_indirect_jump_via_thunksi_z10 (operands[0])); + } + else + { + if (TARGET_64BIT) + emit_jump_insn (gen_indirect_jump_via_thunkdi (operands[0])); + else + emit_jump_insn (gen_indirect_jump_via_thunksi (operands[0])); + } + DONE; + } + + if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK) + { + operands[0] = force_reg (Pmode, operands[0]); + rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); + if (TARGET_CPU_Z10) + { + if (TARGET_64BIT) + emit_jump_insn (gen_indirect_jump_via_inlinethunkdi_z10 (operands[0], + label_ref)); + else + emit_jump_insn (gen_indirect_jump_via_inlinethunksi_z10 (operands[0], + label_ref)); + } + else + { + if (TARGET_64BIT) + emit_jump_insn (gen_indirect_jump_via_inlinethunkdi (operands[0], + label_ref, + force_reg (Pmode, label_ref))); + else + emit_jump_insn (gen_indirect_jump_via_inlinethunksi (operands[0], + label_ref, + force_reg (Pmode, label_ref))); + } + DONE; + } }) -; The first constraint must be an "extra address constraint" in order -; to trigger address reloading in LRA/reload (define_insn "*indirect_jump" [(set (pc) - (match_operand 0 "address_operand" "ZR,a"))] - "" - "@ - b\t%a0 - br\t%0" - [(set_attr "op_type" "RX,RR") + (match_operand 0 "address_operand" "ZR"))] + "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK" +{ + if (get_attr_op_type (insn) == OP_TYPE_RR) + return "br\t%0"; + else + return "b\t%a0"; +} + [(set (attr "op_type") + (if_then_else (match_operand 0 "register_operand" "") + (const_string "RR") (const_string "RX"))) + (set (attr "mnemonic") + (if_then_else (match_operand 0 "register_operand" "") + (const_string "br") (const_string "b"))) (set_attr "type" "branch") - (set_attr "atype" "agen") - (set_attr "cpu_facility" "*")]) + (set_attr "atype" "agen")]) +(define_insn "indirect_jump_via_thunk_z10" + [(set (pc) + (match_operand:P 0 "register_operand" "a"))] + "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK + && TARGET_CPU_Z10" +{ + s390_indirect_branch_via_thunk (REGNO (operands[0]), + INVALID_REGNUM, + NULL_RTX, + s390_indirect_branch_type_jump); + return ""; +} + [(set_attr "op_type" "RIL") + (set_attr "mnemonic" "jg") + (set_attr "type" "branch") + (set_attr "atype" "agen")]) + +(define_insn "indirect_jump_via_thunk" + [(set (pc) + (match_operand:P 0 "register_operand" " a")) + (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))] + "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK + && !TARGET_CPU_Z10" +{ + s390_indirect_branch_via_thunk (REGNO (operands[0]), + INVALID_REGNUM, + NULL_RTX, + s390_indirect_branch_type_jump); + return ""; +} + [(set_attr "op_type" "RIL") + (set_attr "mnemonic" "jg") + (set_attr "type" "branch") + (set_attr "atype" "agen")]) + + +; The label_ref is wrapped into an if_then_else in order to hide it +; from mark_jump_label. Without this the label_ref would become the +; ONLY jump target of that jump breaking the control flow graph. +(define_insn "indirect_jump_via_inlinethunk_z10" + [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X") + (const_int 0) + (const_int 0)) + (const_int 0)] UNSPEC_EXECUTE_JUMP) + (set (pc) (match_operand:P 0 "register_operand" "a"))] + "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK + && TARGET_CPU_Z10" +{ + s390_indirect_branch_via_inline_thunk (operands[1]); + return ""; +} + [(set_attr "op_type" "RIL") + (set_attr "type" "branch") + (set_attr "length" "10")]) + +(define_insn "indirect_jump_via_inlinethunk" + [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X") + (const_int 0) + (const_int 0)) + (match_operand:P 2 "register_operand" "a")] UNSPEC_EXECUTE_JUMP) + (set (pc) (match_operand:P 0 "register_operand" "a"))] + "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK + && !TARGET_CPU_Z10" +{ + s390_indirect_branch_via_inline_thunk (operands[2]); + return ""; +} + [(set_attr "op_type" "RX") + (set_attr "type" "branch") + (set_attr "length" "8")]) + ; FIXME: LRA does not appear to be able to deal with MEMs being ; checked against address constraints like ZR above. So make this a ; separate pattern for now. @@ -9680,7 +9833,7 @@ (define_insn "*indirect2_jump" [(set (pc) (match_operand 0 "nonimmediate_operand" "a,T"))] - "" + "!TARGET_INDIRECT_BRANCH_NOBP_JUMP" "@ br\t%0 bi\t%0" @@ -9693,11 +9846,74 @@ ; casesi instruction pattern(s). ; -(define_insn "casesi_jump" - [(set (pc) (match_operand 0 "address_operand" "ZR")) - (use (label_ref (match_operand 1 "" "")))] +(define_expand "casesi_jump" + [(parallel + [(set (pc) (match_operand 0 "address_operand")) + (use (label_ref (match_operand 1 "")))])] "" { + if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK) + { + operands[0] = force_reg (GET_MODE (operands[0]), operands[0]); + + if (TARGET_CPU_Z10) + { + if (TARGET_64BIT) + emit_jump_insn (gen_casesi_jump_via_thunkdi_z10 (operands[0], + operands[1])); + else + emit_jump_insn (gen_casesi_jump_via_thunksi_z10 (operands[0], + operands[1])); + } + else + { + if (TARGET_64BIT) + emit_jump_insn (gen_casesi_jump_via_thunkdi (operands[0], + operands[1])); + else + emit_jump_insn (gen_casesi_jump_via_thunksi (operands[0], + operands[1])); + } + DONE; + } + + if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK) + { + operands[0] = force_reg (Pmode, operands[0]); + rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); + if (TARGET_CPU_Z10) + { + if (TARGET_64BIT) + emit_jump_insn (gen_casesi_jump_via_inlinethunkdi_z10 (operands[0], + operands[1], + label_ref)); + else + emit_jump_insn (gen_casesi_jump_via_inlinethunksi_z10 (operands[0], + operands[1], + label_ref)); + } + else + { + if (TARGET_64BIT) + emit_jump_insn (gen_casesi_jump_via_inlinethunkdi (operands[0], + operands[1], + label_ref, + force_reg (Pmode, label_ref))); + else + emit_jump_insn (gen_casesi_jump_via_inlinethunksi (operands[0], + operands[1], + label_ref, + force_reg (Pmode, label_ref))); + } + DONE; + } +}) + +(define_insn "*casesi_jump" + [(set (pc) (match_operand 0 "address_operand" "ZR")) + (use (label_ref (match_operand 1 "" "")))] + "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK" +{ if (get_attr_op_type (insn) == OP_TYPE_RR) return "br\t%0"; else @@ -9706,9 +9922,85 @@ [(set (attr "op_type") (if_then_else (match_operand 0 "register_operand" "") (const_string "RR") (const_string "RX"))) + (set (attr "mnemonic") + (if_then_else (match_operand 0 "register_operand" "") + (const_string "br") (const_string "b"))) (set_attr "type" "branch") (set_attr "atype" "agen")]) +(define_insn "casesi_jump_via_thunk_z10" + [(set (pc) (match_operand:P 0 "register_operand" "a")) + (use (label_ref (match_operand 1 "" "")))] + "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK + && TARGET_CPU_Z10" +{ + s390_indirect_branch_via_thunk (REGNO (operands[0]), + INVALID_REGNUM, + NULL_RTX, + s390_indirect_branch_type_jump); + return ""; +} + [(set_attr "op_type" "RIL") + (set_attr "mnemonic" "jg") + (set_attr "type" "branch") + (set_attr "atype" "agen")]) + +(define_insn "casesi_jump_via_thunk" + [(set (pc) (match_operand:P 0 "register_operand" "a")) + (use (label_ref (match_operand 1 "" ""))) + (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))] + "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK + && !TARGET_CPU_Z10" +{ + s390_indirect_branch_via_thunk (REGNO (operands[0]), + INVALID_REGNUM, + NULL_RTX, + s390_indirect_branch_type_jump); + return ""; +} + [(set_attr "op_type" "RIL") + (set_attr "mnemonic" "jg") + (set_attr "type" "branch") + (set_attr "atype" "agen")]) + + +; The label_ref is wrapped into an if_then_else in order to hide it +; from mark_jump_label. Without this the label_ref would become the +; ONLY jump target of that jump breaking the control flow graph. +(define_insn "casesi_jump_via_inlinethunk_z10" + [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X") + (const_int 0) + (const_int 0)) + (const_int 0)] UNSPEC_EXECUTE_JUMP) + (set (pc) (match_operand:P 0 "register_operand" "a")) + (use (label_ref (match_operand 1 "" "")))] + "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK + && TARGET_CPU_Z10" +{ + s390_indirect_branch_via_inline_thunk (operands[2]); + return ""; +} + [(set_attr "op_type" "RIL") + (set_attr "type" "cs") + (set_attr "length" "10")]) + +(define_insn "casesi_jump_via_inlinethunk" + [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X") + (const_int 0) + (const_int 0)) + (match_operand:P 3 "register_operand" "a")] UNSPEC_EXECUTE_JUMP) + (set (pc) (match_operand:P 0 "register_operand" "a")) + (use (label_ref (match_operand 1 "" "")))] + "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK + && !TARGET_CPU_Z10" +{ + s390_indirect_branch_via_inline_thunk (operands[3]); + return ""; +} + [(set_attr "op_type" "RX") + (set_attr "type" "cs") + (set_attr "length" "8")]) + (define_expand "casesi" [(match_operand:SI 0 "general_operand" "") (match_operand:SI 1 "general_operand" "") @@ -9813,8 +10105,27 @@ (match_operand 0 "const_int_operand" "n"))] "SIBLING_CALL_P (insn) && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode" - "br\t%%r1" - [(set_attr "op_type" "RR") +{ + if (TARGET_INDIRECT_BRANCH_NOBP_CALL) + { + gcc_assert (TARGET_CPU_Z10); + s390_indirect_branch_via_thunk (SIBCALL_REGNUM, + INVALID_REGNUM, + NULL_RTX, + s390_indirect_branch_type_call); + return ""; + } + else + return "br\t%%r1"; +} + [(set (attr "op_type") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL") + (const_string "RIL") + (const_string "RR"))) + (set (attr "mnemonic") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL") + (const_string "jg") + (const_string "br"))) (set_attr "type" "branch") (set_attr "atype" "agen")]) @@ -9854,8 +10165,27 @@ (match_operand 1 "const_int_operand" "n")))] "SIBLING_CALL_P (insn) && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode" - "br\t%%r1" - [(set_attr "op_type" "RR") +{ + if (TARGET_INDIRECT_BRANCH_NOBP_CALL) + { + gcc_assert (TARGET_CPU_Z10); + s390_indirect_branch_via_thunk (SIBCALL_REGNUM, + INVALID_REGNUM, + NULL_RTX, + s390_indirect_branch_type_call); + return ""; + } + else + return "br\t%%r1"; +} + [(set (attr "op_type") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL") + (const_string "RIL") + (const_string "RR"))) + (set (attr "mnemonic") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL") + (const_string "jg") + (const_string "br"))) (set_attr "type" "branch") (set_attr "atype" "agen")]) @@ -9921,7 +10251,9 @@ [(call (mem:QI (match_operand 0 "address_operand" "ZR")) (match_operand 1 "const_int_operand" "n")) (clobber (match_operand 2 "register_operand" "=r"))] - "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode" + "!TARGET_INDIRECT_BRANCH_NOBP_CALL + && !SIBLING_CALL_P (insn) + && GET_MODE (operands[2]) == Pmode" { if (get_attr_op_type (insn) == OP_TYPE_RR) return "basr\t%2,%0"; @@ -9931,10 +10263,54 @@ [(set (attr "op_type") (if_then_else (match_operand 0 "register_operand" "") (const_string "RR") (const_string "RX"))) + (set (attr "mnemonic") + (if_then_else (match_operand 0 "register_operand" "") + (const_string "basr") (const_string "bas"))) (set_attr "type" "jsr") (set_attr "atype" "agen") (set_attr "z196prop" "z196_cracked")]) +(define_insn "*basr_via_thunk_z10" + [(call (mem:QI (match_operand:P 0 "register_operand" "a")) + (match_operand 1 "const_int_operand" "n")) + (clobber (match_operand:P 2 "register_operand" "=&r"))] + "TARGET_INDIRECT_BRANCH_NOBP_CALL + && TARGET_CPU_Z10 + && !SIBLING_CALL_P (insn)" +{ + s390_indirect_branch_via_thunk (REGNO (operands[0]), + REGNO (operands[2]), + NULL_RTX, + s390_indirect_branch_type_call); + return ""; +} + [(set_attr "op_type" "RIL") + (set_attr "mnemonic" "brasl") + (set_attr "type" "jsr") + (set_attr "atype" "agen") + (set_attr "z196prop" "z196_cracked")]) + +(define_insn "*basr_via_thunk" + [(call (mem:QI (match_operand:P 0 "register_operand" "a")) + (match_operand 1 "const_int_operand" "n")) + (clobber (match_operand:P 2 "register_operand" "=&r")) + (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))] + "TARGET_INDIRECT_BRANCH_NOBP_CALL + && !TARGET_CPU_Z10 + && !SIBLING_CALL_P (insn)" +{ + s390_indirect_branch_via_thunk (REGNO (operands[0]), + REGNO (operands[2]), + NULL_RTX, + s390_indirect_branch_type_call); + return ""; +} + [(set_attr "op_type" "RIL") + (set_attr "mnemonic" "brasl") + (set_attr "type" "jsr") + (set_attr "atype" "agen") + (set_attr "z196prop" "z196_cracked")]) + ; ; call_value instruction pattern(s). ; @@ -9982,7 +10358,9 @@ (call (mem:QI (match_operand 1 "address_operand" "ZR")) (match_operand 2 "const_int_operand" "n"))) (clobber (match_operand 3 "register_operand" "=r"))] - "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode" + "!TARGET_INDIRECT_BRANCH_NOBP_CALL + && !SIBLING_CALL_P (insn) + && GET_MODE (operands[3]) == Pmode" { if (get_attr_op_type (insn) == OP_TYPE_RR) return "basr\t%3,%1"; @@ -9992,10 +10370,58 @@ [(set (attr "op_type") (if_then_else (match_operand 1 "register_operand" "") (const_string "RR") (const_string "RX"))) + (set (attr "mnemonic") + (if_then_else (match_operand 1 "register_operand" "") + (const_string "basr") (const_string "bas"))) (set_attr "type" "jsr") (set_attr "atype" "agen") (set_attr "z196prop" "z196_cracked")]) +(define_insn "*basr_r_via_thunk_z10" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand 1 "register_operand" "a")) + (match_operand 2 "const_int_operand" "n"))) + (clobber (match_operand 3 "register_operand" "=&r"))] + "TARGET_INDIRECT_BRANCH_NOBP_CALL + && TARGET_CPU_Z10 + && !SIBLING_CALL_P (insn) + && GET_MODE (operands[3]) == Pmode" +{ + s390_indirect_branch_via_thunk (REGNO (operands[1]), + REGNO (operands[3]), + NULL_RTX, + s390_indirect_branch_type_call); + return ""; +} + [(set_attr "op_type" "RIL") + (set_attr "mnemonic" "brasl") + (set_attr "type" "jsr") + (set_attr "atype" "agen") + (set_attr "z196prop" "z196_cracked")]) + +(define_insn "*basr_r_via_thunk" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand 1 "register_operand" "a")) + (match_operand 2 "const_int_operand" "n"))) + (clobber (match_operand 3 "register_operand" "=&r")) + (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))] + "TARGET_INDIRECT_BRANCH_NOBP_CALL + && !TARGET_CPU_Z10 + && !SIBLING_CALL_P (insn) + && GET_MODE (operands[3]) == Pmode" +{ + s390_indirect_branch_via_thunk (REGNO (operands[1]), + REGNO (operands[3]), + NULL_RTX, + s390_indirect_branch_type_call); + return ""; +} + [(set_attr "op_type" "RIL") + (set_attr "mnemonic" "brasl") + (set_attr "type" "jsr") + (set_attr "atype" "agen") + (set_attr "z196prop" "z196_cracked")]) + ;; ;;- Thread-local storage support. ;; @@ -10737,21 +11163,105 @@ (define_insn "" [(ANY_RETURN)] "s390_can_use__insn ()" - "br\t%%r14" - [(set_attr "op_type" "RR") +{ + if (TARGET_INDIRECT_BRANCH_NOBP_RET) + { + /* The target is always r14 so there is no clobber + of r1 needed for pre z10 targets. */ + s390_indirect_branch_via_thunk (RETURN_REGNUM, + INVALID_REGNUM, + NULL_RTX, + s390_indirect_branch_type_return); + return ""; + } + else + return "br\t%%r14"; +} + [(set (attr "op_type") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET") + (const_string "RIL") + (const_string "RR"))) + (set (attr "mnemonic") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET") + (const_string "jg") + (const_string "br"))) (set_attr "type" "jsr") (set_attr "atype" "agen")]) -(define_insn "*return" + +(define_expand "return_use" + [(parallel + [(return) + (use (match_operand 0 "register_operand" "a"))])] + "" +{ + if (!TARGET_CPU_Z10 + && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION) + { + if (TARGET_64BIT) + emit_jump_insn (gen_returndi_prez10 (operands[0])); + else + emit_jump_insn (gen_returnsi_prez10 (operands[0])); + DONE; + } +}) + +(define_insn "*return" [(return) - (use (match_operand 0 "register_operand" "a"))] - "GET_MODE (operands[0]) == Pmode" - "br\t%0" - [(set_attr "op_type" "RR") + (use (match_operand:P 0 "register_operand" "a"))] + "TARGET_CPU_Z10 || !TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION" +{ + if (TARGET_INDIRECT_BRANCH_NOBP_RET) + { + s390_indirect_branch_via_thunk (REGNO (operands[0]), + INVALID_REGNUM, + NULL_RTX, + s390_indirect_branch_type_return); + return ""; + } + else + return "br\t%0"; +} + [(set (attr "op_type") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET") + (const_string "RIL") + (const_string "RR"))) + (set (attr "mnemonic") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET") + (const_string "jg") + (const_string "br"))) (set_attr "type" "jsr") (set_attr "atype" "agen")]) +(define_insn "return_prez10" + [(return) + (use (match_operand:P 0 "register_operand" "a")) + (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))] + "!TARGET_CPU_Z10 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION" +{ + if (TARGET_INDIRECT_BRANCH_NOBP_RET) + { + s390_indirect_branch_via_thunk (REGNO (operands[0]), + INVALID_REGNUM, + NULL_RTX, + s390_indirect_branch_type_return); + return ""; + } + else + return "br\t%0"; +} + [(set (attr "op_type") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET") + (const_string "RIL") + (const_string "RR"))) + (set (attr "mnemonic") + (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET") + (const_string "jg") + (const_string "br"))) + (set_attr "type" "jsr") + (set_attr "atype" "agen")]) + ;; Instruction definition to extend a 31-bit pointer into a 64-bit ;; pointer. This is used for compatibility. Index: gcc/config/s390/s390.opt =================================================================== diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt --- a/gcc/config/s390/s390.opt (revision 257042) +++ b/gcc/config/s390/s390.opt (revision 259627) @@ -229,3 +229,62 @@ mlra Target Report Var(s390_lra_flag) Init(1) Save Use LRA instead of reload. + +mindirect-branch= +Target Report RejectNegative Joined Enum(indirect_branch) Var(s390_indirect_branch) Init(indirect_branch_keep) +Wrap all indirect branches into execute in order to disable branch +prediction. + +mindirect-branch-jump= +Target Report RejectNegative Joined Enum(indirect_branch) Var(s390_indirect_branch_jump) Init(indirect_branch_keep) +Wrap indirect table jumps and computed gotos into execute in order to +disable branch prediction. Using thunk or thunk-extern with this +option requires the thunks to be considered signal handlers to order to +generate correct CFI. For environments where unwinding (e.g. for +exceptions) is required please use thunk-inline instead. + +mindirect-branch-call= +Target Report RejectNegative Joined Enum(indirect_branch) Var(s390_indirect_branch_call) Init(indirect_branch_keep) +Wrap all indirect calls into execute in order to disable branch prediction. + +mfunction-return= +Target Report RejectNegative Joined Enum(indirect_branch) Var(s390_function_return) Init(indirect_branch_keep) +Wrap all indirect return branches into execute in order to disable branch +prediction. + +mfunction-return-mem= +Target Report RejectNegative Joined Enum(indirect_branch) Var(s390_function_return_mem) Init(indirect_branch_keep) +Wrap indirect return branches into execute in order to disable branch +prediction. This affects only branches where the return address is +going to be restored from memory. + +mfunction-return-reg= +Target Report RejectNegative Joined Enum(indirect_branch) Var(s390_function_return_reg) Init(indirect_branch_keep) +Wrap indirect return branches into execute in order to disable branch +prediction. This affects only branches where the return address +doesn't need to be restored from memory. + +Enum +Name(indirect_branch) Type(enum indirect_branch) +Known indirect branch choices (for use with the -mindirect-branch=/-mfunction-return= options): + +EnumValue +Enum(indirect_branch) String(keep) Value(indirect_branch_keep) + +EnumValue +Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk) + +EnumValue +Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) + +EnumValue +Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) + +mindirect-branch-table +Target Report Var(s390_indirect_branch_table) Init(TARGET_DEFAULT_INDIRECT_BRANCH_TABLE) +Generate sections .s390_indirect_jump, .s390_indirect_call, +.s390_return_reg, and .s390_return_mem to contain the indirect branch +locations which have been patched as part of using one of the +-mindirect-branch* or -mfunction-return* options. The sections +consist of an array of 32 bit elements. Each entry holds the offset +from the entry to the patched location. Index: gcc/config/s390/s390-opts.h =================================================================== diff --git a/gcc/config/s390/s390-opts.h b/gcc/config/s390/s390-opts.h --- a/gcc/config/s390/s390-opts.h (revision 257042) +++ b/gcc/config/s390/s390-opts.h (revision 259627) @@ -43,4 +43,13 @@ PROCESSOR_max }; + +/* Values for -mindirect-branch and -mfunction-return options. */ +enum indirect_branch { + indirect_branch_unset = 0, + indirect_branch_keep, + indirect_branch_thunk, + indirect_branch_thunk_inline, + indirect_branch_thunk_extern +}; #endif Index: gcc/config/s390/s390-protos.h =================================================================== diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h --- a/gcc/config/s390/s390-protos.h (revision 257042) +++ b/gcc/config/s390/s390-protos.h (revision 259627) @@ -53,6 +53,7 @@ extern int s390_cannot_change_mode_class (machine_mode, machine_mode, enum reg_class); extern bool s390_function_arg_vector (machine_mode, const_tree); +extern bool s390_return_addr_from_memory(void); #if S390_USE_TARGET_ATTRIBUTE extern tree s390_valid_target_attribute_tree (tree args, struct gcc_options *opts, @@ -147,6 +148,17 @@ extern bool s390_extzv_shift_ok (int, int, unsigned HOST_WIDE_INT); extern void s390_asm_output_function_label (FILE *, const char *, tree); +enum s390_indirect_branch_type + { + s390_indirect_branch_type_jump = 0, + s390_indirect_branch_type_call, + s390_indirect_branch_type_return + }; +extern void s390_indirect_branch_via_thunk (unsigned int regno, + unsigned int return_addr_regno, + rtx comparison_operator, + enum s390_indirect_branch_type type); +extern void s390_indirect_branch_via_inline_thunk (rtx execute_target); #endif /* RTX_CODE */ /* s390-c.c routines */ Index: gcc/config/s390/s390.c =================================================================== diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c --- a/gcc/config/s390/s390.c (revision 257042) +++ b/gcc/config/s390/s390.c (revision 259627) @@ -377,84 +377,6 @@ bool literal_pool; }; -/* The following structure is embedded in the machine - specific part of struct function. */ - -struct GTY (()) s390_frame_layout -{ - /* Offset within stack frame. */ - HOST_WIDE_INT gprs_offset; - HOST_WIDE_INT f0_offset; - HOST_WIDE_INT f4_offset; - HOST_WIDE_INT f8_offset; - HOST_WIDE_INT backchain_offset; - - /* Number of first and last gpr where slots in the register - save area are reserved for. */ - int first_save_gpr_slot; - int last_save_gpr_slot; - - /* Location (FP register number) where GPRs (r0-r15) should - be saved to. - 0 - does not need to be saved at all - -1 - stack slot */ -#define SAVE_SLOT_NONE 0 -#define SAVE_SLOT_STACK -1 - signed char gpr_save_slots[16]; - - /* Number of first and last gpr to be saved, restored. */ - int first_save_gpr; - int first_restore_gpr; - int last_save_gpr; - int last_restore_gpr; - - /* Bits standing for floating point registers. Set, if the - respective register has to be saved. Starting with reg 16 (f0) - at the rightmost bit. - Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - fpr 15 13 11 9 14 12 10 8 7 5 3 1 6 4 2 0 - reg 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */ - unsigned int fpr_bitmap; - - /* Number of floating point registers f8-f15 which must be saved. */ - int high_fprs; - - /* Set if return address needs to be saved. - This flag is set by s390_return_addr_rtx if it could not use - the initial value of r14 and therefore depends on r14 saved - to the stack. */ - bool save_return_addr_p; - - /* Size of stack frame. */ - HOST_WIDE_INT frame_size; -}; - -/* Define the structure for the machine field in struct function. */ - -struct GTY(()) machine_function -{ - struct s390_frame_layout frame_layout; - - /* Literal pool base register. */ - rtx base_reg; - - /* True if we may need to perform branch splitting. */ - bool split_branches_pending_p; - - bool has_landing_pad_p; - - /* True if the current function may contain a tbegin clobbering - FPRs. */ - bool tbegin_p; - - /* For -fsplit-stack support: A stack local which holds a pointer to - the stack arguments for a function with a variable number of - arguments. This is set at the start of the function and is used - to initialize the overflow_arg_area field of the va_list - structure. */ - rtx split_stack_varargs_pointer; -}; - /* Few accessor macros for struct cfun->machine->s390_frame_layout. */ #define cfun_frame_layout (cfun->machine->frame_layout) @@ -495,7 +417,34 @@ bytes on a z10 (or higher) CPU. */ #define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048) +/* Masks per jump target register indicating which thunk need to be + generated. */ +static GTY(()) int indirect_branch_prez10thunk_mask = 0; +static GTY(()) int indirect_branch_z10thunk_mask = 0; +#define INDIRECT_BRANCH_NUM_OPTIONS 4 + +enum s390_indirect_branch_option + { + s390_opt_indirect_branch_jump = 0, + s390_opt_indirect_branch_call, + s390_opt_function_return_reg, + s390_opt_function_return_mem + }; + +static GTY(()) int indirect_branch_table_label_no[INDIRECT_BRANCH_NUM_OPTIONS] = { 0 }; +const char *indirect_branch_table_label[INDIRECT_BRANCH_NUM_OPTIONS] = \ + { "LJUMP", "LCALL", "LRETREG", "LRETMEM" }; +const char *indirect_branch_table_name[INDIRECT_BRANCH_NUM_OPTIONS] = \ + { ".s390_indirect_jump", ".s390_indirect_call", + ".s390_return_reg", ".s390_return_mem" }; + +bool +s390_return_addr_from_memory () +{ + return cfun_gpr_save_slot(RETURN_REGNUM) == SAVE_SLOT_STACK; +} + /* Indicate which ABI has been used for passing vector args. 0 - no vector type arguments have been passed where the ABI is relevant 1 - the old ABI has been used @@ -1148,9 +1097,83 @@ return NULL_TREE; } +/* Check syntax of function decl attributes having a string type value. */ + +static tree +s390_handle_string_attribute (tree *node, tree name ATTRIBUTE_UNUSED, + tree args ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, + bool *no_add_attrs) +{ + tree cst; + + if (TREE_CODE (*node) != FUNCTION_DECL) + { + warning (OPT_Wattributes, "%qE attribute only applies to functions", + name); + *no_add_attrs = true; + } + + cst = TREE_VALUE (args); + + if (TREE_CODE (cst) != STRING_CST) + { + warning (OPT_Wattributes, + "%qE attribute requires a string constant argument", + name); + *no_add_attrs = true; + } + + if (is_attribute_p ("indirect_branch", name) + || is_attribute_p ("indirect_branch_call", name) + || is_attribute_p ("function_return", name) + || is_attribute_p ("function_return_reg", name) + || is_attribute_p ("function_return_mem", name)) + { + if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0 + && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0 + && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0) + { + warning (OPT_Wattributes, + "argument to %qE attribute is not " + "(keep|thunk|thunk-extern)", name); + *no_add_attrs = true; + } + } + + if (is_attribute_p ("indirect_branch_jump", name) + && strcmp (TREE_STRING_POINTER (cst), "keep") != 0 + && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0 + && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0 + && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0) + { + warning (OPT_Wattributes, + "argument to %qE attribute is not " + "(keep|thunk|thunk-inline|thunk-extern)", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + static const struct attribute_spec s390_attribute_table[] = { - { "hotpatch", 2, 2, true, false, false, s390_handle_hotpatch_attribute, false }, - { "s390_vector_bool", 0, 0, false, true, false, s390_handle_vectorbool_attribute, true }, + { "hotpatch", 2, 2, true, false, false, + s390_handle_hotpatch_attribute, false }, + { "s390_vector_bool", 0, 0, false, true, false, + s390_handle_vectorbool_attribute, true }, + { "indirect_branch", 1, 1, true, false, false, + s390_handle_string_attribute, false }, + { "indirect_branch_jump", 1, 1, true, false, false, + s390_handle_string_attribute, false }, + { "indirect_branch_call", 1, 1, true, false, false, + s390_handle_string_attribute, false }, + { "function_return", 1, 1, true, false, false, + s390_handle_string_attribute, false }, + { "function_return_reg", 1, 1, true, false, false, + s390_handle_string_attribute, false }, + { "function_return_mem", 1, 1, true, false, false, + s390_handle_string_attribute, false }, + /* End element. */ { NULL, 0, 0, false, false, false, NULL, false } }; @@ -8583,11 +8606,25 @@ static rtx s390_execute_label (rtx insn) { - if (NONJUMP_INSN_P (insn) + if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == PARALLEL && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC - && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE) - return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2); + && (XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE + || XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE_JUMP)) + { + if (XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE) + return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2); + else + { + gcc_assert (JUMP_P (insn)); + /* For jump insns as execute target: + - There is one operand less in the parallel (the + modification register of the execute is always 0). + - The execute target label is wrapped into an + if_then_else in order to hide it from jump analysis. */ + return XEXP (XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 0), 0); + } + } return NULL_RTX; } @@ -11273,7 +11310,6 @@ rtx frame_pointer, return_reg, cfa_restores = NULL_RTX; int area_bottom, area_top, offset = 0; int next_offset; - rtvec p; int i; if (TARGET_TPF_PROFILING) @@ -11427,10 +11463,15 @@ if (cfun_gpr_save_slot (RETURN_REGNUM) == SAVE_SLOT_STACK) { int return_regnum = find_unused_clobbered_reg(); - if (!return_regnum) - return_regnum = 4; + if (!return_regnum + || (TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION + && !TARGET_CPU_Z10 + && return_regnum == INDIRECT_BRANCH_THUNK_REGNUM)) + { + gcc_assert (INDIRECT_BRANCH_THUNK_REGNUM != 4); + return_regnum = 4; + } return_reg = gen_rtx_REG (Pmode, return_regnum); - addr = plus_constant (Pmode, frame_pointer, offset + cfun_frame_layout.gprs_offset + (RETURN_REGNUM @@ -11466,16 +11507,7 @@ s390_restore_gprs_from_fprs (); if (! sibcall) - { - - /* Return to caller. */ - - p = rtvec_alloc (2); - - RTVEC_ELT (p, 0) = ret_rtx; - RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg); - emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p)); - } + emit_jump_insn (gen_return_use (return_reg)); } /* Implement TARGET_SET_UP_BY_PROLOGUE. */ @@ -13053,6 +13085,112 @@ final_end_function (); } +/* Output either an indirect jump or a an indirect call + (RETURN_ADDR_REGNO != INVALID_REGNUM) with target register REGNO + using a branch trampoline disabling branch target prediction. */ + +void +s390_indirect_branch_via_thunk (unsigned int regno, + unsigned int return_addr_regno, + rtx comparison_operator, + enum s390_indirect_branch_type type) +{ + enum s390_indirect_branch_option option; + + if (type == s390_indirect_branch_type_return) + { + if (s390_return_addr_from_memory ()) + option = s390_opt_function_return_mem; + else + option = s390_opt_function_return_reg; + } + else if (type == s390_indirect_branch_type_jump) + option = s390_opt_indirect_branch_jump; + else if (type == s390_indirect_branch_type_call) + option = s390_opt_indirect_branch_call; + else + gcc_unreachable (); + + if (TARGET_INDIRECT_BRANCH_TABLE) + { + char label[32]; + + ASM_GENERATE_INTERNAL_LABEL (label, + indirect_branch_table_label[option], + indirect_branch_table_label_no[option]++); + ASM_OUTPUT_LABEL (asm_out_file, label); + } + + if (return_addr_regno != INVALID_REGNUM) + { + gcc_assert (comparison_operator == NULL_RTX); + fprintf (asm_out_file, " \tbrasl\t%%r%d,", return_addr_regno); + } + else + { + fputs (" \tjg", asm_out_file); + if (comparison_operator != NULL_RTX) + print_operand (asm_out_file, comparison_operator, 'C'); + + fputs ("\t", asm_out_file); + } + + if (TARGET_CPU_Z10) + fprintf (asm_out_file, + TARGET_INDIRECT_BRANCH_THUNK_NAME_EXRL "\n", + regno); + else + fprintf (asm_out_file, + TARGET_INDIRECT_BRANCH_THUNK_NAME_EX "\n", + INDIRECT_BRANCH_THUNK_REGNUM, regno); + + if ((option == s390_opt_indirect_branch_jump + && cfun->machine->indirect_branch_jump == indirect_branch_thunk) + || (option == s390_opt_indirect_branch_call + && cfun->machine->indirect_branch_call == indirect_branch_thunk) + || (option == s390_opt_function_return_reg + && cfun->machine->function_return_reg == indirect_branch_thunk) + || (option == s390_opt_function_return_mem + && cfun->machine->function_return_mem == indirect_branch_thunk)) + { + if (TARGET_CPU_Z10) + indirect_branch_z10thunk_mask |= (1 << regno); + else + indirect_branch_prez10thunk_mask |= (1 << regno); + } +} + +/* Output an inline thunk for indirect jumps. EXECUTE_TARGET can + either be an address register or a label pointing to the location + of the jump instruction. */ + +void +s390_indirect_branch_via_inline_thunk (rtx execute_target) +{ + if (TARGET_INDIRECT_BRANCH_TABLE) + { + char label[32]; + + ASM_GENERATE_INTERNAL_LABEL (label, + indirect_branch_table_label[s390_opt_indirect_branch_jump], + indirect_branch_table_label_no[s390_opt_indirect_branch_jump]++); + ASM_OUTPUT_LABEL (asm_out_file, label); + } + + if (!TARGET_ZARCH) + fputs ("\t.machinemode zarch\n", asm_out_file); + + if (REG_P (execute_target)) + fprintf (asm_out_file, "\tex\t%%r0,0(%%r%d)\n", REGNO (execute_target)); + else + output_asm_insn ("exrl\t%%r0,%0", &execute_target); + + if (!TARGET_ZARCH) + fputs ("\t.machinemode esa\n", asm_out_file); + + fputs ("0:\tj\t0b\n", asm_out_file); +} + static bool s390_valid_pointer_mode (machine_mode mode) { @@ -13158,6 +13296,14 @@ if (!TARGET_64BIT && flag_pic && decl && !targetm.binds_local_p (decl)) return false; + /* The thunks for indirect branches require r1 if no exrl is + available. r1 might not be available when doing a sibling + call. */ + if (TARGET_INDIRECT_BRANCH_NOBP_CALL + && !TARGET_CPU_Z10 + && !decl) + return false; + /* Register 6 on s390 is available as an argument register but unfortunately "caller saved". This makes functions needing this register for arguments not suitable for sibcalls. */ @@ -13191,9 +13337,13 @@ { bool plt_call = false; rtx_insn *insn; - rtx call; - rtx clobber; - rtvec vec; + rtx vec[4] = { NULL_RTX }; + int elts = 0; + rtx *call = &vec[0]; + rtx *clobber_ret_reg = &vec[1]; + rtx *use = &vec[2]; + rtx *clobber_thunk_reg = &vec[3]; + int i; /* Direct function calls need special treatment. */ if (GET_CODE (addr_location) == SYMBOL_REF) @@ -13245,26 +13395,58 @@ addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM); } + if (TARGET_INDIRECT_BRANCH_NOBP_CALL + && GET_CODE (addr_location) != SYMBOL_REF + && !plt_call) + { + /* Indirect branch thunks require the target to be a single GPR. */ + addr_location = force_reg (Pmode, addr_location); + + /* Without exrl the indirect branch thunks need an additional + register for larl;ex */ + if (!TARGET_CPU_Z10) + { + *clobber_thunk_reg = gen_rtx_REG (Pmode, INDIRECT_BRANCH_THUNK_REGNUM); + *clobber_thunk_reg = gen_rtx_CLOBBER (VOIDmode, *clobber_thunk_reg); + } + } + addr_location = gen_rtx_MEM (QImode, addr_location); - call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx); + *call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx); if (result_reg != NULL_RTX) - call = gen_rtx_SET (result_reg, call); + *call = gen_rtx_SET (result_reg, *call); if (retaddr_reg != NULL_RTX) { - clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg); + *clobber_ret_reg = gen_rtx_CLOBBER (VOIDmode, retaddr_reg); if (tls_call != NULL_RTX) - vec = gen_rtvec (3, call, clobber, - gen_rtx_USE (VOIDmode, tls_call)); - else - vec = gen_rtvec (2, call, clobber); + *use = gen_rtx_USE (VOIDmode, tls_call); + } - call = gen_rtx_PARALLEL (VOIDmode, vec); + + for (i = 0; i < 4; i++) + if (vec[i] != NULL_RTX) + elts++; + + if (elts > 1) + { + rtvec v; + int e = 0; + + v = rtvec_alloc (elts); + for (i = 0; i < 4; i++) + if (vec[i] != NULL_RTX) + { + RTVEC_ELT (v, e) = vec[i]; + e++; + } + + *call = gen_rtx_PARALLEL (VOIDmode, v); } - insn = emit_call_insn (call); + insn = emit_call_insn (*call); /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */ if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX) @@ -14046,7 +14228,16 @@ target = emit_label (XEXP (label, 0)); INSN_ADDRESSES_NEW (target, -1); - target = emit_insn (s390_execute_target (insn)); + if (JUMP_P (insn)) + { + target = emit_jump_insn (s390_execute_target (insn)); + /* This is important in order to keep a table jump + pointing at the jump table label. Only this makes it + being recognized as table jump. */ + JUMP_LABEL (target) = JUMP_LABEL (insn); + } + else + target = emit_insn (s390_execute_target (insn)); INSN_ADDRESSES_NEW (target, -1); } } @@ -14699,6 +14890,42 @@ if (TARGET_64BIT && !TARGET_ZARCH_P (opts->x_target_flags)) error ("64-bit ABI not supported in ESA/390 mode"); + if (opts->x_s390_indirect_branch == indirect_branch_thunk_inline + || opts->x_s390_indirect_branch_call == indirect_branch_thunk_inline + || opts->x_s390_function_return == indirect_branch_thunk_inline + || opts->x_s390_function_return_reg == indirect_branch_thunk_inline + || opts->x_s390_function_return_mem == indirect_branch_thunk_inline) + error ("thunk-inline is only supported with -mindirect-branch-jump"); + + if (opts->x_s390_indirect_branch != indirect_branch_keep) + { + if (!opts_set->x_s390_indirect_branch_call) + opts->x_s390_indirect_branch_call = opts->x_s390_indirect_branch; + + if (!opts_set->x_s390_indirect_branch_jump) + opts->x_s390_indirect_branch_jump = opts->x_s390_indirect_branch; + } + + if (opts->x_s390_function_return != indirect_branch_keep) + { + if (!opts_set->x_s390_function_return_reg) + opts->x_s390_function_return_reg = opts->x_s390_function_return; + + if (!opts_set->x_s390_function_return_mem) + opts->x_s390_function_return_mem = opts->x_s390_function_return; + } + + if (!TARGET_CPU_ZARCH) + { + if (opts->x_s390_indirect_branch_call != indirect_branch_keep + || opts->x_s390_indirect_branch_jump != indirect_branch_keep) + error ("-mindirect-branch* options require -march=z900 or higher"); + if (opts->x_s390_function_return_reg != indirect_branch_keep + || opts->x_s390_function_return_mem != indirect_branch_keep) + error ("-mfunction-return* options require -march=z900 or higher"); + } + + /* Enable hardware transactions if available and not explicitly disabled by user. E.g. with -m31 -march=zEC12 -mzarch */ if (!TARGET_OPT_HTM_P (opts_set->x_target_flags)) @@ -15267,6 +15494,79 @@ return ret; } +/* Set VAL to correct enum value according to the indirect-branch or + function-return attribute in ATTR. */ + +static inline void +s390_indirect_branch_attrvalue (tree attr, enum indirect_branch *val) +{ + const char *str = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))); + if (strcmp (str, "keep") == 0) + *val = indirect_branch_keep; + else if (strcmp (str, "thunk") == 0) + *val = indirect_branch_thunk; + else if (strcmp (str, "thunk-inline") == 0) + *val = indirect_branch_thunk_inline; + else if (strcmp (str, "thunk-extern") == 0) + *val = indirect_branch_thunk_extern; +} + +/* Memorize the setting for -mindirect-branch* and -mfunction-return* + from either the cmdline or the function attributes in + cfun->machine. */ + +static void +s390_indirect_branch_settings (tree fndecl) +{ + tree attr; + + if (!fndecl) + return; + + /* Initialize with the cmdline options and let the attributes + override it. */ + cfun->machine->indirect_branch_jump = s390_indirect_branch_jump; + cfun->machine->indirect_branch_call = s390_indirect_branch_call; + + cfun->machine->function_return_reg = s390_function_return_reg; + cfun->machine->function_return_mem = s390_function_return_mem; + + if ((attr = lookup_attribute ("indirect_branch", + DECL_ATTRIBUTES (fndecl)))) + { + s390_indirect_branch_attrvalue (attr, + &cfun->machine->indirect_branch_jump); + s390_indirect_branch_attrvalue (attr, + &cfun->machine->indirect_branch_call); + } + + if ((attr = lookup_attribute ("indirect_branch_jump", + DECL_ATTRIBUTES (fndecl)))) + s390_indirect_branch_attrvalue (attr, &cfun->machine->indirect_branch_jump); + + if ((attr = lookup_attribute ("indirect_branch_call", + DECL_ATTRIBUTES (fndecl)))) + s390_indirect_branch_attrvalue (attr, &cfun->machine->indirect_branch_call); + + if ((attr = lookup_attribute ("function_return", + DECL_ATTRIBUTES (fndecl)))) + { + s390_indirect_branch_attrvalue (attr, + &cfun->machine->function_return_reg); + s390_indirect_branch_attrvalue (attr, + &cfun->machine->function_return_mem); + } + + if ((attr = lookup_attribute ("function_return_reg", + DECL_ATTRIBUTES (fndecl)))) + s390_indirect_branch_attrvalue (attr, &cfun->machine->function_return_reg); + + if ((attr = lookup_attribute ("function_return_mem", + DECL_ATTRIBUTES (fndecl)))) + s390_indirect_branch_attrvalue (attr, &cfun->machine->function_return_mem); +} + + /* Restore targets globals from NEW_TREE and invalidate s390_previous_fndecl cache. */ @@ -15293,7 +15593,10 @@ several times in the course of compiling a function, and we don't want to slow things down too much or call target_reinit when it isn't safe. */ if (fndecl == s390_previous_fndecl) - return; + { + s390_indirect_branch_settings (fndecl); + return; + } tree old_tree; if (s390_previous_fndecl == NULL_TREE) @@ -15317,6 +15620,8 @@ if (old_tree != new_tree) s390_activate_target_options (new_tree); s390_previous_fndecl = fndecl; + + s390_indirect_branch_settings (fndecl); } #endif @@ -15598,6 +15903,186 @@ return TARGET_64BIT ? HOST_WIDE_INT_1U << 52 : HOST_WIDE_INT_UC (0x20000000); } +#ifdef HAVE_GAS_HIDDEN +# define USE_HIDDEN_LINKONCE 1 +#else +# define USE_HIDDEN_LINKONCE 0 +#endif + +/* Output an indirect branch trampoline for target register REGNO. */ + +static void +s390_output_indirect_thunk_function (unsigned int regno, bool z10_p) +{ + tree decl; + char thunk_label[32]; + int i; + + if (z10_p) + sprintf (thunk_label, TARGET_INDIRECT_BRANCH_THUNK_NAME_EXRL, regno); + else + sprintf (thunk_label, TARGET_INDIRECT_BRANCH_THUNK_NAME_EX, + INDIRECT_BRANCH_THUNK_REGNUM, regno); + + decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, + get_identifier (thunk_label), + build_function_type_list (void_type_node, NULL_TREE)); + DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, + NULL_TREE, void_type_node); + TREE_PUBLIC (decl) = 1; + TREE_STATIC (decl) = 1; + DECL_IGNORED_P (decl) = 1; + + if (USE_HIDDEN_LINKONCE) + { + cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl)); + + targetm.asm_out.unique_section (decl, 0); + switch_to_section (get_named_section (decl, NULL, 0)); + + targetm.asm_out.globalize_label (asm_out_file, thunk_label); + fputs ("\t.hidden\t", asm_out_file); + assemble_name (asm_out_file, thunk_label); + putc ('\n', asm_out_file); + ASM_DECLARE_FUNCTION_NAME (asm_out_file, thunk_label, decl); + } + else + { + switch_to_section (text_section); + ASM_OUTPUT_LABEL (asm_out_file, thunk_label); + } + + DECL_INITIAL (decl) = make_node (BLOCK); + current_function_decl = decl; + allocate_struct_function (decl, false); + init_function_start (decl); + cfun->is_thunk = true; + first_function_block_is_cold = false; + final_start_function (emit_barrier (), asm_out_file, 1); + + /* This makes CFI at least usable for indirect jumps. + + Stopping in the thunk: backtrace will point to the thunk target + is if it was interrupted by a signal. For a call this means that + the call chain will be: caller->callee->thunk */ + if (flag_asynchronous_unwind_tables && flag_dwarf2_cfi_asm) + { + fputs ("\t.cfi_signal_frame\n", asm_out_file); + fprintf (asm_out_file, "\t.cfi_return_column %d\n", regno); + for (i = 0; i < FPR15_REGNUM; i++) + fprintf (asm_out_file, "\t.cfi_same_value %s\n", reg_names[i]); + } + + if (z10_p) + { + /* exrl 0,1f */ + + /* We generate a thunk for z10 compiled code although z10 is + currently not enabled. Tell the assembler to accept the + instruction. */ + if (!TARGET_CPU_Z10) + { + fputs ("\t.machine push\n", asm_out_file); + fputs ("\t.machine z10\n", asm_out_file); + } + /* We use exrl even if -mzarch hasn't been specified on the + command line so we have to tell the assembler to accept + it. */ + if (!TARGET_ZARCH) + fputs ("\t.machinemode zarch\n", asm_out_file); + + fputs ("\texrl\t0,1f\n", asm_out_file); + + if (!TARGET_ZARCH) + fputs ("\t.machinemode esa\n", asm_out_file); + + if (!TARGET_CPU_Z10) + fputs ("\t.machine pop\n", asm_out_file); + } + else if (TARGET_CPU_ZARCH) + { + /* larl %r1,1f */ + fprintf (asm_out_file, "\tlarl\t%%r%d,1f\n", + INDIRECT_BRANCH_THUNK_REGNUM); + + /* ex 0,0(%r1) */ + fprintf (asm_out_file, "\tex\t0,0(%%r%d)\n", + INDIRECT_BRANCH_THUNK_REGNUM); + } + else + gcc_unreachable (); + + /* 0: j 0b */ + fputs ("0:\tj\t0b\n", asm_out_file); + + /* 1: br */ + fprintf (asm_out_file, "1:\tbr\t%%r%d\n", regno); + + final_end_function (); + init_insn_lengths (); + free_after_compilation (cfun); + set_cfun (NULL); + current_function_decl = NULL; +} + +/* Implement the asm.code_end target hook. */ + +static void +s390_code_end (void) +{ + int i; + + for (i = 1; i < 16; i++) + { + if (indirect_branch_z10thunk_mask & (1 << i)) + s390_output_indirect_thunk_function (i, true); + + if (indirect_branch_prez10thunk_mask & (1 << i)) + s390_output_indirect_thunk_function (i, false); + } + + if (TARGET_INDIRECT_BRANCH_TABLE) + { + int o; + int i; + + for (o = 0; o < INDIRECT_BRANCH_NUM_OPTIONS; o++) + { + if (indirect_branch_table_label_no[o] == 0) + continue; + + switch_to_section (get_section (indirect_branch_table_name[o], + 0, + NULL_TREE)); + for (i = 0; i < indirect_branch_table_label_no[o]; i++) + { + char label_start[32]; + + ASM_GENERATE_INTERNAL_LABEL (label_start, + indirect_branch_table_label[o], i); + + fputs ("\t.long\t", asm_out_file); + assemble_name_raw (asm_out_file, label_start); + fputs ("-.\n", asm_out_file); + } + switch_to_section (current_function_section ()); + } + } +} + +/* Implement the TARGET_CASE_VALUES_THRESHOLD target hook. */ + +unsigned int +s390_case_values_threshold (void) +{ + /* Disabling branch prediction for indirect jumps makes jump tables + much more expensive. */ + if (TARGET_INDIRECT_BRANCH_NOBP_JUMP) + return 20; + + return default_case_values_threshold (); +} + /* Initialize GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -15854,6 +16339,12 @@ #undef TARGET_OPTION_RESTORE #define TARGET_OPTION_RESTORE s390_function_specific_restore +#undef TARGET_ASM_CODE_END +#define TARGET_ASM_CODE_END s390_code_end + +#undef TARGET_CASE_VALUES_THRESHOLD +#define TARGET_CASE_VALUES_THRESHOLD s390_case_values_threshold + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-s390.h" Index: gcc/config/s390/s390.h =================================================================== diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h --- a/gcc/config/s390/s390.h (revision 257042) +++ b/gcc/config/s390/s390.h (revision 259627) @@ -1120,4 +1120,124 @@ s390_register_target_pragmas (); \ } while (0) +#ifndef USED_FOR_TARGET +/* The following structure is embedded in the machine + specific part of struct function. */ + +struct GTY (()) s390_frame_layout +{ + /* Offset within stack frame. */ + HOST_WIDE_INT gprs_offset; + HOST_WIDE_INT f0_offset; + HOST_WIDE_INT f4_offset; + HOST_WIDE_INT f8_offset; + HOST_WIDE_INT backchain_offset; + + /* Number of first and last gpr where slots in the register + save area are reserved for. */ + int first_save_gpr_slot; + int last_save_gpr_slot; + + /* Location (FP register number) where GPRs (r0-r15) should + be saved to. + 0 - does not need to be saved at all + -1 - stack slot */ +#define SAVE_SLOT_NONE 0 +#define SAVE_SLOT_STACK -1 + signed char gpr_save_slots[16]; + + /* Number of first and last gpr to be saved, restored. */ + int first_save_gpr; + int first_restore_gpr; + int last_save_gpr; + int last_restore_gpr; + + /* Bits standing for floating point registers. Set, if the + respective register has to be saved. Starting with reg 16 (f0) + at the rightmost bit. + Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + fpr 15 13 11 9 14 12 10 8 7 5 3 1 6 4 2 0 + reg 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */ + unsigned int fpr_bitmap; + + /* Number of floating point registers f8-f15 which must be saved. */ + int high_fprs; + + /* Set if return address needs to be saved. + This flag is set by s390_return_addr_rtx if it could not use + the initial value of r14 and therefore depends on r14 saved + to the stack. */ + bool save_return_addr_p; + + /* Size of stack frame. */ + HOST_WIDE_INT frame_size; +}; + + +/* Define the structure for the machine field in struct function. */ + +struct GTY(()) machine_function +{ + struct s390_frame_layout frame_layout; + + /* Literal pool base register. */ + rtx base_reg; + + /* True if we may need to perform branch splitting. */ + bool split_branches_pending_p; + + bool has_landing_pad_p; + + /* True if the current function may contain a tbegin clobbering + FPRs. */ + bool tbegin_p; + + /* For -fsplit-stack support: A stack local which holds a pointer to + the stack arguments for a function with a variable number of + arguments. This is set at the start of the function and is used + to initialize the overflow_arg_area field of the va_list + structure. */ + rtx split_stack_varargs_pointer; + + enum indirect_branch indirect_branch_jump; + enum indirect_branch indirect_branch_call; + + enum indirect_branch function_return_mem; + enum indirect_branch function_return_reg; +}; +#endif + +#define TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION \ + (cfun->machine->function_return_reg != indirect_branch_keep \ + || cfun->machine->function_return_mem != indirect_branch_keep) + +#define TARGET_INDIRECT_BRANCH_NOBP_RET \ + ((cfun->machine->function_return_reg != indirect_branch_keep \ + && !s390_return_addr_from_memory ()) \ + || (cfun->machine->function_return_mem != indirect_branch_keep \ + && s390_return_addr_from_memory ())) + +#define TARGET_INDIRECT_BRANCH_NOBP_JUMP \ + (cfun->machine->indirect_branch_jump != indirect_branch_keep) + +#define TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK \ + (cfun->machine->indirect_branch_jump == indirect_branch_thunk \ + || cfun->machine->indirect_branch_jump == indirect_branch_thunk_extern) + +#define TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK \ + (cfun->machine->indirect_branch_jump == indirect_branch_thunk_inline) + +#define TARGET_INDIRECT_BRANCH_NOBP_CALL \ + (cfun->machine->indirect_branch_call != indirect_branch_keep) + +#ifndef TARGET_DEFAULT_INDIRECT_BRANCH_TABLE +#define TARGET_DEFAULT_INDIRECT_BRANCH_TABLE 0 +#endif + +#define TARGET_INDIRECT_BRANCH_THUNK_NAME_EXRL "__s390_indirect_jump_r%d" +#define TARGET_INDIRECT_BRANCH_THUNK_NAME_EX "__s390_indirect_jump_r%duse_r%d" + +#define TARGET_INDIRECT_BRANCH_TABLE s390_indirect_branch_table + + #endif /* S390_H */ Index: gcc/config/sparc/sparc.md =================================================================== diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md --- a/gcc/config/sparc/sparc.md (revision 257042) +++ b/gcc/config/sparc/sparc.md (revision 259627) @@ -1758,7 +1758,7 @@ (define_expand "movsi_pic_label_ref" [(set (match_dup 3) (high:SI - (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") + (unspec:SI [(match_operand:SI 1 "symbolic_operand" "") (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) (set (match_dup 4) (lo_sum:SI (match_dup 3) (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) @@ -1784,7 +1784,7 @@ (define_insn "*movsi_high_pic_label_ref" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI - (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") + (unspec:SI [(match_operand:SI 1 "symbolic_operand" "") (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "flag_pic" "sethi\t%%hi(%a2-(%a1-.)), %0") @@ -1792,7 +1792,7 @@ (define_insn "*movsi_lo_sum_pic_label_ref" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") - (unspec:SI [(match_operand:SI 2 "label_ref_operand" "") + (unspec:SI [(match_operand:SI 2 "symbolic_operand" "") (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "flag_pic" "or\t%1, %%lo(%a3-(%a2-.)), %0") @@ -1896,7 +1896,7 @@ (define_expand "movdi_pic_label_ref" [(set (match_dup 3) (high:DI - (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") + (unspec:DI [(match_operand:DI 1 "symbolic_operand" "") (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) (set (match_dup 4) (lo_sum:DI (match_dup 3) (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) @@ -1922,7 +1922,7 @@ (define_insn "*movdi_high_pic_label_ref" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI - (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") + (unspec:DI [(match_operand:DI 1 "symbolic_operand" "") (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "TARGET_ARCH64 && flag_pic" "sethi\t%%hi(%a2-(%a1-.)), %0") @@ -1930,7 +1930,7 @@ (define_insn "*movdi_lo_sum_pic_label_ref" [(set (match_operand:DI 0 "register_operand" "=r") (lo_sum:DI (match_operand:DI 1 "register_operand" "r") - (unspec:DI [(match_operand:DI 2 "label_ref_operand" "") + (unspec:DI [(match_operand:DI 2 "symbolic_operand" "") (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "TARGET_ARCH64 && flag_pic" "or\t%1, %%lo(%a3-(%a2-.)), %0") Index: gcc/config/sparc/sparc.c =================================================================== diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c --- a/gcc/config/sparc/sparc.c (revision 257042) +++ b/gcc/config/sparc/sparc.c (revision 259627) @@ -2188,7 +2188,7 @@ } } - /* Fixup TLS cases. */ + /* Fix up TLS cases. */ if (TARGET_HAVE_TLS && CONSTANT_P (operands[1]) && sparc_tls_referenced_p (operands [1])) @@ -2197,7 +2197,7 @@ return false; } - /* Fixup PIC cases. */ + /* Fix up PIC cases. */ if (flag_pic && CONSTANT_P (operands[1])) { if (pic_address_needs_scratch (operands[1])) @@ -2204,8 +2204,13 @@ operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX); /* We cannot use the mov{si,di}_pic_label_ref patterns in all cases. */ - if (GET_CODE (operands[1]) == LABEL_REF - && can_use_mov_pic_label_ref (operands[1])) + if ((GET_CODE (operands[1]) == LABEL_REF + && can_use_mov_pic_label_ref (operands[1])) + || (GET_CODE (operands[1]) == CONST + && GET_CODE (XEXP (operands[1], 0)) == PLUS + && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF + && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT + && can_use_mov_pic_label_ref (XEXP (XEXP (operands[1], 0), 0)))) { if (mode == SImode) { @@ -2215,7 +2220,6 @@ if (mode == DImode) { - gcc_assert (TARGET_ARCH64); emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1])); return true; } @@ -4216,10 +4220,11 @@ pic_address_needs_scratch (rtx x) { /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */ - if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS + if (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) + && !SMALL_INT (XEXP (XEXP (x, 0), 1))) return 1; return 0; @@ -4667,16 +4672,15 @@ static rtx sparc_legitimize_pic_address (rtx orig, rtx reg) { - bool gotdata_op = false; - if (GET_CODE (orig) == SYMBOL_REF /* See the comment in sparc_expand_move. */ || (GET_CODE (orig) == LABEL_REF && !can_use_mov_pic_label_ref (orig))) { + bool gotdata_op = false; rtx pic_ref, address; rtx_insn *insn; - if (reg == 0) + if (!reg) { gcc_assert (can_create_pseudo_p ()); reg = gen_reg_rtx (Pmode); @@ -4687,8 +4691,7 @@ /* If not during reload, allocate another temp reg here for loading in the address, so that these instructions can be optimized properly. */ - rtx temp_reg = (! can_create_pseudo_p () - ? reg : gen_reg_rtx (Pmode)); + rtx temp_reg = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : reg; /* Must put the SYMBOL_REF inside an UNSPEC here so that cse won't get confused into thinking that these two instructions @@ -4704,6 +4707,7 @@ emit_insn (gen_movsi_high_pic (temp_reg, orig)); emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig)); } + address = temp_reg; gotdata_op = true; } @@ -4744,7 +4748,7 @@ && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) return orig; - if (reg == 0) + if (!reg) { gcc_assert (can_create_pseudo_p ()); reg = gen_reg_rtx (Pmode); @@ -4853,7 +4857,11 @@ && XINT (XEXP (XEXP (x, 1), 1), 1) == UNSPEC_MOVE_PIC_LABEL) { x = XVECEXP (XEXP (XEXP (x, 1), 1), 0, 0); - gcc_assert (GET_CODE (x) == LABEL_REF); + gcc_assert (GET_CODE (x) == LABEL_REF + || (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)); } return x; Index: gcc/config/i386/i386.h =================================================================== diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h --- a/gcc/config/i386/i386.h (revision 257042) +++ b/gcc/config/i386/i386.h (revision 259627) @@ -2719,6 +2719,11 @@ #define TARGET_RECIP_VEC_DIV ((recip_mask & RECIP_MASK_VEC_DIV) != 0) #define TARGET_RECIP_VEC_SQRT ((recip_mask & RECIP_MASK_VEC_SQRT) != 0) + +#define TARGET_INDIRECT_BRANCH_REGISTER \ + (ix86_indirect_branch_register \ + || cfun->machine->indirect_branch_type != indirect_branch_keep) + #define IX86_HLE_ACQUIRE (1 << 16) #define IX86_HLE_RELEASE (1 << 17) Index: gcc/config/i386/i386.md =================================================================== diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md --- a/gcc/config/i386/i386.md (revision 257042) +++ b/gcc/config/i386/i386.md (revision 259627) @@ -739,7 +739,7 @@ (if_then_else (match_operand 1 "constant_call_address_operand") (const_string "none") (const_string "load")) - (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1") + (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1") (match_operand 1 "memory_operand")) (const_string "both") (and (match_operand 0 "memory_operand") @@ -750,7 +750,7 @@ (match_operand 1 "memory_operand") (const_string "load") (and (eq_attr "type" - "!alu1,negnot,ishift1, + "!alu1,negnot,ishift1,rotate1, imov,imovx,icmp,test,bitmanip, fmov,fcmp,fsgn, sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt, @@ -8584,14 +8584,14 @@ }) (define_insn "*andndi3_doubleword" - [(set (match_operand:DI 0 "register_operand" "=r,&r") + [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r") (and:DI - (not:DI (match_operand:DI 1 "register_operand" "r,0")) - (match_operand:DI 2 "nonimmediate_operand" "rm,rm"))) + (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0")) + (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm"))) (clobber (reg:CC FLAGS_REG))] "!TARGET_64BIT && TARGET_STV && TARGET_SSE2" "#" - [(set_attr "isa" "bmi,*")]) + [(set_attr "isa" "bmi,bmi,bmi,*")]) (define_split [(set (match_operand:DI 0 "register_operand") @@ -11625,7 +11625,7 @@ [(set (pc) (match_operand 0 "indirect_branch_operand"))] "" { - if (TARGET_X32 || ix86_indirect_branch_register) + if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) operands[0] = convert_memory_address (word_mode, operands[0]); cfun->machine->has_local_indirect_jump = true; }) @@ -11633,7 +11633,7 @@ (define_insn "*indirect_jump" [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] "" - "* return ix86_output_indirect_jmp (operands[0], false);" + "* return ix86_output_indirect_jmp (operands[0]);" [(set (attr "type") (if_then_else (match_test "(cfun->machine->indirect_branch_type != indirect_branch_keep)") @@ -11679,7 +11679,7 @@ OPTAB_DIRECT); } - if (TARGET_X32 || ix86_indirect_branch_register) + if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) operands[0] = convert_memory_address (word_mode, operands[0]); cfun->machine->has_local_indirect_jump = true; }) @@ -11688,7 +11688,7 @@ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) (use (label_ref (match_operand 1)))] "" - "* return ix86_output_indirect_jmp (operands[0], false);" + "* return ix86_output_indirect_jmp (operands[0]);" [(set (attr "type") (if_then_else (match_test "(cfun->machine->indirect_branch_type != indirect_branch_keep)") @@ -11852,7 +11852,10 @@ (match_operand:SI 0 "register_no_elim_operand" "U") (match_operand:SI 1 "GOT32_symbol_operand")))) (match_operand 2))] - "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)" + "!TARGET_MACHO + && !TARGET_64BIT + && !TARGET_INDIRECT_BRANCH_REGISTER + && SIBLING_CALL_P (insn)" { rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]); fnaddr = gen_const_mem (SImode, fnaddr); @@ -11871,7 +11874,7 @@ [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) (match_operand 1)) (unspec [(const_int 0)] UNSPEC_PEEPSIB)] - "!TARGET_X32 && !ix86_indirect_branch_register" + "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" "* return ix86_output_call_insn (insn, operands[0]);" [(set_attr "type" "call")]) @@ -11881,7 +11884,7 @@ (call (mem:QI (match_dup 0)) (match_operand 3))] "!TARGET_X32 - && !ix86_indirect_branch_register + && !TARGET_INDIRECT_BRANCH_REGISTER && SIBLING_CALL_P (peep2_next_insn (1)) && !reg_mentioned_p (operands[0], CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" @@ -11896,7 +11899,7 @@ (call (mem:QI (match_dup 0)) (match_operand 3))] "!TARGET_X32 - && !ix86_indirect_branch_register + && !TARGET_INDIRECT_BRANCH_REGISTER && SIBLING_CALL_P (peep2_next_insn (2)) && !reg_mentioned_p (operands[0], CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" @@ -11994,7 +11997,7 @@ (match_operand:W 1 "memory_operand")) (set (pc) (match_dup 0))] "!TARGET_X32 - && !ix86_indirect_branch_register + && !TARGET_INDIRECT_BRANCH_REGISTER && peep2_reg_dead_p (2, operands[0])" [(set (pc) (match_dup 1))]) @@ -12055,7 +12058,10 @@ (match_operand:SI 1 "register_no_elim_operand" "U") (match_operand:SI 2 "GOT32_symbol_operand")))) (match_operand 3)))] - "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)" + "!TARGET_MACHO + && !TARGET_64BIT + && !TARGET_INDIRECT_BRANCH_REGISTER + && SIBLING_CALL_P (insn)" { rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]); fnaddr = gen_const_mem (SImode, fnaddr); @@ -12076,7 +12082,7 @@ (call (mem:QI (match_operand:W 1 "memory_operand" "m")) (match_operand 2))) (unspec [(const_int 0)] UNSPEC_PEEPSIB)] - "!TARGET_X32 && !ix86_indirect_branch_register" + "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" "* return ix86_output_call_insn (insn, operands[1]);" [(set_attr "type" "callv")]) @@ -12087,7 +12093,7 @@ (call (mem:QI (match_dup 0)) (match_operand 3)))] "!TARGET_X32 - && !ix86_indirect_branch_register + && !TARGET_INDIRECT_BRANCH_REGISTER && SIBLING_CALL_P (peep2_next_insn (1)) && !reg_mentioned_p (operands[0], CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" @@ -12104,7 +12110,7 @@ (call (mem:QI (match_dup 0)) (match_operand 3)))] "!TARGET_X32 - && !ix86_indirect_branch_register + && !TARGET_INDIRECT_BRANCH_REGISTER && SIBLING_CALL_P (peep2_next_insn (2)) && !reg_mentioned_p (operands[0], CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" @@ -12354,11 +12360,14 @@ (set_attr "prefix_rep" "1") (set_attr "modrm" "0")]) -(define_insn "simple_return_pop_internal" +(define_insn_and_split "simple_return_pop_internal" [(simple_return) (use (match_operand:SI 0 "const_int_operand"))] "reload_completed" "%!ret\t%0" + "&& cfun->machine->function_return_type != indirect_branch_keep" + [(const_int 0)] + "ix86_split_simple_return_pop_internal (operands[0]); DONE;" [(set_attr "length" "3") (set_attr "atom_unit" "jeu") (set_attr "length_immediate" "2") @@ -12369,7 +12378,7 @@ [(simple_return) (use (match_operand:SI 0 "register_operand" "r"))] "reload_completed" - "* return ix86_output_indirect_jmp (operands[0], true);" + "* return ix86_output_indirect_function_return (operands[0]);" [(set (attr "type") (if_then_else (match_test "(cfun->machine->indirect_branch_type != indirect_branch_keep)") Index: gcc/config/i386/constraints.md =================================================================== diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md --- a/gcc/config/i386/constraints.md (revision 257042) +++ b/gcc/config/i386/constraints.md (revision 259627) @@ -198,7 +198,7 @@ (define_constraint "Bs" "@internal Sibcall memory operand." - (ior (and (not (match_test "ix86_indirect_branch_register")) + (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) (not (match_test "TARGET_X32")) (match_operand 0 "sibcall_memory_operand")) (and (match_test "TARGET_X32 && Pmode == DImode") @@ -206,7 +206,7 @@ (define_constraint "Bw" "@internal Call memory operand." - (ior (and (not (match_test "ix86_indirect_branch_register")) + (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) (not (match_test "TARGET_X32")) (match_operand 0 "memory_operand")) (and (match_test "TARGET_X32 && Pmode == DImode") Index: gcc/config/i386/predicates.md =================================================================== diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md --- a/gcc/config/i386/predicates.md (revision 257042) +++ b/gcc/config/i386/predicates.md (revision 259627) @@ -635,7 +635,7 @@ ;; Test for a valid operand for indirect branch. (define_predicate "indirect_branch_operand" (ior (match_operand 0 "register_operand") - (and (not (match_test "ix86_indirect_branch_register")) + (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) (not (match_test "TARGET_X32")) (match_operand 0 "memory_operand")))) @@ -679,7 +679,7 @@ (ior (match_test "constant_call_address_operand (op, mode == VOIDmode ? mode : Pmode)") (match_operand 0 "call_register_no_elim_operand") - (and (not (match_test "ix86_indirect_branch_register")) + (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) (ior (and (not (match_test "TARGET_X32")) (match_operand 0 "memory_operand")) (and (match_test "TARGET_X32 && Pmode == DImode") @@ -690,7 +690,7 @@ (ior (match_test "constant_call_address_operand (op, mode == VOIDmode ? mode : Pmode)") (match_operand 0 "register_no_elim_operand") - (and (not (match_test "ix86_indirect_branch_register")) + (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) (ior (and (not (match_test "TARGET_X32")) (match_operand 0 "sibcall_memory_operand")) (and (match_test "TARGET_X32 && Pmode == DImode") Index: gcc/config/i386/sse.md =================================================================== diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md --- a/gcc/config/i386/sse.md (revision 257042) +++ b/gcc/config/i386/sse.md (revision 259627) @@ -9938,11 +9938,11 @@ && ix86_binary_operator_ok (, mode, operands)" "@ p\t{%2, %0|%0, %2} - vp\t{%2, %1, %0|%0, %1, %2}" + vp\t{%2, %1, %0|%0, %1, %2}" [(set_attr "isa" "noavx,avx") (set_attr "type" "sseiadd") (set_attr "prefix_data16" "1,*") - (set_attr "prefix" "") + (set_attr "prefix" "orig,vex") (set_attr "mode" "")]) (define_insn "*3_mask" @@ -11822,7 +11822,7 @@ (eq_attr "mode" "TI")) (const_string "1") (const_string "*"))) - (set_attr "prefix" "") + (set_attr "prefix" "orig,vex") (set (attr "mode") (cond [(and (match_test " == 16") (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) Index: gcc/config/i386/i386-protos.h =================================================================== diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h --- a/gcc/config/i386/i386-protos.h (revision 257042) +++ b/gcc/config/i386/i386-protos.h (revision 259627) @@ -313,8 +313,10 @@ #endif extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); -extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); +extern const char * ix86_output_indirect_jmp (rtx call_op); extern const char * ix86_output_function_return (bool long_p); +extern const char * ix86_output_indirect_function_return (rtx ret_op); +extern void ix86_split_simple_return_pop_internal (rtx); extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, enum machine_mode mode); Index: gcc/config/i386/avx512vlintrin.h =================================================================== diff --git a/gcc/config/i386/avx512vlintrin.h b/gcc/config/i386/avx512vlintrin.h --- a/gcc/config/i386/avx512vlintrin.h (revision 257042) +++ b/gcc/config/i386/avx512vlintrin.h (revision 259627) @@ -9099,6 +9099,17 @@ extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_permutexvar_epi64 (__m256i __X, __m256i __Y) +{ + return (__m256i) __builtin_ia32_permvardi256_mask ((__v4di) __Y, + (__v4di) __X, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_permutexvar_epi64 (__m256i __W, __mmask8 __M, __m256i __X, __m256i __Y) { @@ -9163,6 +9174,17 @@ extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_permutexvar_epi32 (__m256i __X, __m256i __Y) +{ + return (__m256i) __builtin_ia32_permvarsi256_mask ((__v8si) __Y, + (__v8si) __X, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_permutexvar_epi32 (__m256i __W, __mmask8 __M, __m256i __X, __m256i __Y) { @@ -9751,6 +9773,17 @@ #ifdef __OPTIMIZE__ extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_permutex_epi64 (__m256i __X, const int __I) +{ + return (__m256i) __builtin_ia32_permdi256_mask ((__v4di) __X, + __I, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_permutex_epi64 (__m256i __W, __mmask8 __M, __m256i __X, const int __I) { @@ -12367,6 +12400,13 @@ _mm256_undefined_pd (), \ (__mmask8)-1)) +#define _mm256_permutex_epi64(X, I) \ + ((__m256i) __builtin_ia32_permdi256_mask ((__v4di)(__m256i)(X), \ + (int)(I), \ + (__v4di)(__m256i) \ + (_mm256_setzero_si256 ()),\ + (__mmask8) -1)) + #define _mm256_maskz_permutex_epi64(M, X, I) \ ((__m256i) __builtin_ia32_permdi256_mask ((__v4di)(__m256i)(X), \ (int)(I), \ Index: gcc/config/i386/i386.c =================================================================== diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c --- a/gcc/config/i386/i386.c (revision 257042) +++ b/gcc/config/i386/i386.c (revision 259627) @@ -12031,19 +12031,29 @@ labels in call and return thunks. */ static int indirectlabelno; -/* True if call and return thunk functions are needed. */ +/* True if call thunk function is needed. */ static bool indirect_thunk_needed = false; -/* True if call and return thunk functions with the BND prefix are - needed. */ +/* True if call thunk function with the BND prefix is needed. */ static bool indirect_thunk_bnd_needed = false; /* Bit masks of integer registers, which contain branch target, used - by call and return thunks functions. */ + by call thunk functions. */ static int indirect_thunks_used; /* Bit masks of integer registers, which contain branch target, used - by call and return thunks functions with the BND prefix. */ + by call thunk functions with the BND prefix. */ static int indirect_thunks_bnd_used; +/* True if return thunk function is needed. */ +static bool indirect_return_needed = false; +/* True if return thunk function with the BND prefix is needed. */ +static bool indirect_return_bnd_needed = false; + +/* True if return thunk function via CX is needed. */ +static bool indirect_return_via_cx; +/* True if return thunk function via CX with the BND prefix is + needed. */ +static bool indirect_return_via_cx_bnd; + #ifndef INDIRECT_LABEL # define INDIRECT_LABEL "LIND" #endif @@ -12051,16 +12061,17 @@ /* Fills in the label name that should be used for the indirect thunk. */ static void -indirect_thunk_name (char name[32], int regno, bool need_bnd_p, - bool ret_p) +indirect_thunk_name (char name[32], unsigned int regno, + bool need_bnd_p, bool ret_p) { - if (regno >= 0 && ret_p) + if (regno != INVALID_REGNUM && regno != CX_REG && ret_p) gcc_unreachable (); if (USE_HIDDEN_LINKONCE) { const char *bnd = need_bnd_p ? "_bnd" : ""; - if (regno >= 0) + const char *ret = ret_p ? "return" : "indirect"; + if (regno != INVALID_REGNUM) { const char *reg_prefix; if (LEGACY_INT_REGNO_P (regno)) @@ -12067,18 +12078,15 @@ reg_prefix = TARGET_64BIT ? "r" : "e"; else reg_prefix = ""; - sprintf (name, "__x86_indirect_thunk%s_%s%s", - bnd, reg_prefix, reg_names[regno]); + sprintf (name, "__x86_%s_thunk%s_%s%s", + ret, bnd, reg_prefix, reg_names[regno]); } else - { - const char *ret = ret_p ? "return" : "indirect"; - sprintf (name, "__x86_%s_thunk%s", ret, bnd); - } + sprintf (name, "__x86_%s_thunk%s", ret, bnd); } else { - if (regno >= 0) + if (regno != INVALID_REGNUM) { if (need_bnd_p) ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno); @@ -12130,7 +12138,7 @@ */ static void -output_indirect_thunk (bool need_bnd_p, int regno) +output_indirect_thunk (bool need_bnd_p, unsigned int regno) { char indirectlabel1[32]; char indirectlabel2[32]; @@ -12160,7 +12168,7 @@ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); - if (regno >= 0) + if (regno != INVALID_REGNUM) { /* MOV. */ rtx xops[2]; @@ -12184,18 +12192,20 @@ } /* Output a funtion with a call and return thunk for indirect branch. - If BND_P is true, the BND prefix is needed. If REGNO != -1, the - function address is in REGNO. Otherwise, the function address is - on the top of stack. */ + If BND_P is true, the BND prefix is needed. If REGNO != INVALID_REGNUM, + the function address is in REGNO. Otherwise, the function address is + on the top of stack. Thunk is used for function return if RET_P is + true. */ static void -output_indirect_thunk_function (bool need_bnd_p, int regno) +output_indirect_thunk_function (bool need_bnd_p, unsigned int regno, + bool ret_p) { char name[32]; tree decl; /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */ - indirect_thunk_name (name, regno, need_bnd_p, false); + indirect_thunk_name (name, regno, need_bnd_p, ret_p); decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, get_identifier (name), build_function_type_list (void_type_node, NULL_TREE)); @@ -12238,36 +12248,6 @@ ASM_OUTPUT_LABEL (asm_out_file, name); } - if (regno < 0) - { - /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */ - char alias[32]; - - indirect_thunk_name (alias, regno, need_bnd_p, true); -#if TARGET_MACHO - if (TARGET_MACHO) - { - fputs ("\t.weak_definition\t", asm_out_file); - assemble_name (asm_out_file, alias); - fputs ("\n\t.private_extern\t", asm_out_file); - assemble_name (asm_out_file, alias); - putc ('\n', asm_out_file); - ASM_OUTPUT_LABEL (asm_out_file, alias); - } -#else - ASM_OUTPUT_DEF (asm_out_file, alias, name); - if (USE_HIDDEN_LINKONCE) - { - fputs ("\t.globl\t", asm_out_file); - assemble_name (asm_out_file, alias); - putc ('\n', asm_out_file); - fputs ("\t.hidden\t", asm_out_file); - assemble_name (asm_out_file, alias); - putc ('\n', asm_out_file); - } -#endif - } - DECL_INITIAL (decl) = make_node (BLOCK); current_function_decl = decl; allocate_struct_function (decl, false); @@ -12312,21 +12292,31 @@ ix86_code_end (void) { rtx xops[2]; - int regno; + unsigned int regno; + if (indirect_return_needed) + output_indirect_thunk_function (false, INVALID_REGNUM, true); + if (indirect_return_bnd_needed) + output_indirect_thunk_function (true, INVALID_REGNUM, true); + + if (indirect_return_via_cx) + output_indirect_thunk_function (false, CX_REG, true); + if (indirect_return_via_cx_bnd) + output_indirect_thunk_function (true, CX_REG, true); + if (indirect_thunk_needed) - output_indirect_thunk_function (false, -1); + output_indirect_thunk_function (false, INVALID_REGNUM, false); if (indirect_thunk_bnd_needed) - output_indirect_thunk_function (true, -1); + output_indirect_thunk_function (true, INVALID_REGNUM, false); for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++) { - int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; + unsigned int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; if ((indirect_thunks_used & (1 << i))) - output_indirect_thunk_function (false, regno); + output_indirect_thunk_function (false, regno, false); if ((indirect_thunks_bnd_used & (1 << i))) - output_indirect_thunk_function (true, regno); + output_indirect_thunk_function (true, regno, false); } for (regno = AX_REG; regno <= SP_REG; regno++) @@ -12335,10 +12325,10 @@ tree decl; if ((indirect_thunks_used & (1 << regno))) - output_indirect_thunk_function (false, regno); + output_indirect_thunk_function (false, regno, false); if ((indirect_thunks_bnd_used & (1 << regno))) - output_indirect_thunk_function (true, regno); + output_indirect_thunk_function (true, regno, false); if (!(pic_labels_used & (1 << regno))) continue; @@ -14061,7 +14051,6 @@ { struct machine_function *m = cfun->machine; rtx insn, t; - struct ix86_frame frame; HOST_WIDE_INT allocate; bool int_registers_saved; bool sse_registers_saved; @@ -14085,7 +14074,7 @@ m->fs.sp_valid = true; ix86_compute_frame_layout (); - frame = m->frame; + const struct ix86_frame &frame = cfun->machine->frame; if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl)) { @@ -14748,13 +14737,12 @@ { struct machine_function *m = cfun->machine; struct machine_frame_state frame_state_save = m->fs; - struct ix86_frame frame; bool restore_regs_via_mov; bool using_drap; ix86_finalize_stack_realign_flags (); ix86_compute_frame_layout (); - frame = m->frame; + const struct ix86_frame &frame = cfun->machine->frame; m->fs.sp_valid = (!frame_pointer_needed || (crtl->sp_is_unchanging @@ -14796,11 +14784,13 @@ + UNITS_PER_WORD); } + HOST_WIDE_INT reg_save_offset = frame.reg_save_offset; + /* Special care must be taken for the normal return case of a function using eh_return: the eax and edx registers are marked as saved, but not restored along this path. Adjust the save location to match. */ if (crtl->calls_eh_return && style != 2) - frame.reg_save_offset -= 2 * UNITS_PER_WORD; + reg_save_offset -= 2 * UNITS_PER_WORD; /* EH_RETURN requires the use of moves to function properly. */ if (crtl->calls_eh_return) @@ -14816,11 +14806,11 @@ else if (TARGET_EPILOGUE_USING_MOVE && cfun->machine->use_fast_prologue_epilogue && (frame.nregs > 1 - || m->fs.sp_offset != frame.reg_save_offset)) + || m->fs.sp_offset != reg_save_offset)) restore_regs_via_mov = true; else if (frame_pointer_needed && !frame.nregs - && m->fs.sp_offset != frame.reg_save_offset) + && m->fs.sp_offset != reg_save_offset) restore_regs_via_mov = true; else if (frame_pointer_needed && TARGET_USE_LEAVE @@ -14858,7 +14848,7 @@ rtx t; if (frame.nregs) - ix86_emit_restore_regs_using_mov (frame.reg_save_offset, style == 2); + ix86_emit_restore_regs_using_mov (reg_save_offset, style == 2); /* eh_return epilogues need %ecx added to the stack pointer. */ if (style == 2) @@ -14948,19 +14938,19 @@ epilogues. */ if (!m->fs.sp_valid || (TARGET_SEH - && (m->fs.sp_offset - frame.reg_save_offset + && (m->fs.sp_offset - reg_save_offset >= SEH_MAX_FRAME_SIZE))) { pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx, GEN_INT (m->fs.fp_offset - - frame.reg_save_offset), + - reg_save_offset), style, false); } - else if (m->fs.sp_offset != frame.reg_save_offset) + else if (m->fs.sp_offset != reg_save_offset) { pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (m->fs.sp_offset - - frame.reg_save_offset), + - reg_save_offset), style, m->fs.cfa_reg == stack_pointer_rtx); } @@ -18842,7 +18832,8 @@ since we can in fact encode that into an immediate. */ if (GET_CODE (x) == CONST_VECTOR) { - gcc_assert (x == CONST0_RTX (GET_MODE (x))); + if (x != CONST0_RTX (GET_MODE (x))) + output_operand_lossage ("invalid vector immediate"); x = const0_rtx; } @@ -19807,74 +19798,38 @@ emit_insn (gen_x86_fnstcw_1 (stored_mode)); emit_move_insn (reg, copy_rtx (stored_mode)); - if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL - || optimize_insn_for_size_p ()) + switch (mode) { - switch (mode) - { - case I387_CW_TRUNC: - /* round toward zero (truncate) */ - emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00))); - slot = SLOT_CW_TRUNC; - break; + case I387_CW_TRUNC: + /* round toward zero (truncate) */ + emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00))); + slot = SLOT_CW_TRUNC; + break; - case I387_CW_FLOOR: - /* round down toward -oo */ - emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00))); - emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400))); - slot = SLOT_CW_FLOOR; - break; + case I387_CW_FLOOR: + /* round down toward -oo */ + emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00))); + emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400))); + slot = SLOT_CW_FLOOR; + break; - case I387_CW_CEIL: - /* round up toward +oo */ - emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00))); - emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800))); - slot = SLOT_CW_CEIL; - break; + case I387_CW_CEIL: + /* round up toward +oo */ + emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00))); + emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800))); + slot = SLOT_CW_CEIL; + break; - case I387_CW_MASK_PM: - /* mask precision exception for nearbyint() */ - emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0020))); - slot = SLOT_CW_MASK_PM; - break; + case I387_CW_MASK_PM: + /* mask precision exception for nearbyint() */ + emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0020))); + slot = SLOT_CW_MASK_PM; + break; - default: - gcc_unreachable (); - } + default: + gcc_unreachable (); } - else - { - switch (mode) - { - case I387_CW_TRUNC: - /* round toward zero (truncate) */ - emit_insn (gen_insvsi_1 (reg, GEN_INT (0xc))); - slot = SLOT_CW_TRUNC; - break; - case I387_CW_FLOOR: - /* round down toward -oo */ - emit_insn (gen_insvsi_1 (reg, GEN_INT (0x4))); - slot = SLOT_CW_FLOOR; - break; - - case I387_CW_CEIL: - /* round up toward +oo */ - emit_insn (gen_insvsi_1 (reg, GEN_INT (0x8))); - slot = SLOT_CW_CEIL; - break; - - case I387_CW_MASK_PM: - /* mask precision exception for nearbyint() */ - emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0020))); - slot = SLOT_CW_MASK_PM; - break; - - default: - gcc_unreachable (); - } - } - gcc_assert (slot < MAX_386_STACK_LOCALS); new_mode = assign_386_stack_local (HImode, slot); @@ -29109,18 +29064,17 @@ else ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p); } -/* Output indirect jump. CALL_OP is the jump target. Jump is a - function return if RET_P is true. */ +/* Output indirect jump. CALL_OP is the jump target. */ + const char * -ix86_output_indirect_jmp (rtx call_op, bool ret_p) +ix86_output_indirect_jmp (rtx call_op) { if (cfun->machine->indirect_branch_type != indirect_branch_keep) { - /* We can't have red-zone if this isn't a function return since - "call" in the indirect thunk pushes the return address onto - stack, destroying red-zone. */ - if (!ret_p && ix86_red_zone_size != 0) + /* We can't have red-zone since "call" in the indirect thunk + pushes the return address onto stack, destroying red-zone. */ + if (ix86_red_zone_size != 0) gcc_unreachable (); ix86_output_indirect_branch (call_op, "%0", true); @@ -29146,20 +29100,21 @@ { bool need_thunk = (cfun->machine->function_return_type == indirect_branch_thunk); - indirect_thunk_name (thunk_name, -1, need_bnd_p, true); + indirect_thunk_name (thunk_name, INVALID_REGNUM, need_bnd_p, + true); if (need_bnd_p) { - indirect_thunk_bnd_needed |= need_thunk; + indirect_return_bnd_needed |= need_thunk; fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); } else { - indirect_thunk_needed |= need_thunk; + indirect_return_needed |= need_thunk; fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); } } else - output_indirect_thunk (need_bnd_p, -1); + output_indirect_thunk (need_bnd_p, INVALID_REGNUM); return ""; } @@ -29170,6 +29125,86 @@ return "rep%; ret"; } +/* Output indirect function return. RET_OP is the function return + target. */ + +const char * +ix86_output_indirect_function_return (rtx ret_op) +{ + if (cfun->machine->function_return_type != indirect_branch_keep) + { + char thunk_name[32]; + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); + unsigned int regno = REGNO (ret_op); + gcc_assert (regno == CX_REG); + + if (cfun->machine->function_return_type + != indirect_branch_thunk_inline) + { + bool need_thunk = (cfun->machine->function_return_type + == indirect_branch_thunk); + indirect_thunk_name (thunk_name, regno, need_bnd_p, true); + if (need_bnd_p) + { + if (need_thunk) + { + indirect_return_via_cx_bnd = true; + indirect_thunks_bnd_used |= 1 << CX_REG; + } + fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); + } + else + { + if (need_thunk) + { + indirect_return_via_cx = true; + indirect_thunks_used |= 1 << CX_REG; + } + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); + } + } + else + output_indirect_thunk (need_bnd_p, regno); + + return ""; + } + else + return "%!jmp\t%A0"; +} + +/* Split simple return with popping POPC bytes from stack to indirect + branch with stack adjustment . */ + +void +ix86_split_simple_return_pop_internal (rtx popc) +{ + struct machine_function *m = cfun->machine; + rtx ecx = gen_rtx_REG (SImode, CX_REG); + rtx_insn *insn; + + /* There is no "pascal" calling convention in any 64bit ABI. */ + gcc_assert (!TARGET_64BIT); + + insn = emit_insn (gen_pop (ecx)); + m->fs.cfa_offset -= UNITS_PER_WORD; + m->fs.sp_offset -= UNITS_PER_WORD; + + rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); + x = gen_rtx_SET (stack_pointer_rtx, x); + add_reg_note (insn, REG_CFA_ADJUST_CFA, x); + add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx)); + RTX_FRAME_RELATED_P (insn) = 1; + + x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, popc); + x = gen_rtx_SET (stack_pointer_rtx, x); + insn = emit_insn (x); + add_reg_note (insn, REG_CFA_ADJUST_CFA, x); + RTX_FRAME_RELATED_P (insn) = 1; + + /* Now return address is in ECX. */ + emit_jump_insn (gen_simple_return_indirect_internal (ecx)); +} + /* Output the assembly for a call instruction. */ const char * Index: gcc/config/avr/avr.md =================================================================== diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md --- a/gcc/config/avr/avr.md (revision 257042) +++ b/gcc/config/avr/avr.md (revision 259627) @@ -3362,6 +3362,8 @@ (match_operand:HI 1 "reg_or_0_operand"))] "optimize && reload_completed + && GENERAL_REG_P (operands[0]) + && (operands[1] == const0_rtx || GENERAL_REG_P (operands[1])) && (!AVR_HAVE_MOVW || const0_rtx == operands[1])" [(set (match_dup 2) (match_dup 3)) Index: gcc/config/avr/avr.h =================================================================== diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h --- a/gcc/config/avr/avr.h (revision 257042) +++ b/gcc/config/avr/avr.h (revision 259627) @@ -153,6 +153,9 @@ #define FIRST_PSEUDO_REGISTER 36 +#define GENERAL_REGNO_P(N) IN_RANGE (N, 2, 31) +#define GENERAL_REG_P(X) (REG_P (X) && GENERAL_REGNO_P (REGNO (X))) + #define FIXED_REGISTERS {\ 1,1,/* r0 r1 */\ 0,0,/* r2 r3 */\ Index: gcc/config/m68k/m68k.c =================================================================== diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c --- a/gcc/config/m68k/m68k.c (revision 257042) +++ b/gcc/config/m68k/m68k.c (revision 259627) @@ -185,6 +185,8 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED; static enum flt_eval_method m68k_excess_precision (enum excess_precision_type); +static machine_mode m68k_promote_function_mode (const_tree, machine_mode, + int *, const_tree, int); /* Initialize the GCC target structure. */ @@ -332,6 +334,9 @@ #undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL #define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 128 +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE m68k_promote_function_mode + static const struct attribute_spec m68k_attribute_table[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, @@ -6571,4 +6576,20 @@ return FLT_EVAL_METHOD_UNPREDICTABLE; } +/* Implement TARGET_PROMOTE_FUNCTION_MODE. */ + +static machine_mode +m68k_promote_function_mode (const_tree type, machine_mode mode, + int *punsignedp ATTRIBUTE_UNUSED, + const_tree fntype ATTRIBUTE_UNUSED, + int for_return) +{ + /* Promote libcall arguments narrower than int to match the normal C + ABI (for which promotions are handled via + TARGET_PROMOTE_PROTOTYPES). */ + if (type == NULL_TREE && !for_return && (mode == QImode || mode == HImode)) + return SImode; + return mode; +} + #include "gt-m68k.h" Index: gcc/config/aarch64/aarch64-simd.md =================================================================== diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md --- a/gcc/config/aarch64/aarch64-simd.md (revision 257042) +++ b/gcc/config/aarch64/aarch64-simd.md (revision 259627) @@ -2462,10 +2462,10 @@ break; } /* Fall through. */ - case UNGE: + case UNLT: std::swap (operands[2], operands[3]); /* Fall through. */ - case UNLE: + case UNGT: case GT: comparison = gen_aarch64_cmgt; break; @@ -2476,10 +2476,10 @@ break; } /* Fall through. */ - case UNGT: + case UNLE: std::swap (operands[2], operands[3]); /* Fall through. */ - case UNLT: + case UNGE: case GE: comparison = gen_aarch64_cmge; break; @@ -2490,6 +2490,7 @@ case UNEQ: case ORDERED: case UNORDERED: + case LTGT: break; default: gcc_unreachable (); @@ -2501,21 +2502,35 @@ case UNGT: case UNLE: case UNLT: - case NE: - /* FCM returns false for lanes which are unordered, so if we use - the inverse of the comparison we actually want to emit, then - invert the result, we will end up with the correct result. - Note that a NE NaN and NaN NE b are true for all a, b. + { + /* All of the above must not raise any FP exceptions. Thus we first + check each operand for NaNs and force any elements containing NaN to + zero before using them in the compare. + Example: UN (a, b) -> UNORDERED (a, b) | + (cm (isnan (a) ? 0.0 : a, + isnan (b) ? 0.0 : b)) + We use the following transformations for doing the comparisions: + a UNGE b -> a GE b + a UNGT b -> a GT b + a UNLE b -> b GE a + a UNLT b -> b GT a. */ - Our transformations are: - a UNGE b -> !(b GT a) - a UNGT b -> !(b GE a) - a UNLE b -> !(a GT b) - a UNLT b -> !(a GE b) - a NE b -> !(a EQ b) */ - gcc_assert (comparison != NULL); - emit_insn (comparison (operands[0], operands[2], operands[3])); - emit_insn (gen_one_cmpl2 (operands[0], operands[0])); + rtx tmp0 = gen_reg_rtx (mode); + rtx tmp1 = gen_reg_rtx (mode); + rtx tmp2 = gen_reg_rtx (mode); + emit_insn (gen_aarch64_cmeq (tmp0, operands[2], operands[2])); + emit_insn (gen_aarch64_cmeq (tmp1, operands[3], operands[3])); + emit_insn (gen_and3 (tmp2, tmp0, tmp1)); + emit_insn (gen_and3 (tmp0, tmp0, + lowpart_subreg (mode, operands[2], mode))); + emit_insn (gen_and3 (tmp1, tmp1, + lowpart_subreg (mode, operands[3], mode))); + gcc_assert (comparison != NULL); + emit_insn (comparison (operands[0], + lowpart_subreg (mode, tmp0, mode), + lowpart_subreg (mode, tmp1, mode))); + emit_insn (gen_orn3 (operands[0], tmp2, operands[0])); + } break; case LT: @@ -2523,6 +2538,7 @@ case GT: case GE: case EQ: + case NE: /* The easy case. Here we emit one of FCMGE, FCMGT or FCMEQ. As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are: a GE b -> a GE b @@ -2529,36 +2545,39 @@ a GT b -> a GT b a LE b -> b GE a a LT b -> b GT a - a EQ b -> a EQ b */ + a EQ b -> a EQ b + a NE b -> ~(a EQ b) */ gcc_assert (comparison != NULL); emit_insn (comparison (operands[0], operands[2], operands[3])); + if (code == NE) + emit_insn (gen_one_cmpl2 (operands[0], operands[0])); break; - case UNEQ: - /* We first check (a > b || b > a) which is !UNEQ, inverting - this result will then give us (a == b || a UNORDERED b). */ + case LTGT: + /* LTGT is not guranteed to not generate a FP exception. So let's + go the faster way : ((a > b) || (b > a)). */ emit_insn (gen_aarch64_cmgt (operands[0], operands[2], operands[3])); emit_insn (gen_aarch64_cmgt (tmp, operands[3], operands[2])); emit_insn (gen_ior3 (operands[0], operands[0], tmp)); - emit_insn (gen_one_cmpl2 (operands[0], operands[0])); break; + case ORDERED: case UNORDERED: - /* Operands are ORDERED iff (a > b || b >= a), so we can compute - UNORDERED as !ORDERED. */ - emit_insn (gen_aarch64_cmgt (tmp, operands[2], operands[3])); - emit_insn (gen_aarch64_cmge (operands[0], - operands[3], operands[2])); - emit_insn (gen_ior3 (operands[0], operands[0], tmp)); - emit_insn (gen_one_cmpl2 (operands[0], operands[0])); - break; + case UNEQ: + /* cmeq (a, a) & cmeq (b, b). */ + emit_insn (gen_aarch64_cmeq (operands[0], + operands[2], operands[2])); + emit_insn (gen_aarch64_cmeq (tmp, operands[3], operands[3])); + emit_insn (gen_and3 (operands[0], operands[0], tmp)); - case ORDERED: - emit_insn (gen_aarch64_cmgt (tmp, operands[2], operands[3])); - emit_insn (gen_aarch64_cmge (operands[0], - operands[3], operands[2])); - emit_insn (gen_ior3 (operands[0], operands[0], tmp)); + if (code == UNORDERED) + emit_insn (gen_one_cmpl2 (operands[0], operands[0])); + else if (code == UNEQ) + { + emit_insn (gen_aarch64_cmeq (tmp, operands[2], operands[3])); + emit_insn (gen_orn3 (operands[0], operands[0], tmp)); + } break; default: Index: gcc/config/aarch64/aarch64.md =================================================================== diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md --- a/gcc/config/aarch64/aarch64.md (revision 257042) +++ b/gcc/config/aarch64/aarch64.md (revision 259627) @@ -3093,7 +3093,8 @@ (define_insn_and_split "*compare_cstore_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (EQL:GPI (match_operand:GPI 1 "register_operand" "r") - (match_operand:GPI 2 "aarch64_imm24" "n")))] + (match_operand:GPI 2 "aarch64_imm24" "n"))) + (clobber (reg:CC CC_REGNUM))] "!aarch64_move_imm (INTVAL (operands[2]), mode) && !aarch64_plus_operand (operands[2], mode) && !reload_completed" Index: gcc/config/aarch64/constraints.md =================================================================== diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md --- a/gcc/config/aarch64/constraints.md (revision 257042) +++ b/gcc/config/aarch64/constraints.md (revision 259627) @@ -21,8 +21,8 @@ (define_register_constraint "k" "STACK_REG" "@internal The stack register.") -(define_register_constraint "Ucs" "CALLER_SAVE_REGS" - "@internal The caller save registers.") +(define_register_constraint "Ucs" "TAILCALL_ADDR_REGS" + "@internal Registers suitable for an indirect tail call") (define_register_constraint "w" "FP_REGS" "Floating point and SIMD vector registers.") Index: gcc/config/aarch64/aarch64.c =================================================================== diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c --- a/gcc/config/aarch64/aarch64.c (revision 257042) +++ b/gcc/config/aarch64/aarch64.c (revision 259627) @@ -4664,7 +4664,6 @@ case UNGT: case UNGE: case UNEQ: - case LTGT: return CCFPmode; case LT: @@ -4671,6 +4670,7 @@ case LE: case GT: case GE: + case LTGT: return CCFPEmode; default: @@ -5721,7 +5721,7 @@ { switch (regclass) { - case CALLER_SAVE_REGS: + case TAILCALL_ADDR_REGS: case POINTER_REGS: case GENERAL_REGS: case ALL_REGS: @@ -7799,10 +7799,10 @@ = aarch64_tune_params.regmove_cost; /* Caller save and pointer regs are equivalent to GENERAL_REGS. */ - if (to == CALLER_SAVE_REGS || to == POINTER_REGS) + if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS) to = GENERAL_REGS; - if (from == CALLER_SAVE_REGS || from == POINTER_REGS) + if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS) from = GENERAL_REGS; /* Moving between GPR and stack cost is the same as GP2GP. */ @@ -8608,17 +8608,6 @@ if (opts->x_pcrelative_literal_loads == 1) aarch64_pcrelative_literal_loads = true; - /* This is PR70113. When building the Linux kernel with - CONFIG_ARM64_ERRATUM_843419, support for relocations - R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADR_PREL_PG_HI21_NC is - removed from the kernel to avoid loading objects with possibly - offending sequences. Without -mpc-relative-literal-loads we would - generate such relocations, preventing the kernel build from - succeeding. */ - if (opts->x_pcrelative_literal_loads == 2 - && TARGET_FIX_ERR_A53_843419) - aarch64_pcrelative_literal_loads = true; - /* In the tiny memory model it makes no sense to disallow PC relative literal pool loads. */ if (aarch64_cmodel == AARCH64_CMODEL_TINY Index: gcc/config/aarch64/aarch64.h =================================================================== diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h --- a/gcc/config/aarch64/aarch64.h (revision 257042) +++ b/gcc/config/aarch64/aarch64.h (revision 259627) @@ -439,7 +439,7 @@ enum reg_class { NO_REGS, - CALLER_SAVE_REGS, + TAILCALL_ADDR_REGS, GENERAL_REGS, STACK_REG, POINTER_REGS, @@ -454,7 +454,7 @@ #define REG_CLASS_NAMES \ { \ "NO_REGS", \ - "CALLER_SAVE_REGS", \ + "TAILCALL_ADDR_REGS", \ "GENERAL_REGS", \ "STACK_REG", \ "POINTER_REGS", \ @@ -466,7 +466,7 @@ #define REG_CLASS_CONTENTS \ { \ { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ - { 0x0007ffff, 0x00000000, 0x00000000 }, /* CALLER_SAVE_REGS */ \ + { 0x0004ffff, 0x00000000, 0x00000000 }, /* TAILCALL_ADDR_REGS */\ { 0x7fffffff, 0x00000000, 0x00000003 }, /* GENERAL_REGS */ \ { 0x80000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \ { 0xffffffff, 0x00000000, 0x00000003 }, /* POINTER_REGS */ \ Index: gcc/config/rs6000/vector.md =================================================================== diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md --- a/gcc/config/rs6000/vector.md (revision 257042) +++ b/gcc/config/rs6000/vector.md (revision 259627) @@ -180,12 +180,7 @@ operands[1] = rs6000_address_for_altivec (operands[1]); rtx and_op = XEXP (operands[1], 0); gcc_assert (GET_CODE (and_op) == AND); - rtx addr = XEXP (and_op, 0); - if (GET_CODE (addr) == PLUS) - emit_insn (gen_altivec_lvx__2op (operands[0], XEXP (addr, 0), - XEXP (addr, 1))); - else - emit_insn (gen_altivec_lvx__1op (operands[0], operands[1])); + emit_insn (gen_altivec_lvx_ (operands[0], operands[1])); DONE; } }") @@ -203,12 +198,7 @@ operands[0] = rs6000_address_for_altivec (operands[0]); rtx and_op = XEXP (operands[0], 0); gcc_assert (GET_CODE (and_op) == AND); - rtx addr = XEXP (and_op, 0); - if (GET_CODE (addr) == PLUS) - emit_insn (gen_altivec_stvx__2op (operands[1], XEXP (addr, 0), - XEXP (addr, 1))); - else - emit_insn (gen_altivec_stvx__1op (operands[1], operands[0])); + emit_insn (gen_altivec_stvx_ (operands[1], operands[0])); DONE; } }") Index: gcc/config/rs6000/predicates.md =================================================================== diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md --- a/gcc/config/rs6000/predicates.md (revision 257042) +++ b/gcc/config/rs6000/predicates.md (revision 259627) @@ -1468,13 +1468,12 @@ rtx elt; int count = XVECLEN (op, 0); - if (count != 59) + if (count != 58) return 0; index = 0; if (GET_CODE (XVECEXP (op, 0, index++)) != RETURN || GET_CODE (XVECEXP (op, 0, index++)) != USE - || GET_CODE (XVECEXP (op, 0, index++)) != USE || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER) return 0; Index: gcc/config/rs6000/sysv4.opt =================================================================== diff --git a/gcc/config/rs6000/sysv4.opt b/gcc/config/rs6000/sysv4.opt --- a/gcc/config/rs6000/sysv4.opt (revision 257042) +++ b/gcc/config/rs6000/sysv4.opt (revision 259627) @@ -27,6 +27,10 @@ Target RejectNegative Joined Var(rs6000_sdata_name) Select method for sdata handling. +mreadonly-in-sdata +Target Report Var(rs6000_readonly_in_sdata) Init(1) Save +Allow readonly data in sdata. + mtls-size= Target RejectNegative Joined Var(rs6000_tls_size) Enum(rs6000_tls_size) Specify bit size of immediate TLS offsets. Index: gcc/config/rs6000/rs6000-protos.h =================================================================== diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h --- a/gcc/config/rs6000/rs6000-protos.h (revision 257042) +++ b/gcc/config/rs6000/rs6000-protos.h (revision 259627) @@ -139,7 +139,6 @@ extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx); extern int rs6000_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx, rtx); extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx); -extern void rs6000_split_signbit (rtx, rtx); extern void rs6000_expand_atomic_compare_and_swap (rtx op[]); extern void rs6000_expand_atomic_exchange (rtx op[]); extern void rs6000_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx); Index: gcc/config/rs6000/rs6000-builtin.def =================================================================== diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def --- a/gcc/config/rs6000/rs6000-builtin.def (revision 257042) +++ b/gcc/config/rs6000/rs6000-builtin.def (revision 259627) @@ -1,5 +1,5 @@ /* Builtin functions for rs6000/powerpc. - Copyright (C) 2009-2017 Free Software Foundation, Inc. + Copyright (C) 2009-2018 Free Software Foundation, Inc. Contributed by Michael Meissner (meissner@linux.vnet.ibm.com) This file is part of GCC. @@ -659,6 +659,14 @@ | RS6000_BTC_BINARY), \ CODE_FOR_ ## ICODE) /* ICODE */ +#define BU_P7_POWERPC64_MISC_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_POPCNTD /* MASK */ \ + | RS6000_BTM_POWERPC64, \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ /* Miscellaneous builtins for instructions added in ISA 2.07. These instructions do require the ISA 2.07 vector support, but they aren't vector @@ -2034,8 +2042,8 @@ /* Insert/extract 4 byte word into a vector. */ BU_P9V_VSX_2 (VEXTRACT4B, "vextract4b", CONST, vextract4b) -BU_P9V_VSX_3 (VINSERT4B, "vinsert4b", CONST, vinsert4b) -BU_P9V_VSX_3 (VINSERT4B_DI, "vinsert4b_di", CONST, vinsert4b_di) +BU_P9V_VSX_3 (INSERT4B, "insert4b", CONST, insert4b) +BU_P9V_VSX_2 (EXTRACT4B, "extract4b", CONST, extract4b) /* 3 argument vector functions returning void, treated as SPECIAL, added in ISA 3.0 (power9). */ @@ -2084,10 +2092,11 @@ BU_P9V_OVERLOAD_2 (VEXTULX, "vextulx") BU_P9V_OVERLOAD_2 (VEXTURX, "vexturx") BU_P9V_OVERLOAD_2 (VEXTRACT4B, "vextract4b") +BU_P9V_OVERLOAD_2 (EXTRACT4B, "extract4b") /* ISA 3.0 Vector scalar overloaded 3 argument functions */ BU_P9V_OVERLOAD_3 (STXVL, "stxvl") -BU_P9V_OVERLOAD_3 (VINSERT4B, "vinsert4b") +BU_P9V_OVERLOAD_3 (INSERT4B, "insert4b") /* Overloaded CMPNE support was implemented prior to Power 9, so is not mentioned here. */ @@ -2103,13 +2112,9 @@ /* 2 argument extended divide functions added in ISA 2.06. */ BU_P7_MISC_2 (DIVWE, "divwe", CONST, dive_si) -BU_P7_MISC_2 (DIVWEO, "divweo", CONST, diveo_si) BU_P7_MISC_2 (DIVWEU, "divweu", CONST, diveu_si) -BU_P7_MISC_2 (DIVWEUO, "divweuo", CONST, diveuo_si) -BU_P7_MISC_2 (DIVDE, "divde", CONST, dive_di) -BU_P7_MISC_2 (DIVDEO, "divdeo", CONST, diveo_di) -BU_P7_MISC_2 (DIVDEU, "divdeu", CONST, diveu_di) -BU_P7_MISC_2 (DIVDEUO, "divdeuo", CONST, diveuo_di) +BU_P7_POWERPC64_MISC_2 (DIVDE, "divde", CONST, dive_di) +BU_P7_POWERPC64_MISC_2 (DIVDEU, "divdeu", CONST, diveu_di) /* 1 argument DFP (decimal floating point) functions added in ISA 2.05. */ BU_DFP_MISC_1 (DXEX, "dxex", CONST, dfp_dxex_dd) Index: gcc/config/rs6000/rs6000-c.c =================================================================== diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c --- a/gcc/config/rs6000/rs6000-c.c (revision 257042) +++ b/gcc/config/rs6000/rs6000-c.c (revision 259627) @@ -5047,6 +5047,8 @@ RS6000_BTI_INTDI, RS6000_BTI_V16QI, RS6000_BTI_UINTSI, 0 }, { P9V_BUILTIN_VEC_VEXTRACT4B, P9V_BUILTIN_VEXTRACT4B, RS6000_BTI_INTDI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTSI, 0 }, + { P9V_BUILTIN_VEC_EXTRACT4B, P9V_BUILTIN_EXTRACT4B, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, 0 }, { P9V_BUILTIN_VEC_VEXTULX, P9V_BUILTIN_VEXTUBLX, RS6000_BTI_INTQI, RS6000_BTI_UINTSI, @@ -5101,27 +5103,12 @@ { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B, - RS6000_BTI_V16QI, RS6000_BTI_V4SI, - RS6000_BTI_V16QI, RS6000_BTI_UINTSI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B, - RS6000_BTI_V16QI, RS6000_BTI_unsigned_V4SI, - RS6000_BTI_V16QI, RS6000_BTI_UINTSI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B, + { P9V_BUILTIN_VEC_INSERT4B, P9V_BUILTIN_INSERT4B, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_V4SI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI }, + { P9V_BUILTIN_VEC_INSERT4B, P9V_BUILTIN_INSERT4B, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTSI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, - RS6000_BTI_V16QI, RS6000_BTI_INTDI, - RS6000_BTI_V16QI, RS6000_BTI_UINTDI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, - RS6000_BTI_V16QI, RS6000_BTI_UINTDI, - RS6000_BTI_V16QI, RS6000_BTI_UINTDI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTDI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTDI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTDI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTDI }, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI }, { P8V_BUILTIN_VEC_VADDECUQ, P8V_BUILTIN_VADDECUQ, RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI }, @@ -6088,6 +6075,15 @@ stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1); stmt = build_indirect_ref (loc, stmt, RO_NULL); + /* PR83660: We mark this as having side effects so that + downstream in fold_build_cleanup_point_expr () it will get a + CLEANUP_POINT_EXPR. If it does not we can run into an ICE + later in gimplify_cleanup_point_expr (). Potentially this + causes missed optimization because the actually is no side + effect. */ + if (c_dialect_cxx ()) + TREE_SIDE_EFFECTS (stmt) = 1; + return stmt; } Index: gcc/config/rs6000/rs6000.c =================================================================== diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c --- a/gcc/config/rs6000/rs6000.c (revision 257042) +++ b/gcc/config/rs6000/rs6000.c (revision 259627) @@ -1,5 +1,5 @@ /* Subroutines used for code generation on IBM RS/6000. - Copyright (C) 1991-2017 Free Software Foundation, Inc. + Copyright (C) 1991-2018 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GCC. @@ -1372,6 +1372,7 @@ int, int, int *); static bool rs6000_mode_dependent_address (const_rtx); static bool rs6000_debug_mode_dependent_address (const_rtx); +static bool rs6000_offsettable_memref_p (rtx, machine_mode, bool); static enum reg_class rs6000_secondary_reload_class (enum reg_class, machine_mode, rtx); static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class, @@ -3890,6 +3891,7 @@ | ((TARGET_P9_MISC) ? RS6000_BTM_P9_MISC : 0) | ((TARGET_MODULO) ? RS6000_BTM_MODULO : 0) | ((TARGET_64BIT) ? RS6000_BTM_64BIT : 0) + | ((TARGET_POWERPC64) ? RS6000_BTM_POWERPC64 : 0) | ((TARGET_CRYPTO) ? RS6000_BTM_CRYPTO : 0) | ((TARGET_HTM) ? RS6000_BTM_HTM : 0) | ((TARGET_DFP) ? RS6000_BTM_DFP : 0) @@ -5563,6 +5565,11 @@ if (TARGET_LINK_STACK == -1) SET_TARGET_LINK_STACK (rs6000_cpu == PROCESSOR_PPC476 && flag_pic); + /* Deprecate use of -mno-speculate-indirect-jumps. */ + if (!rs6000_speculate_indirect_jumps) + warning (0, "%qs is deprecated and not recommended in any circumstances", + "-mno-speculate-indirect-jumps"); + return ret; } @@ -8558,6 +8565,10 @@ int extra; rtx addr = XEXP (op, 0); + /* Don't allow non-offsettable addresses. See PRs 83969 and 84279. */ + if (!rs6000_offsettable_memref_p (op, mode, false)) + return false; + op = address_offset (addr); if (op == NULL_RTX) return true; @@ -10328,7 +10339,7 @@ in 32-bit mode, that the recog predicate rejects. */ static bool -rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode) +rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode, bool strict) { bool worst_case; @@ -10336,7 +10347,7 @@ return false; /* First mimic offsettable_memref_p. */ - if (offsettable_address_p (true, GET_MODE (op), XEXP (op, 0))) + if (offsettable_address_p (strict, GET_MODE (op), XEXP (op, 0))) return true; /* offsettable_address_p invokes rs6000_mode_dependent_address, but @@ -10350,7 +10361,7 @@ worst_case = ((TARGET_POWERPC64 && GET_MODE_CLASS (reg_mode) == MODE_INT) || GET_MODE_SIZE (reg_mode) == 4); return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), - true, worst_case); + strict, worst_case); } /* Determine the reassociation width to be used in reassociate_bb. @@ -15087,12 +15098,12 @@ /* For LVX, express the RTL accurately by ANDing the address with -16. LVXL and LVE*X expand to use UNSPECs to hide their special behavior, so the raw address is fine. */ - if (icode == CODE_FOR_altivec_lvx_v2df_2op - || icode == CODE_FOR_altivec_lvx_v2di_2op - || icode == CODE_FOR_altivec_lvx_v4sf_2op - || icode == CODE_FOR_altivec_lvx_v4si_2op - || icode == CODE_FOR_altivec_lvx_v8hi_2op - || icode == CODE_FOR_altivec_lvx_v16qi_2op) + if (icode == CODE_FOR_altivec_lvx_v2df + || icode == CODE_FOR_altivec_lvx_v2di + || icode == CODE_FOR_altivec_lvx_v4sf + || icode == CODE_FOR_altivec_lvx_v4si + || icode == CODE_FOR_altivec_lvx_v8hi + || icode == CODE_FOR_altivec_lvx_v16qi) { rtx rawaddr; if (op0 == const0_rtx) @@ -15278,12 +15289,12 @@ /* For STVX, express the RTL accurately by ANDing the address with -16. STVXL and STVE*X expand to use UNSPECs to hide their special behavior, so the raw address is fine. */ - if (icode == CODE_FOR_altivec_stvx_v2df_2op - || icode == CODE_FOR_altivec_stvx_v2di_2op - || icode == CODE_FOR_altivec_stvx_v4sf_2op - || icode == CODE_FOR_altivec_stvx_v4si_2op - || icode == CODE_FOR_altivec_stvx_v8hi_2op - || icode == CODE_FOR_altivec_stvx_v16qi_2op) + if (icode == CODE_FOR_altivec_stvx_v2df + || icode == CODE_FOR_altivec_stvx_v2di + || icode == CODE_FOR_altivec_stvx_v4sf + || icode == CODE_FOR_altivec_stvx_v4si + || icode == CODE_FOR_altivec_stvx_v8hi + || icode == CODE_FOR_altivec_stvx_v16qi) { if (op1 == const0_rtx) rawaddr = op2; @@ -16184,18 +16195,18 @@ switch (fcode) { case ALTIVEC_BUILTIN_STVX_V2DF: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2df_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2df, exp); case ALTIVEC_BUILTIN_STVX_V2DI: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2di_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2di, exp); case ALTIVEC_BUILTIN_STVX_V4SF: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4sf_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4sf, exp); case ALTIVEC_BUILTIN_STVX: case ALTIVEC_BUILTIN_STVX_V4SI: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp); case ALTIVEC_BUILTIN_STVX_V8HI: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v8hi_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v8hi, exp); case ALTIVEC_BUILTIN_STVX_V16QI: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v16qi_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v16qi, exp); case ALTIVEC_BUILTIN_STVEBX: return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp); case ALTIVEC_BUILTIN_STVEHX: @@ -16374,6 +16385,7 @@ case P9V_BUILTIN_VEXTRACT4B: case P9V_BUILTIN_VEC_VEXTRACT4B: + case P9V_BUILTIN_VEC_EXTRACT4B: arg1 = CALL_EXPR_ARG (exp, 1); STRIP_NOPS (arg1); @@ -16388,9 +16400,7 @@ } break; - case P9V_BUILTIN_VINSERT4B: - case P9V_BUILTIN_VINSERT4B_DI: - case P9V_BUILTIN_VEC_VINSERT4B: + case P9V_BUILTIN_VEC_INSERT4B: arg2 = CALL_EXPR_ARG (exp, 2); STRIP_NOPS (arg2); @@ -16400,7 +16410,7 @@ if (TREE_CODE (arg2) != INTEGER_CST || TREE_INT_CST_LOW (arg2) > 12) { - error ("third argument to vec_vinsert4b must be 0..12"); + error ("third argument to vec_insert4b must be 0..12"); return expand_call (exp, target, false); } break; @@ -16460,23 +16470,23 @@ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v16qi, exp, target, false); case ALTIVEC_BUILTIN_LVX_V2DF: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2df_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2df, exp, target, false); case ALTIVEC_BUILTIN_LVX_V2DI: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2di_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2di, exp, target, false); case ALTIVEC_BUILTIN_LVX_V4SF: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4sf_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4sf, exp, target, false); case ALTIVEC_BUILTIN_LVX: case ALTIVEC_BUILTIN_LVX_V4SI: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si, exp, target, false); case ALTIVEC_BUILTIN_LVX_V8HI: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v8hi_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v8hi, exp, target, false); case ALTIVEC_BUILTIN_LVX_V16QI: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v16qi_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v16qi, exp, target, false); case ALTIVEC_BUILTIN_LVLX: return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx, @@ -17040,6 +17050,11 @@ error ("Builtin function %s requires the -mhard-float option", name); else if ((fnmask & RS6000_BTM_FLOAT128) != 0) error ("Builtin function %s requires the -mfloat128 option", name); + else if ((fnmask & (RS6000_BTM_POPCNTD | RS6000_BTM_POWERPC64)) + == (RS6000_BTM_POPCNTD | RS6000_BTM_POWERPC64)) + error ("builtin function %qs requires the %qs (or newer), and " + "%qs or %qs options", + name, "-mcpu=power7", "-m64", "-mpowerpc64"); else error ("Builtin function %s is not supported with the current options", name); @@ -18804,9 +18819,7 @@ case CRYPTO_BUILTIN_VPMSUM: case MISC_BUILTIN_ADDG6S: case MISC_BUILTIN_DIVWEU: - case MISC_BUILTIN_DIVWEUO: case MISC_BUILTIN_DIVDEU: - case MISC_BUILTIN_DIVDEUO: h.uns_p[0] = 1; h.uns_p[1] = 1; h.uns_p[2] = 1; @@ -23980,7 +23993,7 @@ /* Fall through. Must be [reg+reg]. */ } - if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x)) + if (VECTOR_MEM_ALTIVEC_OR_VSX_P (GET_MODE (x)) && GET_CODE (tmp) == AND && GET_CODE (XEXP (tmp, 1)) == CONST_INT && INTVAL (XEXP (tmp, 1)) == -16) @@ -25907,49 +25920,6 @@ emit_move_insn (dest, target); } -/* Split a signbit operation on 64-bit machines with direct move. Also allow - for the value to come from memory or if it is already loaded into a GPR. */ - -void -rs6000_split_signbit (rtx dest, rtx src) -{ - machine_mode d_mode = GET_MODE (dest); - machine_mode s_mode = GET_MODE (src); - rtx dest_di = (d_mode == DImode) ? dest : gen_lowpart (DImode, dest); - rtx shift_reg = dest_di; - - gcc_assert (FLOAT128_IEEE_P (s_mode) && TARGET_POWERPC64); - - if (MEM_P (src)) - { - rtx mem = (WORDS_BIG_ENDIAN - ? adjust_address (src, DImode, 0) - : adjust_address (src, DImode, 8)); - emit_insn (gen_rtx_SET (dest_di, mem)); - } - - else - { - unsigned int r = reg_or_subregno (src); - - if (INT_REGNO_P (r)) - shift_reg = gen_rtx_REG (DImode, r + (BYTES_BIG_ENDIAN == 0)); - - else - { - /* Generate the special mfvsrd instruction to get it in a GPR. */ - gcc_assert (VSX_REGNO_P (r)); - if (s_mode == KFmode) - emit_insn (gen_signbitkf2_dm2 (dest_di, src)); - else - emit_insn (gen_signbittf2_dm2 (dest_di, src)); - } - } - - emit_insn (gen_lshrdi3 (dest_di, shift_reg, GEN_INT (63))); - return; -} - /* A subroutine of the atomic operation splitters. Jump to LABEL if COND is true. Mark the jump as unlikely to be taken. */ @@ -26588,7 +26558,7 @@ emit_insn (gen_add3_insn (breg, breg, delta_rtx)); src = replace_equiv_address (src, breg); } - else if (! rs6000_offsettable_memref_p (src, reg_mode)) + else if (! rs6000_offsettable_memref_p (src, reg_mode, true)) { if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY) { @@ -26655,7 +26625,7 @@ emit_insn (gen_add3_insn (breg, breg, delta_rtx)); dst = replace_equiv_address (dst, breg); } - else if (!rs6000_offsettable_memref_p (dst, reg_mode) + else if (!rs6000_offsettable_memref_p (dst, reg_mode, true) && GET_CODE (XEXP (dst, 0)) != LO_SUM) { if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY) @@ -26694,7 +26664,7 @@ } } else if (GET_CODE (XEXP (dst, 0)) != LO_SUM) - gcc_assert (rs6000_offsettable_memref_p (dst, reg_mode)); + gcc_assert (rs6000_offsettable_memref_p (dst, reg_mode, true)); } for (i = 0; i < nregs; i++) @@ -31988,8 +31958,9 @@ emit_insn_after (pat, get_insns ()); pop_topmost_sequence (); } - return plus_constant (Pmode, cfun->machine->split_stack_arg_pointer, - FIRST_PARM_OFFSET (current_function_decl)); + rtx ret = plus_constant (Pmode, cfun->machine->split_stack_arg_pointer, + FIRST_PARM_OFFSET (current_function_decl)); + return copy_to_reg (ret); } return virtual_incoming_args_rtx; } @@ -35647,6 +35618,11 @@ } else { + /* If we are told not to put readonly data in sdata, then don't. */ + if (TREE_READONLY (decl) && rs6000_sdata != SDATA_EABI + && !rs6000_readonly_in_sdata) + return false; + HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl)); if (size > 0 @@ -39167,6 +39143,7 @@ { "hard-dfp", RS6000_BTM_DFP, false, false }, { "hard-float", RS6000_BTM_HARD_FLOAT, false, false }, { "long-double-128", RS6000_BTM_LDBL128, false, false }, + { "powerpc64", RS6000_BTM_POWERPC64, false, false }, { "float128", RS6000_BTM_FLOAT128, false, false }, }; @@ -41657,6 +41634,38 @@ return 1; } +/* Return 1 iff UID, known to reference a swap, is both fed by a load + and a feeder of a store. */ +static unsigned int +swap_feeds_both_load_and_store (swap_web_entry *insn_entry) +{ + rtx insn = insn_entry->insn; + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + df_ref def, use; + struct df_link *link = 0; + rtx_insn *load = 0, *store = 0; + bool fed_by_load = 0; + bool feeds_store = 0; + + FOR_EACH_INSN_INFO_USE (use, insn_info) + { + link = DF_REF_CHAIN (use); + load = DF_REF_INSN (link->ref); + if (insn_is_load_p (load) && insn_is_swap_p (load)) + fed_by_load = 1; + } + + FOR_EACH_INSN_INFO_DEF (def, insn_info) + { + link = DF_REF_CHAIN (def); + store = DF_REF_INSN (link->ref); + if (insn_is_store_p (store) && insn_is_swap_p (store)) + feeds_store = 1; + } + + return fed_by_load && feeds_store; +} + /* Return TRUE if insn is a swap fed by a load from the constant pool. */ static bool const_load_sequence_p (swap_web_entry *insn_entry, rtx insn) @@ -41860,6 +41869,7 @@ { default: break; + case UNSPEC_VBPERMQ: case UNSPEC_VMRGH_DIRECT: case UNSPEC_VMRGL_DIRECT: case UNSPEC_VPACK_SIGN_SIGN_SAT: @@ -41871,6 +41881,7 @@ case UNSPEC_VPERM_UNS: case UNSPEC_VPERMHI: case UNSPEC_VPERMSI: + case UNSPEC_VPERMXOR: case UNSPEC_VPKPX: case UNSPEC_VSLDOI: case UNSPEC_VSLO: @@ -43129,6 +43140,14 @@ && !insn_entry[i].is_swap && !insn_entry[i].is_swappable) root->web_not_optimizable = 1; + /* If we have a swap that is both fed by a permuting load + and a feeder of a permuting store, then the optimization + isn't appropriate. (Consider vec_xl followed by vec_xst_be.) */ + else if (insn_entry[i].is_swap && !insn_entry[i].is_load + && !insn_entry[i].is_store + && swap_feeds_both_load_and_store (&insn_entry[i])) + root->web_not_optimizable = 1; + /* If we have permuting loads or stores that are not accompanied by a register swap, the optimization isn't appropriate. */ else if (insn_entry[i].is_load && insn_entry[i].is_swap) Index: gcc/config/rs6000/vsx.md =================================================================== diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md --- a/gcc/config/rs6000/vsx.md (revision 257042) +++ b/gcc/config/rs6000/vsx.md (revision 259627) @@ -157,6 +157,22 @@ (TF "wp") (KF "wq")]) +;; A mode attribute to disparage use of GPR registers, except for scalar +;; interger modes. +(define_mode_attr ??r [(V16QI "??r") + (V8HI "??r") + (V4SI "??r") + (V4SF "??r") + (V2DI "??r") + (V2DF "??r") + (DI "r") + (DF "??r") + (SF "??r") + (V1TI "??r") + (TI "r") + (TF "??r") + (KF "??r")]) + ;; Same size integer type for floating point data (define_mode_attr VSi [(V4SF "v4si") (V2DF "v2di") @@ -385,7 +401,7 @@ ;; VSX moves so they match first. (define_insn_and_split "*vsx_le_perm_load_" [(set (match_operand:VSX_D 0 "vsx_register_operand" "=") - (match_operand:VSX_D 1 "memory_operand" "Z"))] + (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z"))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" "#" "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" @@ -408,7 +424,7 @@ (define_insn_and_split "*vsx_le_perm_load_" [(set (match_operand:VSX_W 0 "vsx_register_operand" "=") - (match_operand:VSX_W 1 "memory_operand" "Z"))] + (match_operand:VSX_W 1 "indexed_or_indirect_operand" "Z"))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" "#" "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" @@ -433,7 +449,7 @@ (define_insn_and_split "*vsx_le_perm_load_v8hi" [(set (match_operand:V8HI 0 "vsx_register_operand" "=wa") - (match_operand:V8HI 1 "memory_operand" "Z"))] + (match_operand:V8HI 1 "indexed_or_indirect_operand" "Z"))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" "#" "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" @@ -462,7 +478,7 @@ (define_insn_and_split "*vsx_le_perm_load_v16qi" [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa") - (match_operand:V16QI 1 "memory_operand" "Z"))] + (match_operand:V16QI 1 "indexed_or_indirect_operand" "Z"))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" "#" "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" @@ -498,7 +514,7 @@ (set_attr "length" "8")]) (define_insn "*vsx_le_perm_store_" - [(set (match_operand:VSX_D 0 "memory_operand" "=Z") + [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "=Z") (match_operand:VSX_D 1 "vsx_register_operand" "+"))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" "#" @@ -506,7 +522,7 @@ (set_attr "length" "12")]) (define_split - [(set (match_operand:VSX_D 0 "memory_operand" "") + [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "") (match_operand:VSX_D 1 "vsx_register_operand" ""))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed" [(set (match_dup 2) @@ -525,7 +541,7 @@ ;; The post-reload split requires that we re-permute the source ;; register in case it is still live. (define_split - [(set (match_operand:VSX_D 0 "memory_operand" "") + [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "") (match_operand:VSX_D 1 "vsx_register_operand" ""))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed" [(set (match_dup 1) @@ -543,7 +559,7 @@ "") (define_insn "*vsx_le_perm_store_" - [(set (match_operand:VSX_W 0 "memory_operand" "=Z") + [(set (match_operand:VSX_W 0 "indexed_or_indirect_operand" "=Z") (match_operand:VSX_W 1 "vsx_register_operand" "+"))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" "#" @@ -551,7 +567,7 @@ (set_attr "length" "12")]) (define_split - [(set (match_operand:VSX_W 0 "memory_operand" "") + [(set (match_operand:VSX_W 0 "indexed_or_indirect_operand" "") (match_operand:VSX_W 1 "vsx_register_operand" ""))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed" [(set (match_dup 2) @@ -572,7 +588,7 @@ ;; The post-reload split requires that we re-permute the source ;; register in case it is still live. (define_split - [(set (match_operand:VSX_W 0 "memory_operand" "") + [(set (match_operand:VSX_W 0 "indexed_or_indirect_operand" "") (match_operand:VSX_W 1 "vsx_register_operand" ""))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed" [(set (match_dup 1) @@ -593,7 +609,7 @@ "") (define_insn "*vsx_le_perm_store_v8hi" - [(set (match_operand:V8HI 0 "memory_operand" "=Z") + [(set (match_operand:V8HI 0 "indexed_or_indirect_operand" "=Z") (match_operand:V8HI 1 "vsx_register_operand" "+wa"))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" "#" @@ -601,7 +617,7 @@ (set_attr "length" "12")]) (define_split - [(set (match_operand:V8HI 0 "memory_operand" "") + [(set (match_operand:V8HI 0 "indexed_or_indirect_operand" "") (match_operand:V8HI 1 "vsx_register_operand" ""))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed" [(set (match_dup 2) @@ -626,7 +642,7 @@ ;; The post-reload split requires that we re-permute the source ;; register in case it is still live. (define_split - [(set (match_operand:V8HI 0 "memory_operand" "") + [(set (match_operand:V8HI 0 "indexed_or_indirect_operand" "") (match_operand:V8HI 1 "vsx_register_operand" ""))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed" [(set (match_dup 1) @@ -653,7 +669,7 @@ "") (define_insn "*vsx_le_perm_store_v16qi" - [(set (match_operand:V16QI 0 "memory_operand" "=Z") + [(set (match_operand:V16QI 0 "indexed_or_indirect_operand" "=Z") (match_operand:V16QI 1 "vsx_register_operand" "+wa"))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" "#" @@ -661,7 +677,7 @@ (set_attr "length" "12")]) (define_split - [(set (match_operand:V16QI 0 "memory_operand" "") + [(set (match_operand:V16QI 0 "indexed_or_indirect_operand" "") (match_operand:V16QI 1 "vsx_register_operand" ""))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed" [(set (match_dup 2) @@ -694,7 +710,7 @@ ;; The post-reload split requires that we re-permute the source ;; register in case it is still live. (define_split - [(set (match_operand:V16QI 0 "memory_operand" "") + [(set (match_operand:V16QI 0 "indexed_or_indirect_operand" "") (match_operand:V16QI 1 "vsx_register_operand" ""))] "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed" [(set (match_dup 1) @@ -961,7 +977,7 @@ (define_insn "*vsx_mov_64bit" [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=ZwO, , , r, we, ?wQ, - ?&r, ??r, ??Y, ??r, wo, v, + ?&r, ??r, ??Y, , wo, v, ?, *r, v, ??r, wZ, v") (match_operand:VSX_M 1 "input_operand" @@ -990,7 +1006,7 @@ ;; LVX (VMX) STVX (VMX) (define_insn "*vsx_mov_32bit" [(set (match_operand:VSX_M 0 "nonimmediate_operand" - "=ZwO, , , ??r, ??Y, ??r, + "=ZwO, , , ??r, ??Y, , wo, v, ?, *r, v, ??r, wZ, v") @@ -4084,46 +4100,21 @@ ;; Vector insert/extract word at arbitrary byte values. Note, the little ;; endian version needs to adjust the byte number, and the V4SI element in -;; vinsert4b. -(define_expand "vextract4b" - [(set (match_operand:DI 0 "gpc_reg_operand") - (unspec:DI [(match_operand:V16QI 1 "vsx_register_operand") - (match_operand:QI 2 "const_0_to_12_operand")] - UNSPEC_XXEXTRACTUW))] +;; insert4b. +(define_insn "extract4b" + [(set (match_operand:V2DI 0 "vsx_register_operand") + (unspec:V2DI [(match_operand:V16QI 1 "vsx_register_operand" "wa") + (match_operand:QI 2 "const_0_to_12_operand" "n")] + UNSPEC_XXEXTRACTUW))] "TARGET_P9_VECTOR" { if (!VECTOR_ELT_ORDER_BIG) operands[2] = GEN_INT (12 - INTVAL (operands[2])); + + return "xxextractuw %x0,%x1,%2"; }) -(define_insn_and_split "*vextract4b_internal" - [(set (match_operand:DI 0 "gpc_reg_operand" "=wj,r") - (unspec:DI [(match_operand:V16QI 1 "vsx_register_operand" "wa,v") - (match_operand:QI 2 "const_0_to_12_operand" "n,n")] - UNSPEC_XXEXTRACTUW))] - "TARGET_P9_VECTOR" - "@ - xxextractuw %x0,%x1,%2 - #" - "&& reload_completed && int_reg_operand (operands[0], DImode)" - [(const_int 0)] -{ - rtx op0 = operands[0]; - rtx op1 = operands[1]; - rtx op2 = operands[2]; - rtx op0_si = gen_rtx_REG (SImode, REGNO (op0)); - rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (op1)); - - emit_move_insn (op0, op2); - if (VECTOR_ELT_ORDER_BIG) - emit_insn (gen_vextuwlx (op0_si, op0_si, op1_v4si)); - else - emit_insn (gen_vextuwrx (op0_si, op0_si, op1_v4si)); - DONE; -} - [(set_attr "type" "vecperm")]) - -(define_expand "vinsert4b" +(define_expand "insert4b" [(set (match_operand:V16QI 0 "vsx_register_operand") (unspec:V16QI [(match_operand:V4SI 1 "vsx_register_operand") (match_operand:V16QI 2 "vsx_register_operand") @@ -4141,7 +4132,7 @@ } }) -(define_insn "*vinsert4b_internal" +(define_insn "*insert4b_internal" [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa") (unspec:V16QI [(match_operand:V4SI 1 "vsx_register_operand" "wa") (match_operand:V16QI 2 "vsx_register_operand" "0") @@ -4151,26 +4142,42 @@ "xxinsertw %x0,%x1,%3" [(set_attr "type" "vecperm")]) -(define_expand "vinsert4b_di" - [(set (match_operand:V16QI 0 "vsx_register_operand") - (unspec:V16QI [(match_operand:DI 1 "vsx_register_operand") - (match_operand:V16QI 2 "vsx_register_operand") - (match_operand:QI 3 "const_0_to_12_operand")] - UNSPEC_XXINSERTW))] +(define_expand "vextract4b" + [(set (match_operand:DI 0 "gpc_reg_operand") + (unspec:DI [(match_operand:V16QI 1 "vsx_register_operand") + (match_operand:QI 2 "const_0_to_12_operand")] + UNSPEC_XXEXTRACTUW))] "TARGET_P9_VECTOR" { if (!VECTOR_ELT_ORDER_BIG) - operands[3] = GEN_INT (12 - INTVAL (operands[3])); + operands[2] = GEN_INT (12 - INTVAL (operands[2])); }) -(define_insn "*vinsert4b_di_internal" - [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa") - (unspec:V16QI [(match_operand:DI 1 "vsx_register_operand" "wj") - (match_operand:V16QI 2 "vsx_register_operand" "0") - (match_operand:QI 3 "const_0_to_12_operand" "n")] - UNSPEC_XXINSERTW))] +(define_insn_and_split "*vextract4b_internal" + [(set (match_operand:DI 0 "gpc_reg_operand" "=wj,r") + (unspec:DI [(match_operand:V16QI 1 "vsx_register_operand" "wa,v") + (match_operand:QI 2 "const_0_to_12_operand" "n,n")] + UNSPEC_XXEXTRACTUW))] "TARGET_P9_VECTOR" - "xxinsertw %x0,%x1,%3" + "@ + xxextractuw %x0,%x1,%2 + #" + "&& reload_completed && int_reg_operand (operands[0], DImode)" + [(const_int 0)] +{ + rtx op0 = operands[0]; + rtx op1 = operands[1]; + rtx op2 = operands[2]; + rtx op0_si = gen_rtx_REG (SImode, REGNO (op0)); + rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (op1)); + + emit_move_insn (op0, op2); + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_vextuwlx (op0_si, op0_si, op1_v4si)); + else + emit_insn (gen_vextuwrx (op0_si, op0_si, op1_v4si)); + DONE; +} [(set_attr "type" "vecperm")]) Index: gcc/config/rs6000/rs6000.h =================================================================== diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h --- a/gcc/config/rs6000/rs6000.h (revision 257042) +++ b/gcc/config/rs6000/rs6000.h (revision 259627) @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000. - Copyright (C) 1992-2017 Free Software Foundation, Inc. + Copyright (C) 1992-2018 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GCC. @@ -2735,6 +2735,7 @@ #define RS6000_BTM_HARD_FLOAT MASK_SOFT_FLOAT /* Hardware floating point. */ #define RS6000_BTM_LDBL128 MASK_MULTIPLE /* 128-bit long double. */ #define RS6000_BTM_64BIT MASK_64BIT /* 64-bit addressing. */ +#define RS6000_BTM_POWERPC64 MASK_POWERPC64 /* 64-bit registers. */ #define RS6000_BTM_FLOAT128 MASK_FLOAT128_TYPE /* IEEE 128-bit float. */ #define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \ @@ -2754,6 +2755,7 @@ | RS6000_BTM_DFP \ | RS6000_BTM_HARD_FLOAT \ | RS6000_BTM_LDBL128 \ + | RS6000_BTM_POWERPC64 \ | RS6000_BTM_FLOAT128) /* Define builtin enum index. */ Index: gcc/config/rs6000/altivec.md =================================================================== diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md --- a/gcc/config/rs6000/altivec.md (revision 257042) +++ b/gcc/config/rs6000/altivec.md (revision 259627) @@ -414,7 +414,6 @@ (define_insn "*restore_world" [(match_parallel 0 "restore_world_operation" [(return) - (use (reg:SI LR_REGNO)) (use (match_operand:SI 1 "call_operand" "s")) (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])] "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT" @@ -2616,42 +2615,52 @@ "lvx %0,%y1" [(set_attr "type" "vecload")]) +; The following patterns embody what lvx should usually look like. +(define_expand "altivec_lvx_" + [(set (match_operand:VM2 0 "register_operand") + (match_operand:VM2 1 "altivec_indexed_or_indirect_operand"))] + "TARGET_ALTIVEC" +{ + rtx addr = XEXP (operand1, 0); + if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) + && REG_P (XEXP (addr, 1))) + { + rtx op1 = XEXP (addr, 0); + rtx op2 = XEXP (addr, 1); + if (TARGET_64BIT) + emit_insn (gen_altivec_lvx__2op_di (operand0, op1, op2)); + else + emit_insn (gen_altivec_lvx__2op_si (operand0, op1, op2)); + } + else + { + if (TARGET_64BIT) + emit_insn (gen_altivec_lvx__1op_di (operand0, addr)); + else + emit_insn (gen_altivec_lvx__1op_si (operand0, addr)); + } + DONE; +}) + ; The next two patterns embody what lvx should usually look like. -(define_insn "altivec_lvx__2op" +(define_insn "altivec_lvx__2op_" [(set (match_operand:VM2 0 "register_operand" "=v") - (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b") - (match_operand:DI 2 "register_operand" "r")) - (const_int -16))))] - "TARGET_ALTIVEC && TARGET_64BIT" + (mem:VM2 (and:P (plus:P (match_operand:P 1 "register_operand" "b") + (match_operand:P 2 "register_operand" "r")) + (const_int -16))))] + "TARGET_ALTIVEC" "lvx %0,%1,%2" [(set_attr "type" "vecload")]) -(define_insn "altivec_lvx__1op" +(define_insn "altivec_lvx__1op_" [(set (match_operand:VM2 0 "register_operand" "=v") - (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r") - (const_int -16))))] - "TARGET_ALTIVEC && TARGET_64BIT" + (mem:VM2 (and:P (match_operand:P 1 "register_operand" "r") + (const_int -16))))] + "TARGET_ALTIVEC" "lvx %0,0,%1" [(set_attr "type" "vecload")]) -; 32-bit versions of the above. -(define_insn "altivec_lvx__2op_si" - [(set (match_operand:VM2 0 "register_operand" "=v") - (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")) - (const_int -16))))] - "TARGET_ALTIVEC && TARGET_32BIT" - "lvx %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx__1op_si" - [(set (match_operand:VM2 0 "register_operand" "=v") - (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r") - (const_int -16))))] - "TARGET_ALTIVEC && TARGET_32BIT" - "lvx %0,0,%1" - [(set_attr "type" "vecload")]) - ; This version of stvx is used only in cases where we need to force an stvx ; over any other store, and we don't care about losing CSE opportunities. ; Its primary use is for epilogue register restores. @@ -2664,42 +2673,52 @@ "stvx %1,%y0" [(set_attr "type" "vecstore")]) +; The following patterns embody what stvx should usually look like. +(define_expand "altivec_stvx_" + [(set (match_operand:VM2 1 "altivec_indexed_or_indirect_operand") + (match_operand:VM2 0 "register_operand"))] + "TARGET_ALTIVEC" +{ + rtx addr = XEXP (operand1, 0); + if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) + && REG_P (XEXP (addr, 1))) + { + rtx op1 = XEXP (addr, 0); + rtx op2 = XEXP (addr, 1); + if (TARGET_64BIT) + emit_insn (gen_altivec_stvx__2op_di (operand0, op1, op2)); + else + emit_insn (gen_altivec_stvx__2op_si (operand0, op1, op2)); + } + else + { + if (TARGET_64BIT) + emit_insn (gen_altivec_stvx__1op_di (operand0, addr)); + else + emit_insn (gen_altivec_stvx__1op_si (operand0, addr)); + } + DONE; +}) + ; The next two patterns embody what stvx should usually look like. -(define_insn "altivec_stvx__2op" - [(set (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b") - (match_operand:DI 2 "register_operand" "r")) - (const_int -16))) - (match_operand:VM2 0 "register_operand" "v"))] - "TARGET_ALTIVEC && TARGET_64BIT" +(define_insn "altivec_stvx__2op_" + [(set (mem:VM2 (and:P (plus:P (match_operand:P 1 "register_operand" "b") + (match_operand:P 2 "register_operand" "r")) + (const_int -16))) + (match_operand:VM2 0 "register_operand" "v"))] + "TARGET_ALTIVEC" "stvx %0,%1,%2" [(set_attr "type" "vecstore")]) -(define_insn "altivec_stvx__1op" - [(set (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r") - (const_int -16))) - (match_operand:VM2 0 "register_operand" "v"))] - "TARGET_ALTIVEC && TARGET_64BIT" +(define_insn "altivec_stvx__1op_" + [(set (mem:VM2 (and:P (match_operand:P 1 "register_operand" "r") + (const_int -16))) + (match_operand:VM2 0 "register_operand" "v"))] + "TARGET_ALTIVEC" "stvx %0,0,%1" [(set_attr "type" "vecstore")]) -; 32-bit versions of the above. -(define_insn "altivec_stvx__2op_si" - [(set (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")) - (const_int -16))) - (match_operand:VM2 0 "register_operand" "v"))] - "TARGET_ALTIVEC && TARGET_32BIT" - "stvx %0,%1,%2" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvx__1op_si" - [(set (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r") - (const_int -16))) - (match_operand:VM2 0 "register_operand" "v"))] - "TARGET_ALTIVEC && TARGET_32BIT" - "stvx %0,0,%1" - [(set_attr "type" "vecstore")]) - (define_expand "altivec_stvxl_" [(parallel [(set (match_operand:VM2 0 "memory_operand" "=Z") Index: gcc/config/rs6000/rs6000.md =================================================================== diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md --- a/gcc/config/rs6000/rs6000.md (revision 257042) +++ b/gcc/config/rs6000/rs6000.md (revision 259627) @@ -1,5 +1,5 @@ ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler -;; Copyright (C) 1990-2017 Free Software Foundation, Inc. +;; Copyright (C) 1990-2018 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GCC. @@ -135,9 +135,7 @@ UNSPEC_CDTBCD UNSPEC_CBCDTD UNSPEC_DIVE - UNSPEC_DIVEO UNSPEC_DIVEU - UNSPEC_DIVEUO UNSPEC_UNPACK_128BIT UNSPEC_PACK_128BIT UNSPEC_LSQ @@ -544,7 +542,7 @@ (define_code_attr su [(sign_extend "s") (zero_extend "u") (fix "s") - (unsigned_fix "s") + (unsigned_fix "u") (float "s") (unsigned_float "u")]) @@ -4757,12 +4755,19 @@ { if (FLOAT128_IEEE_P (mode)) { + rtx dest = operands[0]; + rtx src = operands[1]; + rtx tmp = gen_reg_rtx (DImode); + rtx dest_di = gen_lowpart (DImode, dest); + if (mode == KFmode) - emit_insn (gen_signbitkf2_dm (operands[0], operands[1])); + emit_insn (gen_signbitkf2_dm (tmp, src)); else if (mode == TFmode) - emit_insn (gen_signbittf2_dm (operands[0], operands[1])); + emit_insn (gen_signbittf2_dm (tmp, src)); else gcc_unreachable (); + + emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63))); DONE; } operands[2] = gen_reg_rtx (DFmode); @@ -4783,6 +4788,66 @@ } }) +;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid +;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the +;; register allocator would typically move the entire _Float128 item to GPRs (2 +;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07). +;; +;; After register allocation, if the _Float128 had originally been in GPRs, the +;; split allows the post reload phases to eliminate the move, and do the shift +;; directly with the register that contains the signbit. +(define_insn_and_split "signbit2_dm" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")] + UNSPEC_SIGNBIT))] + "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" + "@ + mfvsrd %0,%x1 + #" + "&& reload_completed && int_reg_operand (operands[1], mode)" + [(set (match_dup 0) + (match_dup 2))] +{ + operands[2] = gen_highpart (DImode, operands[1]); +} + [(set_attr "type" "mftgpr,*")]) + +;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector +;; register and then doing a direct move if the value comes from memory. On +;; little endian, we have to load the 2nd double-word to get the sign bit. +(define_insn_and_split "*signbit2_dm_mem" + [(set (match_operand:DI 0 "gpc_reg_operand" "=b") + (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")] + UNSPEC_SIGNBIT))] + "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" + "#" + "&& 1" + [(set (match_dup 0) + (match_dup 2))] +{ + rtx dest = operands[0]; + rtx src = operands[1]; + rtx addr = XEXP (src, 0); + + if (WORDS_BIG_ENDIAN) + operands[2] = adjust_address (src, DImode, 0); + + else if (REG_P (addr) || SUBREG_P (addr)) + operands[2] = adjust_address (src, DImode, 8); + + else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0)) + && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode)) + operands[2] = adjust_address (src, DImode, 8); + + else + { + rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest; + emit_insn (gen_rtx_SET (tmp, addr)); + operands[2] = change_address (src, DImode, + gen_rtx_PLUS (DImode, tmp, GEN_INT (8))); + } +}) + (define_expand "copysign3" [(set (match_dup 3) (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" ""))) @@ -4812,54 +4877,6 @@ operands[5] = CONST0_RTX (mode); }) -;; Optimize signbit on 64-bit systems with direct move to avoid doing the store -;; and load. -(define_insn_and_split "signbit2_dm" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") - (unspec:SI - [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")] - UNSPEC_SIGNBIT))] - "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" - "#" - "&& reload_completed" - [(const_int 0)] -{ - rs6000_split_signbit (operands[0], operands[1]); - DONE; -} - [(set_attr "length" "8,8,4") - (set_attr "type" "mftgpr,load,integer")]) - -(define_insn_and_split "*signbit2_dm_ext" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") - (any_extend:DI - (unspec:SI - [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")] - UNSPEC_SIGNBIT)))] - "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" - "#" - "&& reload_completed" - [(const_int 0)] -{ - rs6000_split_signbit (operands[0], operands[1]); - DONE; -} - [(set_attr "length" "8,8,4") - (set_attr "type" "mftgpr,load,integer")]) - -;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating -;; point types, which makes normal SUBREG's problematical. Instead use a -;; special pattern to avoid using a normal movdi. -(define_insn "signbit2_dm2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa") - (const_int 0)] - UNSPEC_SIGNBIT))] - "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" - "mfvsrd %0,%x1" - [(set_attr "type" "mftgpr")]) - - ;; Use an unspec rather providing an if-then-else in RTL, to prevent the ;; compiler from optimizing -0.0 (define_insn "copysign3_fcpsgn" @@ -5694,45 +5711,59 @@ xscvdpsxds %x0,%x1" [(set_attr "type" "fp")]) -(define_expand "fix_trunc2" - [(parallel [(set (match_operand: 0 "nonimmediate_operand") - (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand"))) - (clobber (match_scratch:DI 2))])] - "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT - && TARGET_VSX_SMALL_INTEGER" +;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR +;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the +;; vector registers, so we need to do direct moves to the GPRs, but SImode +;; values can go in VSX registers. Keeping the direct move part through +;; register allocation prevents the register allocator from doing a direct move +;; of the SImode value to a GPR, and then a store/load. +(define_insn_and_split "fix_trunc2" + [(set (match_operand: 0 "gpc_reg_operand" "=wJ,wJwK,r") + (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa"))) + (clobber (match_scratch:SI 2 "=X,X,wi"))] + "TARGET_DIRECT_MOVE" + "@ + fctiwz %0,%1 + xscvdpxws %x0,%x1 + #" + "&& reload_completed && int_reg_operand (operands[0], mode)" + [(set (match_dup 2) + (any_fix:SI (match_dup 1))) + (set (match_dup 3) + (match_dup 2))] { - if (MEM_P (operands[0])) - operands[0] = rs6000_address_for_fpconvert (operands[0]); -}) + operands[3] = gen_rtx_REG (SImode, REGNO (operands[0])); +} + [(set_attr "length" "4,4,8") + (set_attr "type" "fp")]) -(define_insn_and_split "*fix_trunc2_internal" - [(set (match_operand: 0 "reg_or_indexed_operand" "=wIwJ,rZ") - (fix:QHI - (match_operand:SFDF 1 "gpc_reg_operand" ","))) - (clobber (match_scratch:DI 2 "=X,wi"))] - "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT - && TARGET_VSX_SMALL_INTEGER" +(define_insn "*fix_truncsi2_p8" + [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa") + (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))] + "TARGET_DIRECT_MOVE" + "@ + fctiwz %0,%1 + xscvdpxws %x0,%x1" + [(set_attr "type" "fp")]) + +;; Keep the convert and store together through register allocation to prevent +;; the register allocator from getting clever and doing a direct move to a GPR +;; and then store for reg+offset stores. +(define_insn_and_split "*fix_trunc2_mem" + [(set (match_operand:QHSI 0 "memory_operand" "=Z") + (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa"))) + (clobber (match_scratch:SI 2 "=wa"))] + "(mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR" "#" "&& reload_completed" - [(const_int 0)] + [(set (match_dup 2) + (any_fix:SI (match_dup 1))) + (set (match_dup 0) + (match_dup 3))] { - rtx dest = operands[0]; - rtx src = operands[1]; - - if (vsx_register_operand (dest, mode)) - { - rtx di_dest = gen_rtx_REG (DImode, REGNO (dest)); - emit_insn (gen_fix_truncdi2 (di_dest, src)); - } - else - { - rtx tmp = operands[2]; - rtx tmp2 = gen_rtx_REG (mode, REGNO (tmp)); - - emit_insn (gen_fix_truncdi2 (tmp, src)); - emit_move_insn (dest, tmp2); - } - DONE; + operands[3] = (mode == SImode + ? operands[2] + : gen_rtx_REG (mode, REGNO (operands[2]))); }) (define_expand "fixuns_truncsi2" @@ -5801,75 +5832,6 @@ xscvdpuxds %x0,%x1" [(set_attr "type" "fp")]) -(define_expand "fixuns_trunc2" - [(parallel [(set (match_operand: 0 "nonimmediate_operand") - (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand"))) - (clobber (match_scratch:DI 2))])] - "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT - && TARGET_VSX_SMALL_INTEGER" -{ - if (MEM_P (operands[0])) - operands[0] = rs6000_address_for_fpconvert (operands[0]); -}) - -(define_insn_and_split "*fixuns_trunc2_internal" - [(set (match_operand: 0 "reg_or_indexed_operand" "=wIwJ,rZ") - (unsigned_fix:QHI - (match_operand:SFDF 1 "gpc_reg_operand" ","))) - (clobber (match_scratch:DI 2 "=X,wi"))] - "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT - && TARGET_VSX_SMALL_INTEGER" - "#" - "&& reload_completed" - [(const_int 0)] -{ - rtx dest = operands[0]; - rtx src = operands[1]; - - if (vsx_register_operand (dest, mode)) - { - rtx di_dest = gen_rtx_REG (DImode, REGNO (dest)); - emit_insn (gen_fixuns_truncdi2 (di_dest, src)); - } - else - { - rtx tmp = operands[2]; - rtx tmp2 = gen_rtx_REG (mode, REGNO (tmp)); - - emit_insn (gen_fixuns_truncdi2 (tmp, src)); - emit_move_insn (dest, tmp2); - } - DONE; -}) - -;; If -mvsx-small-integer, we can represent the FIX operation directly. On -;; older machines, we have to use an UNSPEC to produce a SImode and move it -;; to another location, since SImode is not allowed in vector registers. -(define_insn "*fctiwz__smallint" - [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi") - (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" ",")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_VSX_SMALL_INTEGER" - "@ - fctiwz %0,%1 - xscvdpxws %x0,%x1" - [(set_attr "type" "fp")]) - -;; Combiner pattern to prevent moving the result of converting a floating point -;; value to 32-bit integer to GPR in order to save it. -(define_insn_and_split "*fctiwz__mem" - [(set (match_operand:SI 0 "memory_operand" "=Z") - (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa"))) - (clobber (match_scratch:SI 2 "=wa"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_VSX_SMALL_INTEGER" - "#" - "&& reload_completed" - [(set (match_dup 2) - (any_fix:SI (match_dup 1))) - (set (match_dup 0) - (match_dup 2))]) - ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) ;; rather than (set (subreg:SI (reg)) (fix:SI ...)) ;; because the first makes it clear that operand 0 is not live @@ -8678,7 +8640,7 @@ ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX (define_insn "*movdi_internal64" [(set (match_operand:DI 0 "nonimmediate_operand" - "=Y, r, r, r, r, r, + "=YZ, r, r, r, r, r, ^m, ^d, ^d, ^wY, $Z, $wb, $wv, ^wi, *wo, *wo, *wv, *wi, *wi, *wv, *wv, r, *h, *h, @@ -8685,7 +8647,7 @@ ?*r, ?*wg, ?*r, ?*wj") (match_operand:DI 1 "input_operand" - "r, Y, r, I, L, nF, + "r, YZ, r, I, L, nF, d, m, d, wb, wv, wY, Z, wi, Oj, wM, OjwM, Oj, wM, wS, wB, *h, r, 0, @@ -14419,14 +14381,10 @@ (set_attr "length" "4")]) (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE - UNSPEC_DIVEO - UNSPEC_DIVEU - UNSPEC_DIVEUO]) + UNSPEC_DIVEU]) (define_int_attr div_extend [(UNSPEC_DIVE "e") - (UNSPEC_DIVEO "eo") - (UNSPEC_DIVEU "eu") - (UNSPEC_DIVEUO "euo")]) + (UNSPEC_DIVEU "eu")]) (define_insn "div_" [(set (match_operand:GPR 0 "register_operand" "=r") @@ -14803,49 +14761,45 @@ (set_attr "length" "8")]) ;; Conversion between IEEE 128-bit and integer types -(define_insn "fix_di2_hw" - [(set (match_operand:DI 0 "altivec_register_operand" "=v") - (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] - "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" - "xscvqpsdz %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "size" "128")]) -(define_insn "fixuns_di2_hw" - [(set (match_operand:DI 0 "altivec_register_operand" "=v") - (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] - "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" - "xscvqpudz %0,%1" +;; The fix function for DImode and SImode was declared earlier as a +;; define_expand. It calls into rs6000_expand_float128_convert if we don't +;; have IEEE 128-bit hardware support. QImode and HImode are not provided +;; unless we have the IEEE 128-bit hardware. +;; +;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have +;; to provide a GPR target that used direct move and a conversion in the GPR +;; which works around QImode/HImode not being allowed in vector registers in +;; ISA 2.07 (power8). +(define_insn "fix_2_hw" + [(set (match_operand:SDI 0 "altivec_register_operand" "=v") + (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xscvqpz %0,%1" [(set_attr "type" "vecfloat") (set_attr "size" "128")]) -(define_insn "fix_si2_hw" - [(set (match_operand:SI 0 "altivec_register_operand" "=v") - (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] - "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" - "xscvqpswz %0,%1" +(define_insn "fix_trunc2" + [(set (match_operand:QHI 0 "altivec_register_operand" "=v") + (any_fix:QHI + (match_operand:IEEE128 1 "altivec_register_operand" "v")))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xscvqpwz %0,%1" [(set_attr "type" "vecfloat") (set_attr "size" "128")]) -(define_insn "fixuns_si2_hw" - [(set (match_operand:SI 0 "altivec_register_operand" "=v") - (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] +;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit +;; floating point value to 8/16/32-bit integer to GPR in order to save it. +(define_insn_and_split "*fix_trunc2_mem" + [(set (match_operand:QHSI 0 "memory_operand" "=Z") + (any_fix:QHSI + (match_operand:IEEE128 1 "altivec_register_operand" "v"))) + (clobber (match_scratch:QHSI 2 "=v"))] "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" - "xscvqpuwz %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "size" "128")]) - -;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit -;; floating point value to 32-bit integer to GPR in order to save it. -(define_insn_and_split "*fix__mem" - [(set (match_operand:SI 0 "memory_operand" "=Z") - (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v"))) - (clobber (match_scratch:SI 2 "=v"))] - "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" "#" "&& reload_completed" [(set (match_dup 2) - (any_fix:SI (match_dup 1))) + (any_fix:QHSI (match_dup 1))) (set (match_dup 0) (match_dup 2))]) Index: gcc/config/rs6000/driver-rs6000.c =================================================================== diff --git a/gcc/config/rs6000/driver-rs6000.c b/gcc/config/rs6000/driver-rs6000.c --- a/gcc/config/rs6000/driver-rs6000.c (revision 257042) +++ b/gcc/config/rs6000/driver-rs6000.c (revision 259627) @@ -21,6 +21,8 @@ #include "system.h" #include "coretypes.h" #include "tm.h" +#include "diagnostic.h" +#include "opts.h" #include #ifdef _AIX @@ -36,6 +38,44 @@ # include #endif +#ifdef __linux__ +/* Canonical GCC cpu name table. */ +static const char *rs6000_supported_cpu_names[] = +{ +#define RS6000_CPU(NAME, CPU, FLAGS) NAME, +#include "rs6000-cpus.def" +#undef RS6000_CPU +}; + +/* This table holds a list of cpus where their Linux AT_PLATFORM name differs + from their GCC canonical name. The first column in a row contains the GCC + canonical cpu name and the other columns in that row contain AT_PLATFORM + names that should be mapped to the canonical name. */ + +static const char *linux_cpu_translation_table[][4] = { + { "403", "ppc403", NULL }, + { "405", "ppc405", NULL }, + { "440", "ppc440", "ppc440gp", NULL }, + { "476", "ppc470", NULL }, + { "601", "ppc601", NULL }, + { "603", "ppc603", NULL }, + { "604", "ppc604", NULL }, + { "7400", "ppc7400", NULL }, + { "7450", "ppc7450", NULL }, + { "750", "ppc750", NULL }, + { "823", "ppc823", NULL }, + { "8540", "ppc8540", NULL }, + { "8548", "ppc8548", NULL }, + { "970", "ppc970", NULL }, + { "cell", "ppc-cell-be", NULL }, + { "e500mc", "ppce500mc", NULL }, + { "e5500", "ppce5500", NULL }, + { "e6500", "ppce6500", NULL }, + { "power7", "power7+", NULL }, + { NULL } /* End of table sentinel. */ +}; +#endif + const char *host_detect_local_cpu (int argc, const char **argv); #if GCC_VERSION >= 0 @@ -156,15 +196,20 @@ #ifdef __linux__ -/* Returns AT_PLATFORM if present, otherwise generic PowerPC. */ +/* Returns the canonical AT_PLATFORM if present, otherwise NULL. */ static const char * elf_platform (void) { - int fd; + /* Used to cache the result we determine below. */ + static const char *cpu = NULL; - fd = open ("/proc/self/auxv", O_RDONLY); + /* Use the cached AT_PLATFORM cpu name if we've already determined it. */ + if (cpu != NULL) + return cpu; + int fd = open ("/proc/self/auxv", O_RDONLY); + if (fd != -1) { char buf[1024]; @@ -177,15 +222,51 @@ if (n > 0) { for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av) - switch (av->a_type) + if (av->a_type == AT_PLATFORM) { - case AT_PLATFORM: - return (const char *) av->a_un.a_val; - - default: + /* Cache the result. */ + cpu = (const char *) av->a_un.a_val; break; } } + + /* Verify that CPU is either a valid -mcpu= option name, or is a + valid alternative name. If it is a valid alternative name, then use + the canonical name. */ + if (cpu != NULL) + { + size_t i, j; + char *s; + + /* Check if AT_PLATFORM is a GCC canonical cpu name. */ + for (i = 0; i < ARRAY_SIZE (rs6000_supported_cpu_names); i++) + if (!strcmp (cpu, rs6000_supported_cpu_names[i])) + return cpu; + + /* Check if AT_PLATFORM can be translated to a canonical cpu name. */ + for (i = 0; linux_cpu_translation_table[i][0] != NULL; i++) + { + const char *canonical = linux_cpu_translation_table[i][0]; + for (j = 1; linux_cpu_translation_table[i][j] != NULL; j++) + if (!strcmp (cpu, linux_cpu_translation_table[i][j])) + { + /* Cache the result. */ + cpu = canonical; + return cpu; + } + } + + /* The kernel returned an AT_PLATFORM name we do not support. */ + auto_vec candidates; + for (i = 0; i < ARRAY_SIZE (rs6000_supported_cpu_names); i++) + candidates.safe_push (rs6000_supported_cpu_names[i]); + candidates_list_and_hint (cpu, s, candidates); + fatal_error ( + input_location, + "Unsupported cpu name returned from kernel for -mcpu=native: %s\n" + "Please use an explicit cpu name. Valid cpu names are: %s", + cpu, s); + } } return NULL; } Index: gcc/config/rs6000/altivec.h =================================================================== diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h --- a/gcc/config/rs6000/altivec.h (revision 257042) +++ b/gcc/config/rs6000/altivec.h (revision 259627) @@ -398,8 +398,8 @@ #define vec_vctzd __builtin_vec_vctzd #define vec_vctzh __builtin_vec_vctzh #define vec_vctzw __builtin_vec_vctzw -#define vec_vextract4b __builtin_vec_vextract4b -#define vec_vinsert4b __builtin_vec_vinsert4b +#define vec_extract4b __builtin_vec_extract4b +#define vec_insert4b __builtin_vec_insert4b #define vec_vprtyb __builtin_vec_vprtyb #define vec_vprtybd __builtin_vec_vprtybd #define vec_vprtybw __builtin_vec_vprtybw Index: gcc/config/arm/arm-builtins.c =================================================================== diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c --- a/gcc/config/arm/arm-builtins.c (revision 257042) +++ b/gcc/config/arm/arm-builtins.c (revision 259627) @@ -2576,7 +2576,7 @@ icode = CODE_FOR_set_fpscr; arg0 = CALL_EXPR_ARG (exp, 0); op0 = expand_normal (arg0); - pat = GEN_FCN (icode) (op0); + pat = GEN_FCN (icode) (force_reg (SImode, op0)); } emit_insn (pat); return target; @@ -2584,7 +2584,9 @@ case ARM_BUILTIN_CMSE_NONSECURE_CALLER: target = gen_reg_rtx (SImode); op0 = arm_return_addr (0, NULL_RTX); - emit_insn (gen_addsi3 (target, op0, const1_rtx)); + emit_insn (gen_andsi3 (target, op0, const1_rtx)); + op1 = gen_rtx_EQ (SImode, target, const0_rtx); + emit_insn (gen_cstoresi4 (target, op1, target, const0_rtx)); return target; case ARM_BUILTIN_TEXTRMSB: Index: gcc/config/arm/arm.c =================================================================== diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c --- a/gcc/config/arm/arm.c (revision 257042) +++ b/gcc/config/arm/arm.c (revision 259627) @@ -19097,6 +19097,11 @@ static int arm_compute_static_chain_stack_bytes (void) { + /* Once the value is updated from the init value of -1, do not + re-compute. */ + if (cfun->machine->static_chain_stack_bytes != -1) + return cfun->machine->static_chain_stack_bytes; + /* See the defining assertion in arm_expand_prologue. */ if (IS_NESTED (arm_current_func_type ()) && ((TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM) @@ -21395,6 +21400,11 @@ emit_insn (gen_movsi (stack_pointer_rtx, r1)); } + /* Let's compute the static_chain_stack_bytes required and store it. Right + now the value must the -1 as stored by arm_init_machine_status (). */ + cfun->machine->static_chain_stack_bytes + = arm_compute_static_chain_stack_bytes (); + /* The static chain register is the same as the IP register. If it is clobbered when creating the frame, we need to save and restore it. */ clobber_ip = IS_NESTED (func_type) @@ -24542,6 +24552,7 @@ #if ARM_FT_UNKNOWN != 0 machine->func_type = ARM_FT_UNKNOWN; #endif + machine->static_chain_stack_bytes = -1; return machine; } @@ -26853,7 +26864,10 @@ arm_array_mode_supported_p (machine_mode mode, unsigned HOST_WIDE_INT nelems) { - if (TARGET_NEON + /* We don't want to enable interleaved loads and stores for BYTES_BIG_ENDIAN + for now, as the lane-swapping logic needs to be extended in the expanders. + See PR target/82518. */ + if (TARGET_NEON && !BYTES_BIG_ENDIAN && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode)) && (nelems >= 2 && nelems <= 4)) return true; Index: gcc/config/arm/arm.h =================================================================== diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h --- a/gcc/config/arm/arm.h (revision 257042) +++ b/gcc/config/arm/arm.h (revision 259627) @@ -1420,6 +1420,9 @@ machine_mode thumb1_cc_mode; /* Set to 1 after arm_reorg has started. */ int after_arm_reorg; + /* The number of bytes used to store the static chain register on the + stack, above the stack frame. */ + int static_chain_stack_bytes; } machine_function; #endif Index: gcc/config/arm/neon.md =================================================================== diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md --- a/gcc/config/arm/neon.md (revision 257042) +++ b/gcc/config/arm/neon.md (revision 259627) @@ -1143,12 +1143,12 @@ ) (define_insn_and_split "ashldi3_neon" - [(set (match_operand:DI 0 "s_register_operand" "= w, w,?&r,?r,?&r, ?w,w") - (ashift:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, 0, r, 0w,w") - (match_operand:SI 2 "general_operand" "rUm, i, r, i, i,rUm,i"))) - (clobber (match_scratch:SI 3 "= X, X,?&r, X, X, X,X")) - (clobber (match_scratch:SI 4 "= X, X,?&r, X, X, X,X")) - (clobber (match_scratch:DI 5 "=&w, X, X, X, X, &w,X")) + [(set (match_operand:DI 0 "s_register_operand" "= w, w, &r, r, &r, ?w,?w") + (ashift:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, 0, r, 0w, w") + (match_operand:SI 2 "general_operand" "rUm, i, r, i, i,rUm, i"))) + (clobber (match_scratch:SI 3 "= X, X, &r, X, X, X, X")) + (clobber (match_scratch:SI 4 "= X, X, &r, X, X, X, X")) + (clobber (match_scratch:DI 5 "=&w, X, X, X, X, &w, X")) (clobber (reg:CC_C CC_REGNUM))] "TARGET_NEON" "#" @@ -1243,7 +1243,7 @@ ;; ashrdi3_neon ;; lshrdi3_neon (define_insn_and_split "di3_neon" - [(set (match_operand:DI 0 "s_register_operand" "= w, w,?&r,?r,?&r,?w,?w") + [(set (match_operand:DI 0 "s_register_operand" "= w, w, &r, r, &r,?w,?w") (RSHIFTS:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, 0, r,0w, w") (match_operand:SI 2 "reg_or_int_operand" " r, i, r, i, i, r, i"))) (clobber (match_scratch:SI 3 "=2r, X, &r, X, X,2r, X")) Index: gcc/config/arm/arm.md =================================================================== diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md --- a/gcc/config/arm/arm.md (revision 257042) +++ b/gcc/config/arm/arm.md (revision 259627) @@ -4498,16 +4498,13 @@ (set_attr "type" "load1")]) (define_insn "unaligned_loadhis" - [(set (match_operand:SI 0 "s_register_operand" "=l,r") + [(set (match_operand:SI 0 "s_register_operand" "=r") (sign_extend:SI - (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")] + (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")] UNSPEC_UNALIGNED_LOAD)))] "unaligned_access" "ldrsh%?\t%0, %1\t@ unaligned" - [(set_attr "arch" "t2,any") - (set_attr "length" "2,4") - (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "yes,no") + [(set_attr "predicable" "yes") (set_attr "type" "load_byte")]) (define_insn "unaligned_loadhiu" Index: gcc/config/pa/predicates.md =================================================================== diff --git a/gcc/config/pa/predicates.md b/gcc/config/pa/predicates.md --- a/gcc/config/pa/predicates.md (revision 257042) +++ b/gcc/config/pa/predicates.md (revision 259627) @@ -277,6 +277,9 @@ case HImode: return true; + case VOIDmode: + return false; + default: return (INTVAL (op) % GET_MODE_SIZE (mode)) == 0; } Index: gcc/config/pa/pa64-hpux.h =================================================================== diff --git a/gcc/config/pa/pa64-hpux.h b/gcc/config/pa/pa64-hpux.h --- a/gcc/config/pa/pa64-hpux.h (revision 257042) +++ b/gcc/config/pa/pa64-hpux.h (revision 259627) @@ -245,9 +245,19 @@ /* We need to use the HP style for internal labels. */ #undef ASM_GENERATE_INTERNAL_LABEL -#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ - sprintf (LABEL, "*%c$%s%04ld", (PREFIX)[0], (PREFIX) + 1, (long)(NUM)) +#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ + do \ + { \ + char *__p; \ + (LABEL)[0] = '*'; \ + (LABEL)[1] = (PREFIX)[0]; \ + (LABEL)[2] = '$'; \ + __p = stpcpy (&(LABEL)[3], &(PREFIX)[1]); \ + sprint_ul (__p, (unsigned long) (NUM)); \ + } \ + while (0) + #else /* USING_ELFOS_H */ /* We are not using GAS. */ Index: gcc/config/pa/pa.md =================================================================== diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md --- a/gcc/config/pa/pa.md (revision 257042) +++ b/gcc/config/pa/pa.md (revision 259627) @@ -2536,24 +2536,40 @@ xoperands[0] = operands[0]; xoperands[1] = operands[1]; - xoperands[2] = gen_label_rtx (); - (*targetm.asm_out.internal_label) (asm_out_file, \"L\", - CODE_LABEL_NUMBER (xoperands[2])); - output_asm_insn (\"mfia %0\", xoperands); + if (GET_CODE (operands[1]) == LABEL_REF + && !LABEL_REF_NONLOCAL_P (operands[1])) + { + xoperands[2] = gen_label_rtx (); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", + CODE_LABEL_NUMBER (xoperands[2])); + output_asm_insn (\"mfia %0\", xoperands); - /* If we're trying to load the address of a label that happens to be - close, then we can use a shorter sequence. */ - if (GET_CODE (operands[1]) == LABEL_REF - && !LABEL_REF_NONLOCAL_P (operands[1]) - && INSN_ADDRESSES_SET_P () - && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) - - INSN_ADDRESSES (INSN_UID (insn))) < 8100) - output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); + /* If we're trying to load the address of a label that happens to be + close, then we can use a shorter sequence. */ + if (INSN_ADDRESSES_SET_P () + && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) + - INSN_ADDRESSES (INSN_UID (insn))) < 8100) + output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); + else + { + output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); + output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); + } + } else { - output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); - output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); + /* Load using linkage table. */ + if (TARGET_64BIT) + { + output_asm_insn (\"addil LT%%%1,%%r27\", xoperands); + output_asm_insn (\"ldd RT%%%1(%0),%0\", xoperands); + } + else + { + output_asm_insn (\"addil LT%%%1,%%r19\", xoperands); + output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands); + } } return \"\"; }" @@ -2570,25 +2586,33 @@ xoperands[0] = operands[0]; xoperands[1] = operands[1]; - xoperands[2] = gen_label_rtx (); - output_asm_insn (\"bl .+8,%0\", xoperands); - output_asm_insn (\"depi 0,31,2,%0\", xoperands); - (*targetm.asm_out.internal_label) (asm_out_file, \"L\", - CODE_LABEL_NUMBER (xoperands[2])); + if (GET_CODE (operands[1]) == LABEL_REF + && !LABEL_REF_NONLOCAL_P (operands[1])) + { + xoperands[2] = gen_label_rtx (); + output_asm_insn (\"bl .+8,%0\", xoperands); + output_asm_insn (\"depi 0,31,2,%0\", xoperands); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", + CODE_LABEL_NUMBER (xoperands[2])); - /* If we're trying to load the address of a label that happens to be - close, then we can use a shorter sequence. */ - if (GET_CODE (operands[1]) == LABEL_REF - && !LABEL_REF_NONLOCAL_P (operands[1]) - && INSN_ADDRESSES_SET_P () - && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) - - INSN_ADDRESSES (INSN_UID (insn))) < 8100) - output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); + /* If we're trying to load the address of a label that happens to be + close, then we can use a shorter sequence. */ + if (INSN_ADDRESSES_SET_P () + && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) + - INSN_ADDRESSES (INSN_UID (insn))) < 8100) + output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); + else + { + output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); + output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); + } + } else { - output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); - output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); + /* Load using linkage table. */ + output_asm_insn (\"addil LT%%%1,%%r19\", xoperands); + output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands); } return \"\"; }" Index: gcc/config/pa/pa.c =================================================================== diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c --- a/gcc/config/pa/pa.c (revision 257042) +++ b/gcc/config/pa/pa.c (revision 259627) @@ -1725,9 +1725,7 @@ } else emit_move_insn (scratch_reg, XEXP (op1, 0)); - emit_insn (gen_rtx_SET (operand0, - replace_equiv_address (op1, scratch_reg))); - return 1; + op1 = replace_equiv_address (op1, scratch_reg); } } else if ((!INT14_OK_STRICT && symbolic_memory_operand (op1, VOIDmode)) @@ -1737,10 +1735,10 @@ /* Load memory address into SCRATCH_REG. */ scratch_reg = force_mode (word_mode, scratch_reg); emit_move_insn (scratch_reg, XEXP (op1, 0)); - emit_insn (gen_rtx_SET (operand0, - replace_equiv_address (op1, scratch_reg))); - return 1; + op1 = replace_equiv_address (op1, scratch_reg); } + emit_insn (gen_rtx_SET (operand0, op1)); + return 1; } else if (scratch_reg && FP_REG_P (operand1) @@ -1778,9 +1776,7 @@ } else emit_move_insn (scratch_reg, XEXP (op0, 0)); - emit_insn (gen_rtx_SET (replace_equiv_address (op0, scratch_reg), - operand1)); - return 1; + op0 = replace_equiv_address (op0, scratch_reg); } } else if ((!INT14_OK_STRICT && symbolic_memory_operand (op0, VOIDmode)) @@ -1790,10 +1786,10 @@ /* Load memory address into SCRATCH_REG. */ scratch_reg = force_mode (word_mode, scratch_reg); emit_move_insn (scratch_reg, XEXP (op0, 0)); - emit_insn (gen_rtx_SET (replace_equiv_address (op0, scratch_reg), - operand1)); - return 1; + op0 = replace_equiv_address (op0, scratch_reg); } + emit_insn (gen_rtx_SET (op0, operand1)); + return 1; } /* Handle secondary reloads for loads of FP registers from constant expressions by forcing the constant into memory. For the most part, @@ -4562,13 +4558,17 @@ lcla2 and load_offset_label_address insn patterns. */ rtx reg = gen_reg_rtx (SImode); rtx_code_label *label_rtx = gen_label_rtx (); - rtx mcount = gen_rtx_MEM (Pmode, gen_rtx_SYMBOL_REF (Pmode, "_mcount")); int reg_parm_stack_space = REG_PARM_STACK_SPACE (NULL_TREE); - rtx arg_bytes, begin_label_rtx; + rtx arg_bytes, begin_label_rtx, mcount, sym; rtx_insn *call_insn; char begin_label_name[16]; bool use_mcount_pcrel_call; + /* Set up call destination. */ + sym = gen_rtx_SYMBOL_REF (Pmode, "_mcount"); + pa_encode_label (sym); + mcount = gen_rtx_MEM (Pmode, sym); + /* If we can reach _mcount with a pc-relative call, we can optimize loading the address of the current function. This requires linker long branch stub support. */ Index: gcc/config/pa/pa.h =================================================================== diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h --- a/gcc/config/pa/pa.h (revision 257042) +++ b/gcc/config/pa/pa.h (revision 259627) @@ -1153,9 +1153,19 @@ PREFIX is the class of label and NUM is the number within the class. This is suitable for output with `assemble_name'. */ -#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf (LABEL, "*%c$%s%04ld", (PREFIX)[0], (PREFIX) + 1, (long)(NUM)) +#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ + do \ + { \ + char *__p; \ + (LABEL)[0] = '*'; \ + (LABEL)[1] = (PREFIX)[0]; \ + (LABEL)[2] = '$'; \ + __p = stpcpy (&(LABEL)[3], &(PREFIX)[1]); \ + sprint_ul (__p, (unsigned long) (NUM)); \ + } \ + while (0) + /* Output the definition of a compiler-generated label named NAME. */ #define ASM_OUTPUT_INTERNAL_LABEL(FILE,NAME) \ @@ -1193,7 +1203,7 @@ /* This is how to output an element of a case-vector that is absolute. */ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - fprintf (FILE, "\t.word L$%04d\n", VALUE) + fprintf (FILE, "\t.word L$%d\n", VALUE) /* This is how to output an element of a case-vector that is relative. Since we always place jump tables in the text section, the difference @@ -1200,7 +1210,7 @@ is absolute and requires no relocation. */ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ - fprintf (FILE, "\t.word L$%04d-L$%04d\n", VALUE, REL) + fprintf (FILE, "\t.word L$%d-L$%d\n", VALUE, REL) /* This is how to output an absolute case-vector. */ Index: gcc/config/msp430/msp430.c =================================================================== diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c --- a/gcc/config/msp430/msp430.c (revision 257042) +++ b/gcc/config/msp430/msp430.c (revision 259627) @@ -905,6 +905,8 @@ { if (mode == PSImode && msp430x) return 1; + if (mode == CPSImode && msp430x) + return 2; return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); } @@ -927,6 +929,8 @@ { if (mode == PSImode) return 2; + if (mode == CPSImode) + return 4; return msp430_hard_regno_nregs (regno, mode); } Index: gcc/dce.c =================================================================== diff --git a/gcc/dce.c b/gcc/dce.c --- a/gcc/dce.c (revision 257042) +++ b/gcc/dce.c (revision 259627) @@ -131,6 +131,12 @@ && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER) return false; + /* Callee-save restores are needed. */ + if (RTX_FRAME_RELATED_P (insn) + && crtl->shrink_wrapped_separate + && find_reg_note (insn, REG_CFA_RESTORE, NULL)) + return false; + body = PATTERN (insn); switch (GET_CODE (body)) { @@ -589,15 +595,6 @@ if (!dbg_cnt (dce)) continue; - if (crtl->shrink_wrapped_separate - && find_reg_note (insn, REG_CFA_RESTORE, NULL)) - { - if (dump_file) - fprintf (dump_file, "DCE: NOT deleting insn %d, it's a " - "callee-save restore\n", INSN_UID (insn)); - continue; - } - if (dump_file) fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn)); Index: gcc/params.def =================================================================== diff --git a/gcc/params.def b/gcc/params.def --- a/gcc/params.def (revision 257042) +++ b/gcc/params.def (revision 259627) @@ -344,11 +344,11 @@ "The maximum number of unswitchings in a single loop.", 3, 0, 0) -/* The maximum number of insns in loop header duplicated by he copy loop +/* The maximum number of insns in loop header duplicated by the copy loop headers pass. */ DEFPARAM(PARAM_MAX_LOOP_HEADER_INSNS, "max-loop-header-insns", - "The maximum number of insns in loop header duplicated by he copy loop headers pass.", + "The maximum number of insns in loop header duplicated by the copy loop headers pass.", 20, 0, 0) /* The maximum number of iterations of a loop the brute force algorithm Index: gcc/ipa-icf.c =================================================================== diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c --- a/gcc/ipa-icf.c (revision 257042) +++ b/gcc/ipa-icf.c (revision 259627) @@ -2132,23 +2132,6 @@ return m_hash; } -/* Set all points-to UIDs of aliases pointing to node N as UID. */ - -static void -set_alias_uids (symtab_node *n, int uid) -{ - ipa_ref *ref; - FOR_EACH_ALIAS (n, ref) - { - if (dump_file) - fprintf (dump_file, " Setting points-to UID of [%s] as %d\n", - xstrdup_for_dump (ref->referring->asm_name ()), uid); - - SET_DECL_PT_UID (ref->referring->decl, uid); - set_alias_uids (ref->referring, uid); - } -} - /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can be applied. */ @@ -2275,7 +2258,6 @@ if (dump_file) fprintf (dump_file, "Unified; Variable alias has been created.\n"); - set_alias_uids (original, DECL_UID (original->decl)); return true; } } @@ -2295,7 +2277,7 @@ sem_item_optimizer::sem_item_optimizer () : worklist (0), m_classes (0), m_classes_count (0), m_cgraph_node_hooks (NULL), - m_varpool_node_hooks (NULL) + m_varpool_node_hooks (NULL), m_merged_variables () { m_items.create (0); bitmap_obstack_initialize (&m_bmstack); @@ -2320,6 +2302,7 @@ m_items.release (); bitmap_obstack_release (&m_bmstack); + m_merged_variables.release (); } /* Write IPA ICF summary for symbols. */ @@ -3571,13 +3554,103 @@ } if (dbg_cnt (merged_ipa_icf)) - merged_p |= source->merge (alias); + { + bool merged = source->merge (alias); + merged_p |= merged; + + if (merged && alias->type == VAR) + { + symtab_pair p = symtab_pair (source->node, alias->node); + m_merged_variables.safe_push (p); + } + } } } + if (!m_merged_variables.is_empty ()) + fixup_points_to_sets (); + return merged_p; } +/* Fixup points to set PT. */ + +void +sem_item_optimizer::fixup_pt_set (struct pt_solution *pt) +{ + if (pt->vars == NULL) + return; + + unsigned i; + symtab_pair *item; + FOR_EACH_VEC_ELT (m_merged_variables, i, item) + if (bitmap_bit_p (pt->vars, DECL_UID (item->second->decl))) + bitmap_set_bit (pt->vars, DECL_UID (item->first->decl)); +} + +/* Set all points-to UIDs of aliases pointing to node N as UID. */ + +static void +set_alias_uids (symtab_node *n, int uid) +{ + ipa_ref *ref; + FOR_EACH_ALIAS (n, ref) + { + if (dump_file) + fprintf (dump_file, " Setting points-to UID of [%s] as %d\n", + xstrdup_for_dump (ref->referring->asm_name ()), uid); + + SET_DECL_PT_UID (ref->referring->decl, uid); + set_alias_uids (ref->referring, uid); + } +} + +/* Fixup points to analysis info. */ + +void +sem_item_optimizer::fixup_points_to_sets (void) +{ + /* TODO: remove in GCC 9 and trigger PTA re-creation after IPA passes. */ + cgraph_node *cnode; + + FOR_EACH_DEFINED_FUNCTION (cnode) + { + tree name; + unsigned i; + function *fn = DECL_STRUCT_FUNCTION (cnode->decl); + if (!gimple_in_ssa_p (fn)) + continue; + + FOR_EACH_SSA_NAME (i, name, fn) + if (POINTER_TYPE_P (TREE_TYPE (name)) + && SSA_NAME_PTR_INFO (name)) + fixup_pt_set (&SSA_NAME_PTR_INFO (name)->pt); + fixup_pt_set (&fn->gimple_df->escaped); + + /* The above get's us to 99% I guess, at least catching the + address compares. Below also gets us aliasing correct + but as said we're giving leeway to the situation with + readonly vars anyway, so ... */ + basic_block bb; + FOR_EACH_BB_FN (bb, fn) + for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); + gsi_next (&gsi)) + { + gcall *call = dyn_cast (gsi_stmt (gsi)); + if (call) + { + fixup_pt_set (gimple_call_use_set (call)); + fixup_pt_set (gimple_call_clobber_set (call)); + } + } + } + + unsigned i; + symtab_pair *item; + FOR_EACH_VEC_ELT (m_merged_variables, i, item) + set_alias_uids (item->first, DECL_UID (item->first->decl)); +} + /* Dump function prints all class members to a FILE with an INDENT. */ void Index: gcc/ipa-icf.h =================================================================== diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h --- a/gcc/ipa-icf.h (revision 257042) +++ b/gcc/ipa-icf.h (revision 259627) @@ -141,6 +141,8 @@ unsigned int index; }; +typedef std::pair symtab_pair; + /* Semantic item is a base class that encapsulates all shared functionality for both semantic function and variable items. */ class sem_item @@ -563,6 +565,12 @@ processed. */ bool merge_classes (unsigned int prev_class_count); + /* Fixup points to analysis info. */ + void fixup_points_to_sets (void); + + /* Fixup points to set PT. */ + void fixup_pt_set (struct pt_solution *pt); + /* Adds a newly created congruence class CLS to worklist. */ void worklist_push (congruence_class *cls); @@ -632,6 +640,10 @@ /* Bitmap stack. */ bitmap_obstack m_bmstack; + + /* Vector of merged variables. Needed for fixup of points-to-analysis + info. */ + vec m_merged_variables; }; // class sem_item_optimizer } // ipa_icf namespace Index: libgfortran/ChangeLog =================================================================== diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog --- a/libgfortran/ChangeLog (revision 257042) +++ b/libgfortran/ChangeLog (revision 259627) @@ -1,3 +1,10 @@ +2018-02-18 Jerry DeLisle + + Backport from trunk + PR libgfortran/84412 + * io/transfer.c (finalize_transfer): After completng an internal unit + I/O operation, clear internal_unit_kind. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: libgfortran/io/transfer.c =================================================================== diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c --- a/libgfortran/io/transfer.c (revision 257042) +++ b/libgfortran/io/transfer.c (revision 259627) @@ -3987,6 +3987,10 @@ if (dtp->u.p.unit_is_internal) { + /* The unit structure may be reused later so clear the + internal unit kind. */ + dtp->u.p.current_unit->internal_unit_kind = 0; + fbuf_destroy (dtp->u.p.current_unit); if (dtp->u.p.current_unit && (dtp->u.p.current_unit->child_dtio == 0) Index: libcpp/include/cpplib.h =================================================================== diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h --- a/libcpp/include/cpplib.h (revision 257042) +++ b/libcpp/include/cpplib.h (revision 259627) @@ -702,7 +702,7 @@ BT_COUNTER, /* `__COUNTER__' */ BT_HAS_ATTRIBUTE, /* `__has_attribute__(x)' */ BT_FIRST_USER, /* User defined builtin macros. */ - BT_LAST_USER = BT_FIRST_USER + 31 + BT_LAST_USER = BT_FIRST_USER + 63 }; #define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE)) Index: libcpp/ChangeLog =================================================================== diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog --- a/libcpp/ChangeLog (revision 257042) +++ b/libcpp/ChangeLog (revision 259627) @@ -1,3 +1,19 @@ +2018-03-03 Jakub Jelinek + + Backported from mainline + 2018-01-31 Jakub Jelinek + + PR preprocessor/69869 + * traditional.c (skip_macro_block_comment): Return bool, true if + the macro block comment is unterminated. + (copy_comment): Use return value from skip_macro_block_comment instead + of always false. + + 2018-01-27 Jakub Jelinek + + * include/cpplib.h (enum cpp_builtin_type): Change BT_LAST_USER from + BT_FIRST_USER + 31 to BT_FIRST_USER + 63. + 2018-01-25 Release Manager * GCC 7.3.0 released. Index: libcpp/traditional.c =================================================================== diff --git a/libcpp/traditional.c b/libcpp/traditional.c --- a/libcpp/traditional.c (revision 257042) +++ b/libcpp/traditional.c (revision 259627) @@ -119,8 +119,11 @@ } /* Skip a C-style block comment in a macro as a result of -CC. - Buffer->cur points to the initial asterisk of the comment. */ -static void + PFILE->buffer->cur points to the initial asterisk of the comment, + change it to point to after the '*' and '/' characters that terminate it. + Return true if the macro has not been termined, in that case set + PFILE->buffer->cur to the end of the buffer. */ +static bool skip_macro_block_comment (cpp_reader *pfile) { const uchar *cur = pfile->buffer->cur; @@ -131,10 +134,15 @@ /* People like decorating comments with '*', so check for '/' instead for efficiency. */ - while(! (*cur++ == '/' && cur[-2] == '*') ) - ; + while (! (*cur++ == '/' && cur[-2] == '*')) + if (cur[-1] == '\n') + { + pfile->buffer->cur = cur - 1; + return true; + } pfile->buffer->cur = cur; + return false; } /* CUR points to the asterisk introducing a comment in the current @@ -158,7 +166,7 @@ buffer->cur = cur; if (pfile->context->prev) - unterminated = false, skip_macro_block_comment (pfile); + unterminated = skip_macro_block_comment (pfile); else unterminated = _cpp_skip_block_comment (pfile);