[gcc-6] 178/401: * Update to SVN 20160724 (r238695, 6.1.1) from the gcc-6-branch.

Ximin Luo infinity0 at debian.org
Wed Apr 5 15:48:59 UTC 2017


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch pu/reproducible_builds
in repository gcc-6.

commit b78c180e82a7177951efc365c90dd081701eea67
Author: doko <doko at 6ca36cf4-e1d1-0310-8c6f-e303bb2178ca>
Date:   Sun Jul 24 18:20:17 2016 +0000

      * Update to SVN 20160724 (r238695, 6.1.1) from the gcc-6-branch.
    
    
    git-svn-id: svn://anonscm.debian.org/gcccvs/branches/sid/gcc-6@8924 6ca36cf4-e1d1-0310-8c6f-e303bb2178ca
---
 debian/changelog                |    23 +-
 debian/patches/svn-updates.diff | 16342 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 15980 insertions(+), 385 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 2234141..cc74a23 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,26 @@
 gcc-6 (6.1.1-10) UNRELEASED; urgency=medium
 
+  * Update to SVN 20160724 (r238695, 6.1.1) from the gcc-6-branch.
+    - Fix PR libstdc++/71856, PR libstdc++/71320, PR c++/71214,
+      PR sanitizer/71953, PR fortran/71688, PR rtl-optimization/71916,
+      PR debug/71855, PR middle-end/71874, PR target/71493 (PPC),
+      PR rtl-optimization/71634, PR target/71733 (PPC), PR ipa/71624,
+      PR target/71805 (PPC), PR target/70098 (PPC), PR target/71763 (PPC),
+      PR middle-end/71758, PR tree-optimization/71823, PR middle-end/71606,
+      PR tree-optimization/71518, PR target/71806 (PPC), PR target/71720 (PPC),
+      PR middle-end/64516, PR tree-optimization/71264, PR middle-end/71423,
+      PR tree-optimization/71521, PR tree-optimization/71452, PR target/50739,
+      PR tree-optimization/71522, PR c++/55922, PR c++/63151, PR c++/70709,
+      PR c++/70778, PR c++/71738, PR c++/71350, PR c++/71748, PR c++/52746,
+      PR c++/69223, PR c++/71630, PR c++/71913, PR c++/71728, PR c++/71941,
+      PR c++/70822, PR c++/70106, PR c++/67565, PR c++/67579, PR c++/71843,
+      PR c++/70781, PR c++/71896, PR c++/71092, PR c++/71117, PR c++/71495,
+      PR c++/71511, PR c++/71513, PR c++/71604, PR c++/54430, PR c++/71711,
+      PR c++/71814, PR c++/71718, PR c++/70824, PR c++/71909, PR c++/71835,
+      PR c++/71828, PR c++/71822, PR c++/71871, PR c++/70869, PR c++/71054,
+      PR fortran/71807, PR fortran/70842, PR fortran/71764, PR fortran/71623,
+      PR fortran/71783.
+
   [ Matthias Klose ]
   * Build-depend on gnat-6 instead of gnat-5 on development distros.
 
@@ -7,7 +28,7 @@ gcc-6 (6.1.1-10) UNRELEASED; urgency=medium
   * Replace libjava-mips64el-proposed.diff by the corresponding patch
     taken from trunk.
 
- -- Matthias Klose <doko at debian.org>  Fri, 08 Jul 2016 14:21:00 +0200
+ -- Matthias Klose <doko at debian.org>  Sun, 24 Jul 2016 19:42:10 +0200
 
 gcc-6 (6.1.1-9) unstable; urgency=medium
 
diff --git a/debian/patches/svn-updates.diff b/debian/patches/svn-updates.diff
index 506e234..4bde4dc 100644
--- a/debian/patches/svn-updates.diff
+++ b/debian/patches/svn-updates.diff
@@ -1,10 +1,10 @@
-# DP: updates from the 6 branch upto 20160705 (r237999).
+# DP: updates from the 6 branch upto 20160724 (r238695).
 
 last_update()
 {
 	cat > ${dir}LAST_UPDATED <EOF
-Tue Jul  5 10:54:16 CEST 2016
-Tue Jul  5 08:54:16 UTC 2016 (revision 237999)
+Sun Jul 24 19:39:27 CEST 2016
+Sun Jul 24 17:39:27 UTC 2016 (revision 238695)
 EOF
 }
 
@@ -1846,7 +1846,36 @@ Index: libstdc++-v3/src/filesystem/ops.cc
    }
  } // namespace
  
-@@ -1138,7 +1172,7 @@
+@@ -1050,6 +1084,28 @@
+ 
+ void fs::permissions(const path& p, perms prms, error_code& ec) noexcept
+ {
++  const bool add = is_set(prms, perms::add_perms);
++  const bool remove = is_set(prms, perms::remove_perms);
++  if (add && remove)
++    {
++      ec = std::make_error_code(std::errc::invalid_argument);
++      return;
++    }
++
++  prms &= perms::mask;
++
++  if (add || remove)
++    {
++      auto st = status(p, ec);
++      if (ec)
++	return;
++      auto curr = st.permissions();
++      if (add)
++	prms |= curr;
++      else
++	prms = curr & ~prms;
++    }
++
+ #if _GLIBCXX_USE_FCHMODAT
+   if (::fchmodat(AT_FDCWD, p.c_str(), static_cast<mode_t>(prms), 0))
+ #else
+@@ -1138,7 +1194,7 @@
    uintmax_t count = 0;
    if (ec.value() == 0 && fs.type() == file_type::directory)
      for (directory_iterator d(p, ec), end; ec.value() == 0 && d != end; ++d)
@@ -2007,6 +2036,286 @@ Index: libstdc++-v3/include/std/tuple
                      _MoveConstructibleTuple<_UElements...>()
                    && !_TMC<_UElements...>::template
                      _ImplicitlyMoveConvertibleTuple<_UElements...>()
+Index: libstdc++-v3/include/parallel/compiletime_settings.h
+===================================================================
+--- a/src/libstdc++-v3/include/parallel/compiletime_settings.h	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/include/parallel/compiletime_settings.h	(.../branches/gcc-6-branch)
+@@ -55,12 +55,6 @@
+ #define _GLIBCXX_SCALE_DOWN_FPU 0
+ #endif
+ 
+-#ifndef _GLIBCXX_ASSERTIONS
+-/** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code.
+- *  Should be switched on only locally. */
+-#define _GLIBCXX_ASSERTIONS 0
+-#endif
+-
+ #ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
+ /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code.
+  *  Consider the size of the L1 cache for
+Index: libstdc++-v3/include/parallel/balanced_quicksort.h
+===================================================================
+--- a/src/libstdc++-v3/include/parallel/balanced_quicksort.h	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/include/parallel/balanced_quicksort.h	(.../branches/gcc-6-branch)
+@@ -53,7 +53,10 @@
+ 
+ #if _GLIBCXX_ASSERTIONS
+ #include <parallel/checkers.h>
++#ifdef _GLIBCXX_HAVE_UNISTD_H
++#include <unistd.h>
+ #endif
++#endif
+ 
+ namespace __gnu_parallel
+ {
+Index: libstdc++-v3/include/experimental/optional
+===================================================================
+--- a/src/libstdc++-v3/include/experimental/optional	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/include/experimental/optional	(.../branches/gcc-6-branch)
+@@ -470,6 +470,23 @@
+       bool _M_engaged = false;
+     };
+ 
++  template<typename _Tp>
++  class optional;
++
++  template<typename>
++    struct __is_optional_impl : false_type
++    { };
++
++  template<typename _Tp>
++  struct __is_optional_impl<optional<_Tp>> : true_type
++    { };
++
++  template<typename _Tp>
++    struct __is_optional
++    : public __is_optional_impl<std::remove_cv_t<std::remove_reference_t<_Tp>>>
++    { };
++
++
+   /**
+     * @brief Class template for optional values.
+     */
+@@ -502,6 +519,78 @@
+       // _Optional_base has the responsibility for construction.
+       using _Base::_Base;
+ 
++      constexpr optional() = default;
++      // Converting constructors for engaged optionals.
++      template <typename _Up,
++                enable_if_t<__and_<
++			      __not_<is_same<_Tp, _Up>>,
++			      is_constructible<_Tp, _Up&&>,
++			      is_convertible<_Up&&, _Tp>
++			      >::value, bool> = true>
++      constexpr optional(_Up&& __t)
++        : _Base(_Tp(std::forward<_Up>(__t))) { }
++
++      template <typename _Up,
++                enable_if_t<__and_<
++			    __not_<is_same<_Tp, _Up>>,
++			    is_constructible<_Tp, _Up&&>,
++			    __not_<is_convertible<_Up&&, _Tp>>
++			    >::value, bool> = false>
++      explicit constexpr optional(_Up&& __t)
++        : _Base(_Tp(std::forward<_Up>(__t))) { }
++
++      template <typename _Up,
++                enable_if_t<__and_<
++			    __not_<is_same<_Tp, _Up>>,
++			    __not_<is_constructible<
++			      _Tp, const optional<_Up>&>>,
++			    __not_<is_convertible<
++			      const optional<_Up>&, _Tp>>,
++			    is_constructible<_Tp, const _Up&>,
++			    is_convertible<const _Up&, _Tp>
++			    >::value, bool> = true>
++      constexpr optional(const optional<_Up>& __t)
++        : _Base(__t ? optional<_Tp>(*__t) : optional<_Tp>()) { }
++
++      template <typename _Up,
++                 enable_if_t<__and_<
++			       __not_<is_same<_Tp, _Up>>,
++			       __not_<is_constructible<
++					_Tp, const optional<_Up>&>>,
++			       __not_<is_convertible<
++				 const optional<_Up>&, _Tp>>,
++			       is_constructible<_Tp, const _Up&>,
++			       __not_<is_convertible<const _Up&, _Tp>>
++			       >::value, bool> = false>
++      explicit constexpr optional(const optional<_Up>& __t)
++        : _Base(__t ? optional<_Tp>(*__t) : optional<_Tp>()) { }
++
++      template <typename _Up,
++                enable_if_t<__and_<
++			      __not_<is_same<_Tp, _Up>>,
++			      __not_<is_constructible<
++				       _Tp, optional<_Up>&&>>,
++			      __not_<is_convertible<
++				       optional<_Up>&&, _Tp>>,
++			      is_constructible<_Tp, _Up&&>,
++			      is_convertible<_Up&&, _Tp>
++			      >::value, bool> = true>
++      constexpr optional(optional<_Up>&& __t)
++        : _Base(__t ? optional<_Tp>(std::move(*__t)) : optional<_Tp>()) { }
++
++      template <typename _Up,
++                enable_if_t<__and_<
++			    __not_<is_same<_Tp, _Up>>,
++			    __not_<is_constructible<
++				     _Tp, optional<_Up>&&>>,
++			    __not_<is_convertible<
++				     optional<_Up>&&, _Tp>>,
++			    is_constructible<_Tp, _Up&&>,
++			    __not_<is_convertible<_Up&&, _Tp>>
++			    >::value, bool> = false>
++      explicit constexpr optional(optional<_Up>&& __t)
++        : _Base(__t ? optional<_Tp>(std::move(*__t)) : optional<_Tp>()) { }
++
+       // [X.Y.4.3] (partly) Assignment.
+       optional&
+       operator=(nullopt_t) noexcept
+@@ -510,8 +599,12 @@
+         return *this;
+       }
+ 
+-      template<typename _Up>
+-        enable_if_t<is_same<_Tp, decay_t<_Up>>::value, optional&>
++      template<typename _Up,
++               enable_if_t<__and_<
++			   __not_<is_same<_Up, nullopt_t>>,
++			   __not_<__is_optional<_Up>>>::value,
++			 bool> = true>
++        optional&
+         operator=(_Up&& __u)
+         {
+           static_assert(__and_<is_constructible<_Tp, _Up>,
+@@ -526,6 +619,57 @@
+           return *this;
+         }
+ 
++      template<typename _Up,
++               enable_if_t<__and_<
++		 __not_<is_same<_Tp, _Up>>>::value,
++			   bool> = true>
++        optional&
++        operator=(const optional<_Up>& __u)
++        {
++          static_assert(__and_<is_constructible<_Tp, _Up>,
++			       is_assignable<_Tp&, _Up>>(),
++                        "Cannot assign to value type from argument");
++
++          if (__u)
++            {
++              if (this->_M_is_engaged())
++                this->_M_get() = *__u;
++              else
++                this->_M_construct(*__u);
++            }
++          else
++            {
++              this->_M_reset();
++            }
++          return *this;
++        }
++
++      template<typename _Up,
++               enable_if_t<__and_<
++		 __not_<is_same<_Tp, _Up>>>::value,
++			   bool> = true>
++        optional&
++        operator=(optional<_Up>&& __u)
++        {
++          static_assert(__and_<is_constructible<_Tp, _Up>,
++			       is_assignable<_Tp&, _Up>>(),
++                        "Cannot assign to value type from argument");
++
++          if (__u)
++            {
++              if (this->_M_is_engaged())
++                this->_M_get() = std::move(*__u);
++              else
++                this->_M_construct(std::move(*__u));
++            }
++          else
++            {
++              this->_M_reset();
++            }
++
++          return *this;
++        }
++
+       template<typename... _Args>
+ 	void
+ 	emplace(_Args&&... __args)
+Index: libstdc++-v3/include/experimental/any
+===================================================================
+--- a/src/libstdc++-v3/include/experimental/any	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/include/experimental/any	(.../branches/gcc-6-branch)
+@@ -158,7 +158,9 @@
+ 
+     /// Construct with a copy of @p __value as the contained object.
+     template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
+-	      typename _Mgr = _Manager<_Tp>>
++	      typename _Mgr = _Manager<_Tp>,
++              typename enable_if<is_constructible<_Tp, _ValueType&&>::value,
++                                 bool>::type = true>
+       any(_ValueType&& __value)
+       : _M_manager(&_Mgr::_S_manage)
+       {
+@@ -167,6 +169,19 @@
+ 		      "The contained object must be CopyConstructible");
+       }
+ 
++    /// Construct with a copy of @p __value as the contained object.
++    template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
++	      typename _Mgr = _Manager<_Tp>,
++              typename enable_if<!is_constructible<_Tp, _ValueType&&>::value,
++                                 bool>::type = false>
++      any(_ValueType&& __value)
++      : _M_manager(&_Mgr::_S_manage)
++      {
++        _Mgr::_S_create(_M_storage, __value);
++	static_assert(is_copy_constructible<_Tp>::value,
++		      "The contained object must be CopyConstructible");
++      }
++
+     /// Destructor, calls @c clear()
+     ~any() { clear(); }
+ 
+@@ -377,7 +392,10 @@
+       __throw_bad_any_cast();
+     }
+ 
+-  template<typename _ValueType>
++  template<typename _ValueType,
++           typename enable_if<!is_move_constructible<_ValueType>::value
++                              || is_lvalue_reference<_ValueType>::value,
++                              bool>::type = true>
+     inline _ValueType any_cast(any&& __any)
+     {
+       static_assert(any::__is_valid_cast<_ValueType>(),
+@@ -387,6 +405,20 @@
+ 	return *__p;
+       __throw_bad_any_cast();
+     }
++
++  template<typename _ValueType,
++           typename enable_if<is_move_constructible<_ValueType>::value
++                              && !is_lvalue_reference<_ValueType>::value,
++                              bool>::type = false>
++    inline _ValueType any_cast(any&& __any)
++    {
++      static_assert(any::__is_valid_cast<_ValueType>(),
++	  "Template argument must be a reference or CopyConstructible type");
++      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
++      if (__p)
++	return std::move(*__p);
++      __throw_bad_any_cast();
++    }
+   // @}
+ 
+   template<typename _Tp>
 Index: libstdc++-v3/include/experimental/bits/fs_dir.h
 ===================================================================
 --- a/src/libstdc++-v3/include/experimental/bits/fs_dir.h	(.../tags/gcc_6_1_0_release)
@@ -2305,6 +2614,20 @@ Index: libstdc++-v3/include/experimental/bits/fs_fwd.h
    { return __x = __x ^ __y; }
  
    typedef chrono::time_point<chrono::system_clock> file_time_type;
+Index: libstdc++-v3/include/experimental/functional
+===================================================================
+--- a/src/libstdc++-v3/include/experimental/functional	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/include/experimental/functional	(.../branches/gcc-6-branch)
+@@ -42,6 +42,9 @@
+ #include <vector>
+ #include <array>
+ #include <bits/stl_algo.h>
++#ifdef _GLIBCXX_PARALLEL
++# include <parallel/algorithm> // For std::__parallel::search
++#endif
+ 
+ namespace std _GLIBCXX_VISIBILITY(default)
+ {
 Index: libstdc++-v3/include/bits/stl_algobase.h
 ===================================================================
 --- a/src/libstdc++-v3/include/bits/stl_algobase.h	(.../tags/gcc_6_1_0_release)
@@ -2397,11 +2720,79 @@ Index: libstdc++-v3/include/bits/stl_algo.h
  
        _ForwardIterator __i
  	= std::__lower_bound(__first, __last, __val,
+Index: libstdc++-v3/include/bits/c++config
+===================================================================
+--- a/src/libstdc++-v3/include/bits/c++config	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/include/bits/c++config	(.../branches/gcc-6-branch)
+@@ -414,7 +414,7 @@
+ 
+ // Debug Mode implies checking assertions.
+ #ifdef _GLIBCXX_DEBUG
+-# define _GLIBCXX_ASSERTIONS
++# define _GLIBCXX_ASSERTIONS 1
+ #endif
+ 
+ // Disable std::string explicit instantiation declarations in order to assert.
 Index: libstdc++-v3/ChangeLog
 ===================================================================
 --- a/src/libstdc++-v3/ChangeLog	(.../tags/gcc_6_1_0_release)
 +++ b/src/libstdc++-v3/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,154 @@
+@@ -1,3 +1,209 @@
++2016-07-19  Jonathan Wakely  <jwakely at redhat.com>
++
++	Backport from mainline
++	2016-07-14  Jonathan Wakely  <jwakely at redhat.com>
++
++	* include/experimental/functional: Include <parallel/algorithm> in
++	Parallel Mode.
++
++	Backport from mainline
++	2016-07-14  Jonathan Wakely  <jwakely at redhat.com>
++
++	* testsuite/experimental/functional/searchers.cc: Include <algorithm>
++	for std::search.
++
++	PR libstdc++/71856
++	* include/bits/c++config (_GLIBCXX_ASSERTIONS): Define to 1 not empty.
++	* include/parallel/balanced_quicksort.h: Include <unistd.h> for sleep.
++	* include/parallel/compiletime_settings.h (_GLIBCXX_ASSERTIONS):
++	Do not define here.
++
++	Backport from mainline
++	2016-06-06  Jonathan Wakely  <jwakely at redhat.com>
++
++	PR libstdc++/71320
++	* src/filesystem/ops.cc (permissions(const path&, perms, error_code&)):
++	Add or remove permissions according to perms argument.
++	* testsuite/experimental/filesystem/operations/permissions.cc: New
++	test.
++
++2016-07-06  Ville Voutilainen  <ville.voutilainen at gmail.com>
++
++	Implement LWG 2451, optional<T> should 'forward' T's
++	implicit conversions.
++	* include/experimental/optional (__is_optional_impl, __is_optional):
++	New.
++	(optional()): Make constexpr and default.
++	(optional(_Up&&), optional(const optional<_Up>&),
++	optional(optional<_Up>&& __t): New.
++	(operator=(_Up&&)): Constrain.
++	(operator=(const optional<_Up>&), operator=(optional<_Up>&&)): New.
++	* testsuite/experimental/optional/cons/value.cc:
++	Add tests for the functionality added by LWG 2451.
++	* testsuite/experimental/optional/cons/value_neg.cc: New.
++
++2016-07-05  Ville Voutilainen  <ville.voutilainen at gmail.com>
++
++	Implement LWG 2509,
++	any_cast doesn't work with rvalue reference targets and cannot
++	move with a value target.
++	* include/experimental/any (any(_ValueType&&)): Constrain and
++	add an overload that doesn't forward.
++	(any_cast(any&&)): Constrain and add an overload that moves.
++	* testsuite/experimental/any/misc/any_cast.cc: Add tests for
++	the functionality added by LWG 2509.
++
 +2016-07-04  Ville Voutilainen  <ville.voutilainen at gmail.com>
 +
 +	PR libstdc++/71313
@@ -3095,6 +3486,62 @@ Index: libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/69703.cc
 +  test01();
 +  test02();
 +}
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/permissions.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/permissions.cc	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/permissions.cc	(.../branches/gcc-6-branch)
+@@ -0,0 +1,51 @@
++// Copyright (C) 2016 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library is free
++// software; you can redistribute it and/or modify it under the
++// terms of the GNU General Public License as published by the
++// Free Software Foundation; either version 3, or (at your option)
++// any later version.
++
++// This library is distributed in the hope that it will be useful,
++// but WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++// GNU General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING3.  If not see
++// <http://www.gnu.org/licenses/>.
++
++// { dg-options "-std=gnu++11 -lstdc++fs" }
++// { dg-require-filesystem-ts "" }
++
++// 15.26 Permissions [fs.op.permissions]
++
++#include <experimental/filesystem>
++#include <fstream>
++#include <testsuite_fs.h>
++#include <testsuite_hooks.h>
++
++void
++test01()
++{
++  bool test __attribute__((unused)) = true;
++  using perms = std::experimental::filesystem::perms;
++
++  auto p = __gnu_test::nonexistent_path();
++  std::ofstream{p.native()};
++  VERIFY( exists(p) );
++  permissions(p, perms::owner_all);
++  VERIFY( status(p).permissions() == perms::owner_all );
++  permissions(p, perms::group_read | perms::add_perms);
++  VERIFY( status(p).permissions() == (perms::owner_all | perms::group_read) );
++  permissions(p, perms::group_read | perms::remove_perms);
++  VERIFY( status(p).permissions() == perms::owner_all );
++
++  remove(p);
++}
++
++int
++main()
++{
++  test01();
++}
 Index: libstdc++-v3/testsuite/experimental/filesystem/operations/create_directories.cc
 ===================================================================
 --- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directories.cc	(.../tags/gcc_6_1_0_release)
@@ -3699,6 +4146,151 @@ Index: libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc
 +  test01();
 +  test02();
 +}
+Index: libstdc++-v3/testsuite/experimental/optional/cons/value.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/optional/cons/value.cc	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/optional/cons/value.cc	(.../branches/gcc-6-branch)
+@@ -22,6 +22,7 @@
+ #include <testsuite_hooks.h>
+ 
+ #include <vector>
++#include <string>
+ 
+ struct tracker
+ {
+@@ -236,4 +237,22 @@
+ 
+     VERIFY( result == caught );
+   }
++
++  {
++    std::experimental::optional<std::string> os = "foo";
++    struct X
++    {
++      explicit X(int) {}
++      X& operator=(int) {return *this;}
++    };
++    std::experimental::optional<X> ox{42};
++    std::experimental::optional<int> oi{42};
++    std::experimental::optional<X> ox2{oi};
++    std::experimental::optional<std::string> os2;
++    os2 = "foo";
++    std::experimental::optional<X> ox3;
++    ox3 = 42;
++    std::experimental::optional<X> ox4;
++    ox4 = oi;
++  }
+ }
+Index: libstdc++-v3/testsuite/experimental/optional/cons/value_neg.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/optional/cons/value_neg.cc	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/optional/cons/value_neg.cc	(.../branches/gcc-6-branch)
+@@ -0,0 +1,39 @@
++// { dg-options "-std=gnu++14" }
++// { dg-do compile }
++
++// Copyright (C) 2013-2016 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 moved_to of the GNU General Public License along
++// with this library; see the file COPYING3.  If not see
++// <http://www.gnu.org/licenses/>.
++
++#include <experimental/optional>
++#include <testsuite_hooks.h>
++
++#include <string>
++#include <memory>
++
++int main()
++{
++  {
++    struct X
++    {
++      explicit X(int) {}
++    };
++    std::experimental::optional<X> ox{42};
++    std::experimental::optional<X> ox2 = 42; // { dg-error "conversion" }
++    std::experimental::optional<std::unique_ptr<int>> oup{new int};
++    std::experimental::optional<std::unique_ptr<int>> oup2 = new int;  // { dg-error "conversion" }
++  }
++}
+Index: libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc	(.../branches/gcc-6-branch)
+@@ -77,8 +77,38 @@
+   }
+ }
+ 
++static int move_count = 0;
++
++void test03()
++{
++  struct MoveEnabled
++  {
++    MoveEnabled(MoveEnabled&&)
++    {
++      ++move_count;
++    }
++    MoveEnabled() = default;
++    MoveEnabled(const MoveEnabled&) = default;
++  };
++  MoveEnabled m;
++  MoveEnabled m2 = any_cast<MoveEnabled>(any(m));
++  VERIFY(move_count == 1);
++  MoveEnabled&& m3 = any_cast<MoveEnabled&&>(any(m));
++  VERIFY(move_count == 1);
++  struct MoveDeleted
++  {
++    MoveDeleted(MoveDeleted&&) = delete;
++    MoveDeleted() = default;
++    MoveDeleted(const MoveDeleted&) = default;
++  };
++  MoveDeleted md;
++  MoveDeleted&& md2 = any_cast<MoveDeleted>(any(std::move(md)));
++  MoveDeleted&& md3 = any_cast<MoveDeleted&&>(any(std::move(md)));
++}
++
+ int main()
+ {
+   test01();
+   test02();
++  test03();
+ }
+Index: libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc	(.../branches/gcc-6-branch)
+@@ -26,5 +26,5 @@
+   using std::experimental::any_cast;
+ 
+   const any y(1);
+-  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 353 }
++  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 368 }
+ }
+Index: libstdc++-v3/testsuite/experimental/functional/searchers.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/functional/searchers.cc	(.../tags/gcc_6_1_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/functional/searchers.cc	(.../branches/gcc-6-branch)
+@@ -22,6 +22,7 @@
+ #ifdef _GLIBCXX_USE_WCHAR_T
+ # include <cwchar>
+ #endif
++#include <algorithm>
+ #include <testsuite_hooks.h>
+ 
+ using std::experimental::make_default_searcher;
 Index: libstdc++-v3/testsuite/util/testsuite_iterators.h
 ===================================================================
 --- a/src/libstdc++-v3/testsuite/util/testsuite_iterators.h	(.../tags/gcc_6_1_0_release)
@@ -3776,7 +4368,20 @@ Index: libiberty/ChangeLog
 ===================================================================
 --- a/src/libiberty/ChangeLog	(.../tags/gcc_6_1_0_release)
 +++ b/src/libiberty/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,30 @@
+@@ -1,3 +1,43 @@
++2016-07-21  Jason Merrill  <jason at redhat.com>
++
++	* cp-demangle.c (cplus_demangle_operators): Add f[lrLR].
++	(d_expression_1): Handle them.
++	(d_maybe_print_fold_expression): New.
++	(d_print_comp_inner): Use it.
++	(d_index_template_argument): Handle negative index.
++
++	* cp-demangle.c (cplus_demangle_operators): Add sP and sZ.
++	(d_print_comp_inner): Handle them.
++	(d_template_args_1): Split out from d_template_args.
++	(d_args_length): New.
++
 +2016-05-19  Jakub Jelinek  <jakub at redhat.com>
 +
 +	Backported from mainline
@@ -3807,7 +4412,7 @@ Index: libiberty/ChangeLog
  2016-04-27  Release Manager
  
  	* GCC 6.1.0 released.
-@@ -16,7 +43,7 @@
+@@ -16,7 +56,7 @@
  	-1.
  
  2016-03-31  Mikhail Maltsev  <maltsevm at gmail.com>
@@ -3816,7 +4421,7 @@ Index: libiberty/ChangeLog
  
  	PR c++/67394
  	PR c++/70481
-@@ -2037,7 +2064,7 @@
+@@ -2037,7 +2077,7 @@
  	that are locale-independent.
  	* Makefile.in (filename_cmp.o): Add dependency on safe-ctype.h.
  
@@ -3829,9 +4434,28 @@ Index: libiberty/testsuite/demangle-expected
 ===================================================================
 --- a/src/libiberty/testsuite/demangle-expected	(.../tags/gcc_6_1_0_release)
 +++ b/src/libiberty/testsuite/demangle-expected	(.../branches/gcc-6-branch)
-@@ -4422,12 +4422,22 @@
+@@ -4421,13 +4421,41 @@
+ --format=gnu-v3
  _Z3fooI1FEN1XIXszdtcl1PclcvT__EEE5arrayEE4TypeEv
  X<sizeof ((P(((F)())())).array)>::Type foo<F>()
++
++_Z1fIJidEEv1AIXsZT_EE
++void f<int, double>(A<2>)
++
++_ZN1A1fIJiiEiJiiiEEEvRAsPDpT_T0_DpT1_E_iS3_S5_
++void A::f<int, int, int, int, int, int>(int (&) [6], int, int, int, int)
++
++_Z10unary_leftIJLi1ELi2ELi3EEEv1AIXflplT_EE
++void unary_left<1, 2, 3>(A<(...+(1, 2, 3))>)
++
++_Z11unary_rightIJLi1ELi2ELi3EEEv1AIXfrplT_EE
++void unary_right<1, 2, 3>(A<((1, 2, 3)+...)>)
++
++_Z11binary_leftIJLi1ELi2ELi3EEEv1AIXfLplLi42ET_EE
++void binary_left<1, 2, 3>(A<((42)+...+(1, 2, 3))>)
++
++_Z12binary_rightIJLi1ELi2ELi3EEEv1AIXfRplT_Li42EEE
++void binary_right<1, 2, 3>(A<((1, 2, 3)+...+(42))>)
  #
 -# Tests a use-after-free problem
 +# Tests a use-after-free problem PR70481
@@ -3872,6 +4496,15 @@ Index: libiberty/cp-demangle.c
  #include "ansidecl.h"
  #include "libiberty.h"
  #include "demangle.h"
+@@ -337,7 +344,7 @@
+   /* Set to 1 if we saw a demangling error.  */
+   int demangle_failure;
+   /* The current index into any template argument packs we are using
+-     for printing.  */
++     for printing, or -1 to print the whole pack.  */
+   int pack_index;
+   /* Number of d_print_flush calls so far.  */
+   unsigned long int flush_count;
 @@ -398,7 +405,7 @@
               struct demangle_component *);
  
@@ -3893,7 +4526,15 @@ Index: libiberty/cp-demangle.c
  
  static struct demangle_component *d_operator_name (struct d_info *);
  
-@@ -1119,7 +1126,7 @@
+@@ -459,6 +466,7 @@
+ d_template_param (struct d_info *);
+ 
+ static struct demangle_component *d_template_args (struct d_info *);
++static struct demangle_component *d_template_args_1 (struct d_info *);
+ 
+ static struct demangle_component *
+ d_template_arg (struct d_info *);
+@@ -1119,7 +1127,7 @@
  /* Add a new template parameter.  */
  
  static struct demangle_component *
@@ -3902,7 +4543,7 @@ Index: libiberty/cp-demangle.c
  {
    struct demangle_component *p;
  
-@@ -1135,7 +1142,7 @@
+@@ -1135,7 +1143,7 @@
  /* Add a new function parameter.  */
  
  static struct demangle_component *
@@ -3911,7 +4552,7 @@ Index: libiberty/cp-demangle.c
  {
    struct demangle_component *p;
  
-@@ -1620,7 +1627,7 @@
+@@ -1620,7 +1628,7 @@
  static struct demangle_component *
  d_source_name (struct d_info *di)
  {
@@ -3920,7 +4561,7 @@ Index: libiberty/cp-demangle.c
    struct demangle_component *ret;
  
    len = d_number (di);
-@@ -1633,12 +1640,12 @@
+@@ -1633,12 +1641,12 @@
  
  /* number ::= [n] <(non-negative decimal integer)>  */
  
@@ -3935,7 +4576,7 @@ Index: libiberty/cp-demangle.c
  
    negative = 0;
    peek = d_peek_char (di);
-@@ -1681,7 +1688,7 @@
+@@ -1681,7 +1689,7 @@
  /* identifier ::= <(unqualified source code identifier)>  */
  
  static struct demangle_component *
@@ -3944,7 +4585,7 @@ Index: libiberty/cp-demangle.c
  {
    const char *name;
  
-@@ -1702,7 +1709,7 @@
+@@ -1702,7 +1710,7 @@
    /* Look for something which looks like a gcc encoding of an
       anonymous namespace, and replace it with a more user friendly
       name.  */
@@ -3953,7 +4594,27 @@ Index: libiberty/cp-demangle.c
        && memcmp (name, ANONYMOUS_NAMESPACE_PREFIX,
  		 ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0)
      {
-@@ -1870,7 +1877,7 @@
+@@ -1754,6 +1762,10 @@
+   { "eO", NL ("^="),        2 },
+   { "eo", NL ("^"),         2 },
+   { "eq", NL ("=="),        2 },
++  { "fL", NL ("..."),       3 },
++  { "fR", NL ("..."),       3 },
++  { "fl", NL ("..."),       2 },
++  { "fr", NL ("..."),       2 },
+   { "ge", NL (">="),        2 },
+   { "gs", NL ("::"),	    1 },
+   { "gt", NL (">"),         2 },
+@@ -1788,6 +1800,8 @@
+   { "rc", NL ("reinterpret_cast"), 2 },
+   { "rm", NL ("%"),         2 },
+   { "rs", NL (">>"),        2 },
++  { "sP", NL ("sizeof..."), 1 },
++  { "sZ", NL ("sizeof..."), 1 },
+   { "sc", NL ("static_cast"), 2 },
+   { "st", NL ("sizeof "),   1 },
+   { "sz", NL ("sizeof "),   1 },
+@@ -1870,7 +1884,7 @@
  {
    struct demangle_component *p = NULL;
    struct demangle_component *next = NULL;
@@ -3962,7 +4623,7 @@ Index: libiberty/cp-demangle.c
    char c;
    const char *str;
  
-@@ -2012,7 +2019,7 @@
+@@ -2012,7 +2026,7 @@
  	case 'C':
  	  {
  	    struct demangle_component *derived_type;
@@ -3971,7 +4632,7 @@ Index: libiberty/cp-demangle.c
  	    struct demangle_component *base_type;
  
  	    derived_type = cplus_demangle_type (di);
-@@ -2946,10 +2953,10 @@
+@@ -2946,10 +2960,10 @@
  
  /* <non-negative number> _ */
  
@@ -3984,7 +4645,7 @@ Index: libiberty/cp-demangle.c
    if (d_peek_char (di) == '_')
      num = 0;
    else if (d_peek_char (di) == 'n')
-@@ -2957,7 +2964,7 @@
+@@ -2957,7 +2971,7 @@
    else
      num = d_number (di) + 1;
  
@@ -3993,7 +4654,7 @@ Index: libiberty/cp-demangle.c
      return -1;
    return num;
  }
-@@ -2969,7 +2976,7 @@
+@@ -2969,7 +2983,7 @@
  static struct demangle_component *
  d_template_param (struct d_info *di)
  {
@@ -4002,7 +4663,39 @@ Index: libiberty/cp-demangle.c
  
    if (! d_check_char (di, 'T'))
      return NULL;
-@@ -3171,9 +3178,10 @@
+@@ -2988,6 +3002,19 @@
+ static struct demangle_component *
+ d_template_args (struct d_info *di)
+ {
++  if (d_peek_char (di) != 'I'
++      && d_peek_char (di) != 'J')
++    return NULL;
++  d_advance (di, 1);
++
++  return d_template_args_1 (di);
++}
++
++/* <template-arg>* E  */
++
++static struct demangle_component *
++d_template_args_1 (struct d_info *di)
++{
+   struct demangle_component *hold_last_name;
+   struct demangle_component *al;
+   struct demangle_component **pal;
+@@ -2997,11 +3024,6 @@
+      constructor or destructor.  */
+   hold_last_name = di->last_name;
+ 
+-  if (d_peek_char (di) != 'I'
+-      && d_peek_char (di) != 'J')
+-    return NULL;
+-  d_advance (di, 1);
+-
+   if (d_peek_char (di) == 'E')
+     {
+       /* An argument pack can be empty.  */
+@@ -3171,9 +3193,10 @@
  	}
        else
  	{
@@ -4015,7 +4708,40 @@ Index: libiberty/cp-demangle.c
  	}
        return d_make_function_param (di, index);
      }
-@@ -3502,7 +3510,7 @@
+@@ -3262,6 +3285,8 @@
+ 	    if (op->type == DEMANGLE_COMPONENT_CAST
+ 		&& d_check_char (di, '_'))
+ 	      operand = d_exprlist (di, 'E');
++	    else if (code && !strcmp (code, "sP"))
++	      operand = d_template_args_1 (di);
+ 	    else
+ 	      operand = d_expression_1 (di);
+ 
+@@ -3284,6 +3309,9 @@
+ 	      return NULL;
+ 	    if (op_is_new_cast (op))
+ 	      left = cplus_demangle_type (di);
++	    else if (code[0] == 'f')
++	      /* fold-expression.  */
++	      left = d_operator_name (di);
+ 	    else
+ 	      left = d_expression_1 (di);
+ 	    if (!strcmp (code, "cl"))
+@@ -3318,6 +3346,13 @@
+ 		second = d_expression_1 (di);
+ 		third = d_expression_1 (di);
+ 	      }
++	    else if (code[0] == 'f')
++	      {
++		/* fold-expression.  */
++		first = d_operator_name (di);
++		second = d_expression_1 (di);
++		third = d_expression_1 (di);
++	      }
+ 	    else if (code[0] == 'n')
+ 	      {
+ 		/* new-expression.  */
+@@ -3502,7 +3537,7 @@
  static int
  d_discriminator (struct d_info *di)
  {
@@ -4024,7 +4750,7 @@ Index: libiberty/cp-demangle.c
  
    if (d_peek_char (di) != '_')
      return 1;
-@@ -3558,7 +3566,7 @@
+@@ -3558,7 +3593,7 @@
  d_unnamed_type (struct d_info *di)
  {
    struct demangle_component *ret;
@@ -4033,7 +4759,7 @@ Index: libiberty/cp-demangle.c
  
    if (! d_check_char (di, 'U'))
      return NULL;
-@@ -4086,10 +4094,10 @@
+@@ -4086,10 +4121,10 @@
  }
  
  static inline void
@@ -4046,6 +4772,169 @@ Index: libiberty/cp-demangle.c
    d_append_string (dpi, buf);
  }
  
+@@ -4171,7 +4206,7 @@
+ }
+ 
+ /* Returns the I'th element of the template arglist ARGS, or NULL on
+-   failure.  */
++   failure.  If I is negative, return the entire arglist.  */
+ 
+ static struct demangle_component *
+ d_index_template_argument (struct demangle_component *args, int i)
+@@ -4178,6 +4213,10 @@
+ {
+   struct demangle_component *a;
+ 
++  if (i < 0)
++    /* Print the whole argument pack.  */
++    return args;
++
+   for (a = args;
+        a != NULL;
+        a = d_right (a))
+@@ -4277,6 +4316,30 @@
+   return count;
+ }
+ 
++/* Returns the number of template args in DC, expanding any pack expansions
++   found there.  */
++
++static int
++d_args_length (struct d_print_info *dpi, const struct demangle_component *dc)
++{
++  int count = 0;
++  for (; dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST;
++       dc = d_right (dc))
++    {
++      struct demangle_component *elt = d_left (dc);
++      if (elt == NULL)
++	break;
++      if (elt->type == DEMANGLE_COMPONENT_PACK_EXPANSION)
++	{
++	  struct demangle_component *a = d_find_pack (dpi, d_left (elt));
++	  count += d_pack_length (a);
++	}
++      else
++	++count;
++    }
++  return count;
++}
++
+ /* DC is a component of a mangled expression.  Print it, wrapped in parens
+    if needed.  */
+ 
+@@ -4353,6 +4416,70 @@
+   return NULL;
+ }
+ 
++/* If DC is a C++17 fold-expression, print it and return true; otherwise
++   return false.  */
++
++static int
++d_maybe_print_fold_expression (struct d_print_info *dpi, int options,
++			       const struct demangle_component *dc)
++{
++  const struct demangle_component *ops, *operator_, *op1, *op2;
++  int save_idx;
++
++  const char *fold_code = d_left (dc)->u.s_operator.op->code;
++  if (fold_code[0] != 'f')
++    return 0;
++
++  ops = d_right (dc);
++  operator_ = d_left (ops);
++  op1 = d_right (ops);
++  op2 = 0;
++  if (op1->type == DEMANGLE_COMPONENT_TRINARY_ARG2)
++    {
++      op2 = d_right (op1);
++      op1 = d_left (op1);
++    }
++
++  /* Print the whole pack.  */
++  save_idx = dpi->pack_index;
++  dpi->pack_index = -1;
++
++  switch (fold_code[1])
++    {
++      /* Unary left fold, (... + X).  */
++    case 'l':
++      d_append_string (dpi, "(...");
++      d_print_expr_op (dpi, options, operator_);
++      d_print_subexpr (dpi, options, op1);
++      d_append_char (dpi, ')');
++      break;
++
++      /* Unary right fold, (X + ...).  */
++    case 'r':
++      d_append_char (dpi, '(');
++      d_print_subexpr (dpi, options, op1);
++      d_print_expr_op (dpi, options, operator_);
++      d_append_string (dpi, "...)");
++      break;
++
++      /* Binary left fold, (42 + ... + X).  */
++    case 'L':
++      /* Binary right fold, (X + ... + 42).  */
++    case 'R':
++      d_append_char (dpi, '(');
++      d_print_subexpr (dpi, options, op1);
++      d_print_expr_op (dpi, options, operator_);
++      d_append_string (dpi, "...");
++      d_print_expr_op (dpi, options, operator_);
++      d_print_subexpr (dpi, options, op2);
++      d_append_char (dpi, ')');
++      break;
++    }
++
++  dpi->pack_index = save_idx;
++  return 1;
++}
++
+ /* Subroutine to handle components.  */
+ 
+ static void
+@@ -5113,6 +5240,21 @@
+ 	      }
+ 	  }
+ 
++	/* For sizeof..., just print the pack length.  */
++	if (code && !strcmp (code, "sZ"))
++	  {
++	    struct demangle_component *a = d_find_pack (dpi, operand);
++	    int len = d_pack_length (a);
++	    d_append_num (dpi, len);
++	    return;
++	  }
++	else if (code && !strcmp (code, "sP"))
++	  {
++	    int len = d_args_length (dpi, operand);
++	    d_append_num (dpi, len);
++	    return;
++	  }
++
+ 	if (op->type != DEMANGLE_COMPONENT_CAST)
+ 	  d_print_expr_op (dpi, options, op);
+ 	else
+@@ -5154,6 +5296,9 @@
+ 	  return;
+ 	}
+ 
++      if (d_maybe_print_fold_expression (dpi, options, dc))
++	return;
++
+       /* We wrap an expression which uses the greater-than operator in
+ 	 an extra layer of parens so that it does not get confused
+ 	 with the '>' which ends the template parameters.  */
+@@ -5209,6 +5354,8 @@
+ 	  d_print_error (dpi);
+ 	  return;
+ 	}
++      if (d_maybe_print_fold_expression (dpi, options, dc))
++	return;
+       {
+ 	struct demangle_component *op = d_left (dc);
+ 	struct demangle_component *first = d_left (d_right (dc));
 Index: libatomic/configure.tgt
 ===================================================================
 --- a/src/libatomic/configure.tgt	(.../tags/gcc_6_1_0_release)
@@ -4315,7 +5204,19 @@ Index: libgcc/ChangeLog
 ===================================================================
 --- a/src/libgcc/ChangeLog	(.../tags/gcc_6_1_0_release)
 +++ b/src/libgcc/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,13 @@
+@@ -1,3 +1,25 @@
++2016-07-14  Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-12  Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	* config/rs6000/_divkc3.c: New.
++	* config/rs6000/_mulkc3.c: New.
++	* config/rs6000/quad-float128.h: Define TFtype; declare _mulkc3
++	and _divkc3.
++	* config/rs6000/t-float128: Add _mulkc3 and _divkc3 to
++	fp128_ppc_funcs.
++
 +2016-05-17  Sebastian Huber  <sebastian.huber at embedded-brains.de>
 +
 +	Backport from mainline
@@ -4329,6 +5230,188 @@ Index: libgcc/ChangeLog
  2016-04-27  Release Manager
  
  	* GCC 6.1.0 released.
+Index: libgcc/config/rs6000/_divkc3.c
+===================================================================
+--- a/src/libgcc/config/rs6000/_divkc3.c	(.../tags/gcc_6_1_0_release)
++++ b/src/libgcc/config/rs6000/_divkc3.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,64 @@
++typedef float KFtype __attribute__ ((mode (KF)));
++typedef __complex float KCtype __attribute__ ((mode (KC)));
++
++#define COPYSIGN(x,y) __builtin_copysignq (x, y)
++#define INFINITY __builtin_infq ()
++#define FABS __builtin_fabsq
++#define isnan __builtin_isnan
++#define isinf __builtin_isinf
++#define isfinite __builtin_isfinite
++
++KCtype
++__divkc3 (KFtype a, KFtype b, KFtype c, KFtype d)
++{
++  KFtype denom, ratio, x, y;
++  KCtype res;
++
++  /* ??? We can get better behavior from logarithmic scaling instead of
++     the division.  But that would mean starting to link libgcc against
++     libm.  We could implement something akin to ldexp/frexp as gcc builtins
++     fairly easily...  */
++  if (FABS (c) < FABS (d))
++    {
++      ratio = c / d;
++      denom = (c * ratio) + d;
++      x = ((a * ratio) + b) / denom;
++      y = ((b * ratio) - a) / denom;
++    }
++  else
++    {
++      ratio = d / c;
++      denom = (d * ratio) + c;
++      x = ((b * ratio) + a) / denom;
++      y = (b - (a * ratio)) / denom;
++    }
++
++  /* Recover infinities and zeros that computed as NaN+iNaN; the only cases
++     are nonzero/zero, infinite/finite, and finite/infinite.  */
++  if (isnan (x) && isnan (y))
++    {
++      if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b)))
++	{
++	  x = COPYSIGN (INFINITY, c) * a;
++	  y = COPYSIGN (INFINITY, c) * b;
++	}
++      else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d))
++	{
++	  a = COPYSIGN (isinf (a) ? 1 : 0, a);
++	  b = COPYSIGN (isinf (b) ? 1 : 0, b);
++	  x = INFINITY * (a * c + b * d);
++	  y = INFINITY * (b * c - a * d);
++	}
++      else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b))
++	{
++	  c = COPYSIGN (isinf (c) ? 1 : 0, c);
++	  d = COPYSIGN (isinf (d) ? 1 : 0, d);
++	  x = 0.0 * (a * c + b * d);
++	  y = 0.0 * (b * c - a * d);
++	}
++    }
++
++  __real__ res = x;
++  __imag__ res = y;
++  return res;
++}
+Index: libgcc/config/rs6000/quad-float128.h
+===================================================================
+--- a/src/libgcc/config/rs6000/quad-float128.h	(.../tags/gcc_6_1_0_release)
++++ b/src/libgcc/config/rs6000/quad-float128.h	(.../branches/gcc-6-branch)
+@@ -33,6 +33,10 @@
+    This define forces it to use KFmode (aka, ieee 128-bit floating point).  */
+ #define TF KF
+ 
++/* We also need TCtype to represent complex ieee 128-bit float for
++   __mulkc3 and __divkc3.  */
++typedef __complex float TCtype __attribute__ ((mode (KC)));
++
+ /* Force the use of the VSX instruction set.  */
+ #if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__))
+ #pragma GCC target ("vsx,float128")
+@@ -154,6 +158,10 @@
+ extern IBM128_TYPE __extendkftf2 (TFtype);
+ extern TFtype __trunctfkf2 (IBM128_TYPE);
+ 
++/* Complex __float128 built on __float128 interfaces.  */
++extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype);
++extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype);
++
+ /* Implementation of conversions between __ibm128 and __float128, to allow the
+    same code to be used on systems with IEEE 128-bit emulation and with IEEE
+    128-bit hardware support.  */
+Index: libgcc/config/rs6000/t-float128
+===================================================================
+--- a/src/libgcc/config/rs6000/t-float128	(.../tags/gcc_6_1_0_release)
++++ b/src/libgcc/config/rs6000/t-float128	(.../branches/gcc-6-branch)
+@@ -25,7 +25,7 @@
+ # New functions for software emulation
+ fp128_ppc_funcs		= floattikf floatuntikf fixkfti fixunskfti \
+ 			  extendkftf2-sw trunctfkf2-sw \
+-			  sfp-exceptions
++			  sfp-exceptions _mulkc3 _divkc3
+ 
+ fp128_ppc_src		= $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \
+ 				.c,$(fp128_ppc_funcs)))
+Index: libgcc/config/rs6000/_mulkc3.c
+===================================================================
+--- a/src/libgcc/config/rs6000/_mulkc3.c	(.../tags/gcc_6_1_0_release)
++++ b/src/libgcc/config/rs6000/_mulkc3.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,69 @@
++typedef float KFtype __attribute__ ((mode (KF)));
++typedef __complex float KCtype __attribute__ ((mode (KC)));
++
++#define COPYSIGN(x,y) __builtin_copysignq (x, y)
++#define INFINITY __builtin_infq ()
++#define isnan __builtin_isnan
++#define isinf __builtin_isinf
++
++KCtype
++__mulkc3 (KFtype a, KFtype b, KFtype c, KFtype d)
++{
++  KFtype ac, bd, ad, bc, x, y;
++  KCtype res;
++
++  ac = a * c;
++  bd = b * d;
++  ad = a * d;
++  bc = b * c;
++
++  x = ac - bd;
++  y = ad + bc;
++
++  if (isnan (x) && isnan (y))
++    {
++      /* Recover infinities that computed as NaN + iNaN.  */
++      _Bool recalc = 0;
++      if (isinf (a) || isinf (b))
++	{
++	  /* z is infinite.  "Box" the infinity and change NaNs in
++	     the other factor to 0.  */
++	  a = COPYSIGN (isinf (a) ? 1 : 0, a);
++	  b = COPYSIGN (isinf (b) ? 1 : 0, b);
++	  if (isnan (c)) c = COPYSIGN (0, c);
++	  if (isnan (d)) d = COPYSIGN (0, d);
++          recalc = 1;
++	}
++     if (isinf (c) || isinf (d))
++	{
++	  /* w is infinite.  "Box" the infinity and change NaNs in
++	     the other factor to 0.  */
++	  c = COPYSIGN (isinf (c) ? 1 : 0, c);
++	  d = COPYSIGN (isinf (d) ? 1 : 0, d);
++	  if (isnan (a)) a = COPYSIGN (0, a);
++	  if (isnan (b)) b = COPYSIGN (0, b);
++	  recalc = 1;
++	}
++     if (!recalc
++	  && (isinf (ac) || isinf (bd)
++	      || isinf (ad) || isinf (bc)))
++	{
++	  /* Recover infinities from overflow by changing NaNs to 0.  */
++	  if (isnan (a)) a = COPYSIGN (0, a);
++	  if (isnan (b)) b = COPYSIGN (0, b);
++	  if (isnan (c)) c = COPYSIGN (0, c);
++	  if (isnan (d)) d = COPYSIGN (0, d);
++	  recalc = 1;
++	}
++      if (recalc)
++	{
++	  x = INFINITY * (a * c - b * d);
++	  y = INFINITY * (a * d + b * c);
++	}
++    }
++
++  __real__ res = x;
++  __imag__ res = y;
++  return res;
++}
++
 Index: gcc/tree-vrp.c
 ===================================================================
 --- a/src/gcc/tree-vrp.c	(.../tags/gcc_6_1_0_release)
@@ -4369,6 +5452,16 @@ Index: gcc/tree-vrp.c
  	    }
  	  else
  	    {
+@@ -2991,7 +2990,8 @@
+ 		     and divisor are available.  */
+ 		  if (vr1.type == VR_RANGE
+ 		      && !symbolic_range_p (&vr0)
+-		      && !symbolic_range_p (&vr1))
++		      && !symbolic_range_p (&vr1)
++		      && compare_values (vr1.max, zero) != 0)
+ 		    min = int_const_binop (code, vr0.min, vr1.max);
+ 		  else
+ 		    min = zero;
 Index: gcc/ipa-chkp.c
 ===================================================================
 --- a/src/gcc/ipa-chkp.c	(.../tags/gcc_6_1_0_release)
@@ -4572,6 +5665,18 @@ Index: gcc/opts-common.c
        if (strncmp (opt_text, new_prefix, new_prefix_len) == 0)
  	{
  	  char *alternative = concat (opt0 + 1, opt_text + new_prefix_len,
+Index: gcc/c-family/c-cppbuiltin.c
+===================================================================
+--- a/src/gcc/c-family/c-cppbuiltin.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/c-family/c-cppbuiltin.c	(.../branches/gcc-6-branch)
+@@ -848,6 +848,7 @@
+ 	  cpp_define (pfile, "__cpp_decltype=200707");
+ 	  cpp_define (pfile, "__cpp_attributes=200809");
+ 	  cpp_define (pfile, "__cpp_rvalue_reference=200610");
++	  cpp_define (pfile, "__cpp_rvalue_references=200610");
+ 	  cpp_define (pfile, "__cpp_variadic_templates=200704");
+ 	  cpp_define (pfile, "__cpp_initializer_lists=200806");
+ 	  cpp_define (pfile, "__cpp_delegating_constructors=200604");
 Index: gcc/c-family/c-gimplify.c
 ===================================================================
 --- a/src/gcc/c-family/c-gimplify.c	(.../tags/gcc_6_1_0_release)
@@ -4624,7 +5729,12 @@ Index: gcc/c-family/ChangeLog
 ===================================================================
 --- a/src/gcc/c-family/ChangeLog	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/c-family/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,32 @@
+@@ -1,3 +1,37 @@
++2016-07-05  Markus Trippelsdorf  <markus at trippelsdorf.de>
++
++	PR c++/71214
++	* c-cppbuiltin.c (c_cpp_builtins): Define __cpp_rvalue_references.
++
 +2016-06-14  Jakub Jelinek  <jakub at redhat.com>
 +
 +	Backported from mainline
@@ -5342,7 +6452,7 @@ Index: gcc/DATESTAMP
 +++ b/src/gcc/DATESTAMP	(.../branches/gcc-6-branch)
 @@ -1 +1 @@
 -20160427
-+20160705
++20160724
 Index: gcc/tree-ssa-strlen.c
 ===================================================================
 --- a/src/gcc/tree-ssa-strlen.c	(.../tags/gcc_6_1_0_release)
@@ -5604,7 +6714,15 @@ Index: gcc/fold-const.c
      }
  
    return var;
-@@ -3781,15 +3776,23 @@
+@@ -2199,7 +2194,6 @@
+ 
+     case REAL_TYPE:
+     case FIXED_POINT_TYPE:
+-    case COMPLEX_TYPE:
+     case VECTOR_TYPE:
+     case VOID_TYPE:
+       return TREE_CODE (type) == TREE_CODE (orig);
+@@ -3781,15 +3775,23 @@
  

  /* Return a BIT_FIELD_REF of type TYPE to refer to BITSIZE bits of INNER
     starting at BITPOS.  The field is unsigned if UNSIGNEDP is nonzero
@@ -5630,7 +6748,7 @@ Index: gcc/fold-const.c
    if (bitpos == 0 && !reversep)
      {
        tree size = TYPE_SIZE (TREE_TYPE (inner));
-@@ -3915,13 +3918,13 @@
+@@ -3915,13 +3917,13 @@
         and return.  */
      return fold_build2_loc (loc, code, compare_type,
  			fold_build2_loc (loc, BIT_AND_EXPR, unsigned_type,
@@ -5646,7 +6764,7 @@ Index: gcc/fold-const.c
  							 unsigned_type,
  							 nbitsize, nbitpos,
  							 1, rreversep),
-@@ -3966,8 +3969,8 @@
+@@ -3966,8 +3968,8 @@
    /* Make a new bitfield reference, shift the constant over the
       appropriate number of bits and mask it with the computed mask
       (in case this was a signed field).  If we changed it, make a new one.  */
@@ -5657,7 +6775,7 @@ Index: gcc/fold-const.c
  
    rhs = const_binop (BIT_AND_EXPR,
  		     const_binop (LSHIFT_EXPR,
-@@ -4006,11 +4009,12 @@
+@@ -4006,11 +4008,12 @@
     do anything with.  */
  
  static tree
@@ -5671,7 +6789,7 @@ Index: gcc/fold-const.c
    tree outer_type = 0;
    tree and_mask = 0;
    tree mask, inner, offset;
-@@ -4047,6 +4051,8 @@
+@@ -4047,6 +4050,8 @@
        || TREE_CODE (inner) == PLACEHOLDER_EXPR)
      return 0;
  
@@ -5680,7 +6798,7 @@ Index: gcc/fold-const.c
    /* If the number of bits in the reference is the same as the bitsize of
       the outer type, then the outer type gives the signedness. Otherwise
       (in case of a small bitfield) the signedness is unchanged.  */
-@@ -5655,19 +5661,19 @@
+@@ -5655,19 +5660,19 @@
  
    ll_reversep = lr_reversep = rl_reversep = rr_reversep = 0;
    volatilep = 0;
@@ -5704,7 +6822,7 @@ Index: gcc/fold-const.c
  				     &rr_bitsize, &rr_bitpos, &rr_mode,
  				     &rr_unsignedp, &rr_reversep, &volatilep,
  				     &rr_mask, &rr_and_mask);
-@@ -5829,12 +5835,14 @@
+@@ -5829,12 +5834,14 @@
        lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask);
        if (lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos)
  	{
@@ -5721,7 +6839,7 @@ Index: gcc/fold-const.c
  				    lr_unsignedp || rr_unsignedp, lr_reversep);
  	  if (! all_ones_mask_p (lr_mask, rnbitsize))
  	    rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask);
-@@ -5856,11 +5864,11 @@
+@@ -5856,11 +5863,11 @@
  	{
  	  tree type;
  
@@ -5735,7 +6853,7 @@ Index: gcc/fold-const.c
  				    lr_bitsize + rr_bitsize,
  				    MIN (lr_bitpos, rr_bitpos),
  				    lr_unsignedp, lr_reversep);
-@@ -5925,7 +5933,8 @@
+@@ -5925,7 +5932,8 @@
       reference we will make.  Unless the mask is all ones the width of
       that field, perform the mask operation.  Then compare with the
       merged constant.  */
@@ -5745,7 +6863,16 @@ Index: gcc/fold-const.c
  			       ll_unsignedp || rl_unsignedp, ll_reversep);
  
    ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask);
-@@ -8566,9 +8575,9 @@
+@@ -7934,6 +7942,8 @@
+     case VIEW_CONVERT_EXPR:
+       if (TREE_CODE (op0) == MEM_REF)
+         {
++	  if (TYPE_ALIGN (TREE_TYPE (op0)) != TYPE_ALIGN (type))
++	    type = build_aligned_type (type, TYPE_ALIGN (TREE_TYPE (op0)));
+ 	  tem = fold_build2_loc (loc, MEM_REF, type,
+ 				 TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1));
+ 	  REF_REVERSE_STORAGE_ORDER (tem) = REF_REVERSE_STORAGE_ORDER (op0);
+@@ -8566,9 +8576,9 @@
  	  if ((offset0 == offset1
  	       || (offset0 && offset1
  		   && operand_equal_p (offset0, offset1, 0)))
@@ -5758,7 +6885,7 @@ Index: gcc/fold-const.c
  		  || POINTER_TYPE_OVERFLOW_UNDEFINED))
  
  	    {
-@@ -8607,7 +8616,8 @@
+@@ -8607,7 +8617,8 @@
  	     6.5.6/8 and /9 with respect to the signed ptrdiff_t.  */
  	  else if (bitpos0 == bitpos1
  		   && (equality_code
@@ -5768,7 +6895,7 @@ Index: gcc/fold-const.c
  		       || POINTER_TYPE_OVERFLOW_UNDEFINED))
  	    {
  	      /* By converting to signed sizetype we cover middle-end pointer
-@@ -10514,11 +10524,15 @@
+@@ -10514,11 +10525,15 @@
  	      || TREE_CODE (arg0) == BIT_IOR_EXPR
  	      || TREE_CODE (arg0) == BIT_XOR_EXPR)
  	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
@@ -5789,7 +6916,7 @@ Index: gcc/fold-const.c
  
        /* Two consecutive rotates adding up to the some integer
  	 multiple of the precision of the type can be ignored.  */
-@@ -10527,7 +10541,7 @@
+@@ -10527,7 +10542,7 @@
  	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
  	  && wi::umod_trunc (wi::add (arg1, TREE_OPERAND (arg0, 1)),
  			     prec) == 0)
@@ -5798,7 +6925,7 @@ Index: gcc/fold-const.c
  
        return NULL_TREE;
  
-@@ -11631,9 +11645,9 @@
+@@ -11631,9 +11646,9 @@
        /* Convert A ? 0 : 1 to !A.  This prefers the use of NOT_EXPR
  	 over COND_EXPR in cases such as floating point comparisons.  */
        if (integer_zerop (op1)
@@ -5811,7 +6938,7 @@ Index: gcc/fold-const.c
  	  && truth_value_p (TREE_CODE (arg0)))
  	return pedantic_non_lvalue_loc (loc,
  				    fold_convert_loc (loc, type,
-@@ -12305,7 +12319,8 @@
+@@ -12305,7 +12320,8 @@
  	       || TYPE_REFERENCE_TO (expr)
  	       || TYPE_CACHED_VALUES_P (expr)
  	       || TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr)
@@ -5821,7 +6948,7 @@ Index: gcc/fold-const.c
      {
        /* Allow these fields to be modified.  */
        tree tmp;
-@@ -12315,6 +12330,7 @@
+@@ -12315,6 +12331,7 @@
        TYPE_POINTER_TO (tmp) = NULL;
        TYPE_REFERENCE_TO (tmp) = NULL;
        TYPE_NEXT_VARIANT (tmp) = NULL;
@@ -5829,7 +6956,7 @@ Index: gcc/fold-const.c
        if (TYPE_CACHED_VALUES_P (tmp))
  	{
  	  TYPE_CACHED_VALUES_P (tmp) = 0;
-@@ -13549,6 +13565,9 @@
+@@ -13549,6 +13566,9 @@
  	if (!DECL_P (base))
  	  base = get_base_address (base);
  
@@ -5907,7 +7034,24 @@ Index: gcc/omp-low.c
  		  t = fold_convert_loc (clause_loc, ptype, t);
  		  x = create_tmp_var (ptype);
  		  t = build2 (MODIFY_EXPR, ptype, x, t);
-@@ -13680,6 +13676,9 @@
+@@ -13356,9 +13352,15 @@
+       make_edge (else_bb, new_bb, EDGE_FALLTHRU);
+ 
+       device = tmp_var;
++      gsi = gsi_last_bb (new_bb);
+     }
++  else
++    {
++      gsi = gsi_last_bb (new_bb);
++      device = force_gimple_operand_gsi (&gsi, device, true, NULL_TREE,
++					 true, GSI_SAME_STMT);
++    }
+ 
+-  gsi = gsi_last_bb (new_bb);
+   t = gimple_omp_target_data_arg (entry_stmt);
+   if (t == NULL)
+     {
+@@ -13680,6 +13682,9 @@
    tree new_parm_decl = copy_node (DECL_ARGUMENTS (kern_fndecl));
    DECL_CONTEXT (new_parm_decl) = kern_fndecl;
    DECL_ARGUMENTS (kern_fndecl) = new_parm_decl;
@@ -5960,7 +7104,520 @@ Index: gcc/ChangeLog
 ===================================================================
 --- a/src/gcc/ChangeLog	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,1507 @@
+@@ -1,3 +1,2020 @@
++2016-07-21  Jakub Jelinek  <jakub at redhat.com>
++
++	PR sanitizer/71953
++	* asan.c (asan_dynamic_init_call): Call asan_init_shadow_ptr_types
++	before builtin_decl_implicit.
++
++	* tree-object-size.c (unknown): Use HOST_WIDE_INT_M1U instead of -1.
++
++2016-07-21  Andrew Sutton  <andrew.n.sutton at gmail.com>
++
++	Improving concepts performance and diagnostics.
++	* timevar.def (TV_CONSTRAINT_SAT, TV_CONSTRAINT_SUB): New time vars
++	for constraint satisfaction and subsumption.
++	* timevar.h (auto_timevar): New constructor that matches the push/pop
++	pattern of usage in pt.c.
++
++2016-07-20  John David Anglin  <danglin at gcc.gnu.org>
++
++	Backport from mainline
++	2016-07-16  John David Anglin  <danglin at gcc.gnu.org>
++
++	* config/pa/pa.c (hppa_profile_hook): Allocate stack space for
++	register parameters.  Remove code to initialize argument pointer
++	on TARGET_64BIT.  Optimize call to _mcount when it can be reached
++	using a pc-relative branch.  Cleanup conditional code.
++	* config/pa/pa.md (call_mcount): New expander.
++	(call_mcount_nonpic): New insn.
++	(call_mcount_pic): New insn and split.
++	(call_mcount_pic_post_reload): New insn.
++	(call_mcount_64bit): New insn and split.
++	(call_mcount_64bit_post_reload): New insn.
++
++2016-07-20  Andreas Krebbel  <krebbel at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-20  Andreas Krebbel  <krebbel at linux.vnet.ibm.com>
++
++	* config/s390/s390.c (s390_encode_section_info): Remove mode size
++	check.
++
++2016-07-20  Martin Jambor  <mjambor at suse.cz>
++
++        PR fortran/71688
++        * trans-decl.c (gfc_generate_function_code): Use get_create rather
++        than create to get a call graph node.
++
++2016-07-19  Jakub Jelinek  <jakub at redhat.com>
++
++	PR rtl-optimization/71916
++	* cfgrtl.c (contains_no_active_insn_p): Return false also for
++	bb which have a single succ fake edge.
++
++2016-07-19  Aldy Hernandez  <aldyh at redhat.com>
++
++	PR debug/71855
++	* dwarf2out.c (gen_subprogram_die): Only call
++	gen_unspecified_parameters_die while dumping early dwarf.
++
++2016-07-19  Jakub Jelinek  <jakub at redhat.com>
++
++	PR middle-end/71874
++	* gimple-fold.c (fold_builtin_memory_op): Use
++	get_addr_base_and_unit_offset instead of get_ref_base_and_extent.
++
++2016-07-18  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	Back port from mainline
++	2016-07-18  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	PR target/71493
++	* config/rs6000/rs6000.c (rs6000_function_value): Fix
++	unintentional System V.4 structure return breakage for structures
++	with a single floating point element.
++
++2016-07-18  Martin Liska  <mliska at suse.cz>
++
++	Backported from mainline
++	2016-07-12  Martin Liska  <mliska at suse.cz>
++
++	PR rtl-optimization/71634
++	* ira-build.c (mark_loops_for_removal): Properly iterate
++	loops.
++
++2016-07-18  Andreas Krebbel  <krebbel at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-18  Andreas Krebbel  <krebbel at linux.vnet.ibm.com>
++
++	* config/s390/s390.c (s390_encode_section_info): Always set
++	notaligned marker if mode size is 0 or no MEM_ALIGN info could be
++	found.
++
++2016-07-15  Alan Modra  <amodra at gmail.com>
++
++	Apply from mainline
++	2016-07-11  Alan Modra  <amodra at gmail.com>
++	* config/rs6000/rs6000.md (UNSPEC_DOLOOP): New unspec.
++	(ctr<mode>): Add unspec.
++	(ctr<mode>_internal*): Likewise.
++
++2016-07-14  Alan Modra  <amodra at gmail.com>
++
++	PR target/71733
++	* config/rs6000/rs6000.c (rs6000_option_override_internal): Deal
++	with p9_vector override before power9-dform override.
++
++2016-07-13  Ilya Enkovich  <ilya.enkovich at intel.com>
++
++	Backport from mainline r238086.
++	2016-07-07  Ilya Enkovich  <ilya.enkovich at intel.com>
++
++	PR ipa/71624
++	* ipa-inline-analysis.c (compute_inline_parameters): Set
++	local.can_change_signature to false for intrumentation
++	thunk callees.
++
++2016-07-12  Michael Meissner  <meissner at linux.vnet.ibm.com>
++	    Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-05  Michael Meissner  <meissner at linux.vnet.ibm.com>
++	            Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	* config/rs6000/rs6000-protos.h (rs6000_split_signbit): New
++	prototype.
++	* config/rs6000/rs6000.c (rs6000_split_signbit): New function.
++	* config/rs6000/rs6000.md (UNSPEC_SIGNBIT): New constant.
++	(SIGNBIT): New mode iterator.
++	(Fsignbit): New mode attribute.
++	(signbit<mode>2): Change operand1 to match FLOAT128 instead of
++	IBM128; dispatch to gen_signbit{kf,tf}2_dm for __float128
++	when direct moves are available.
++	(signbit<mode>2_dm): New define_insn_and_split).
++	(signbit<mode>2_dm2): New define_insn.
++
++2016-07-12  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-12  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	PR target/71805
++	* config/rs6000/altivec.md (altivec_vperm_<mode>_internal):
++	The xxperm and xxpermr instructions require that the 2nd input
++	operand overlap with the output operand, and not the 1st.
++	(altivec_vperm_v8hiv16qi): Likewise.
++	(altivec_vperm_<mode>_uns_internal): Likewise.
++	(altivec_vpermr_<mode>_internal): Likewise.
++	(vperm_v8hiv4si): Likewise.
++	(vperm_v16qiv8hi): Likewise.
++
++2016-07-12  Segher Boessenkool  <segher at kernel.crashing.org>
++
++	Backport from mainline
++	2016-07-06  Segher Boessenkool  <segher at kernel.crashing.org>
++
++	PR target/70098
++	PR target/71763
++	* config/rs6000/rs6000.md (*ctr<mode>_internal1, *ctr<mode>_internal2,
++	*ctr<mode>_internal5, *ctr<mode>_internal6): Add *wi to the output
++	constraint.
++
++2016-07-11  Jakub Jelinek  <jakub at redhat.com>
++
++	PR middle-end/71758
++	* omp-low.c (expand_omp_target): Gimplify device.
++
++	PR tree-optimization/71823
++	* tree-vect-stmts.c (vectorizable_operation): Use vect_get_vec_defs
++	to get vec_oprnds2 from op2.
++
++2016-07-11  Yuri Rumyantsev  <ysrumyan at gmail.com>
++
++	Backport from mainline r238055.
++	2016-07-06  Yuri Rumyantsev  <ysrumyan at gmail.com>
++
++	PR tree-optimization/71518
++	* tree-vect-data-refs.c (vect_compute_data_ref_alignment): Adjust
++	misalign also for outer loops with negative step.
++
++2016-07-08  Martin Liska  <mliska at suse.cz>
++
++	Backported from mainline
++	2016-07-08  Martin Liska  <mliska at suse.cz>
++
++	PR middle-end/71606
++	* fold-const.c (fold_convertible_p): As COMPLEX_TYPE
++	folding produces SAVE_EXPRs, thus return false for the type.
++
++2016-07-08  Kelvin Nilsen  <kelvin at gcc.gnu.org>
++
++	* config/rs6000/rs6000-builtin.def (BU_P9_MISC_1): Remove
++	redundant and erroneous definition of this macro accidentally
++	inserted during backporting.
++	(BU_P9_64BIT_MISC_0): Likewise.
++	(BU_P9_MISC_0): Likewise.
++
++2016-07-08  Jiong Wang  <jiong.wang at arm.com>
++
++	Back port from the trunk
++	2016-07-08  Jiong Wang  <jiong.wang at arm.com>
++
++	* config/aarch64/aarch64-simd-builtins.def (smax): Remove float
++	variants.
++	(smin): Likewise.
++	(fmax): New entry.
++	(fmin): Likewise.
++	* config/aarch64/arm_neon.h (vmaxnm_f32): Use
++	__builtin_aarch64_fmaxv2sf.
++	(vmaxnmq_f32): Likewise.
++	(vmaxnmq_f64): Likewise.
++	(vminnm_f32): Likewise.
++	(vminnmq_f32): Likewise.
++	(vminnmq_f64): Likewise.
++
++2016-07-08  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	Back port from trunk
++	2016-07-08  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	PR target/71806
++	* config/rs6000/rs6000-cpus.def (ISA_3_0_MASKS_SERVER): Do not
++	enable -mfloat128-hardware by default.
++	(ISA_3_0_MASKS_IEEE): New macro to give all of the VSX options
++	that IEEE 128-bit hardware support needs.
++	* config/rs6000/rs6000.c (rs6000_option_override_internal): If
++	-mcpu=power9 -mfloat128, enable -mfloat128-hardware by default.
++	Use ISA_3_0_MASKS_IEEE as the set of options that IEEE 128-bit
++	floating point requires.
++	* doc/invoke.texi (RS/6000 and PowerPC Options): Document
++	-mfloat128 and -mfloat128-hardware changes.
++
++2016-07-08  Kelvin Nilsen  <kelvin at gcc.gnu.org>
++
++	Backport from mainline r237912
++	2016-07-01  Kelvin Nilsen  <kelvin at gcc.gnu.org>
++
++	* config/rs6000/altivec.md (*altivec_vpermr_<mode>_internal):
++	Exchange the order of the second and third operands in the vpermr
++	instruction tmeplate.
++
++2016-07-07  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	Back port from the trunk
++	2016-07-01  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	PR target/71720
++	* config/rs6000/vsx.md (vsx_splat_v4sf_internal): When splitting
++	the insns, use an insn form that does not adjust the offset on
++	little endian systems.
++
++2016-07-07  Kelvin Nilsen  <kelvin at gcc.gnu.org>
++
++	Backport from mainline r237885
++	2016-06-30  Kelvin Nilsen  <kelvin at gcc.gnu.org>
++
++	* config/rs6000/altivec.md (darn_32): Change the condition to
++	TARGET_P9_MISC instead of TARGET_MODULO.
++	(darn_raw): Replace TARGET_MODULO with TARGET_P9_MISC in the
++	condition expression.
++	(darn): Replace TARGET_MODULO with TARGET_P9_MISC in the
++	condition expression.
++	* config/rs6000/dfp.md (UNSPEC_DTSTSFI): New unspec constant.
++	(DFP_TEST): New code iterator.
++	(dfptstsfi_<code>_mode>): New define_expand.
++	(*dfp_sgnfcnc_<mode>): New define_insn.
++	* config/rs6000/rs6000-builtin.def (BU_P9_MISC_0): Move this macro
++	definition next to BU_P9_MISC_1 definition and change the MASK
++	value to RS6000_BTM_P9_MISC.
++	(BU_P9_MISC_1): Change the MASK value to RS6000_BTM_P9_MISC.
++	(BU_P9_64BIT_MISC_0): Likewise.
++	(BU_P9_DFP_MISC_0): New macro definition.
++	(BU_P9_DFP_MISC_1): New macro definition.
++	(BU_P9_DFP_MISC_2): New macro definition.
++	(BU_P9_DFP_OVERLOAD_1): New macro definition.
++	(BU_P9_DFP_OVERLOAD_2): New macro definition.
++	(BU_P9_DFP_OVERLOAD_3): New macro definition.
++	(TSTSFI_LT_DD): New BU_P9_DFP_MISC_2.
++	(TSTSFI_LT_TD): Likewise.
++	(TSTSFI_EQ_DD): Likewise.
++	(TSTSFI_EQ_TD): Likewise.
++	(TSTSFI_GT_DD): Likewise.
++	(TSTSFI_GT_TD): Likewise.
++	(TSTSFI_OV_DD): Likewise.
++	(TSTSFI_OV_TD): Likewise.
++	(TSTSFI_LT): New BU_P9_DFP_OVERLOAD_2.
++	(TSTSFI_LT_DD): Likewise.
++	(TSTSFI_LT_TD): Likewise.
++	(TSTSFI_EQ): Likewise.
++	(TSTSFI_EQ_DD): Likewise.
++	(TSTSFI_EQ_TD): Likewise.
++	(TSTSFI_GT): Likewise.
++	(TSTSFI_GT_DD): Likewise.
++	(TSTSFI_GT_TD): Likewise.
++	(TSTSFI_OV): Likewise.
++	(TSTSFI_OV_DD): Likewise.
++	(TSTSFI_OV_TD): Likewise.
++	* config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add
++	overloaded test significance functions.
++	* config/rs6000/rs6000-cpus.def (ISA_3_0_MASKS_SERVER): Add
++	OPTION_MASK_P9_MISC into the representation of this mask.
++	(POWERPC_MASKS): Add OPTION_MASK_P9_MISC into the representation
++	of this mask.
++	* config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Set the
++	RS6000_BTM_P9_MISC flag in the return value if TARGET_P9_MISC is
++	non-zero.
++	(rs6000_expand_binop_builtin): Enforce that argument 0 of the exp
++	argument is a 6-bit unsigned literal value if the icode argument
++	represents a DFP test significance built-in call.
++	(rs6000_invalid_builtin): Add support for the RS6000_BTM_P9_MISC
++	flag used independently and in combination with the
++	RS6000_BTM_64BIT flag.
++	(rs6000_opt_masks): Add entry for power9-misc command-line option.
++	(rs6000_builtin_mask_names): Add entry for power9-misc
++	command-line option.
++	* config/rs6000/rs6000.h: Redefine TARGET_P9_MISC as 0 if
++	HAVE_AS_POWER9 is not a defined macro.  Define MASK_P9_MISC and
++	RS6000_BTM_P9_MISC macros.
++	* config/rs6000/rs6000.opt: Add support for the -mpower9-misc
++	option and change the description of the -mpower9-vector option to
++	enable only vector instructions, removing its erroneously claimed
++	support for scalar instructions.
++	* doc/extend.texi (PowerPC AltiVec Built-in Functions): Document
++	the ISA 3.0 digital floating point test significance built-in
++	functions.
++
++2016-07-07  Richard Biener  <rguenther at suse.de>
++
++	Backport from mainline
++	2016-06-13  Richard Biener  <rguenther at suse.de>
++
++	PR middle-end/64516
++	* fold-const.c (fold_unary_loc): Preserve alignment when
++	folding a VIEW_CONVERT_EXPR into a MEM_REF.
++
++2016-07-07  Richard Biener  <rguenther at suse.de>
++
++	Backport from mainline
++	2016-05-25  Richard Biener  <rguenther at suse.de>
++
++	PR tree-optimization/71264
++	* tree-vect-stmts.c (vect_init_vector): Properly deal with
++	vector type val.
++
++	2016-06-07  Richard Biener  <rguenther at suse.de>
++
++	PR middle-end/71423
++	* match.pd ((X | ~Y) -> Y <= X): Properly invert the comparison
++	for signed ops.
++
++	2016-06-14  Richard Biener  <rguenther at suse.de>
++
++	PR tree-optimization/71521
++	* tree-vrp.c (extract_range_from_binary_expr_1): Guard
++	division int_const_binop against zero divisor.
++
++	2016-06-08  Richard Biener  <rguenther at suse.de>
++
++	PR tree-optimization/71452
++	* tree-ssa.c (non_rewritable_lvalue_p): Make sure that the
++	type used for the SSA rewrite has enough precision to cover
++	the dynamic type of the location.
++
++	2016-06-14  Richard Biener  <rguenther at suse.de>
++
++	PR tree-optimization/71522
++	* tree-ssa.c (non_rewritable_lvalue_p): Do not rewrite non-float
++	copying into float copying.
++
++2016-07-06  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj at atmel.com>
++
++	Backport from mainline
++	2016-07-06  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj at atmel.com>
++
++	PR target/50739	
++	* config/avr/avr.c (avr_asm_select_section): Strip off
++	SECTION_DECLARED from flags when calling get_section.
++
++2016-07-05  Pat Haugen  <pthaugen at us.ibm.com>
++
++	Backport from mainline
++	2016-06-28  Pat Haugen  <pthaugen at us.ibm.com>
++
++	* config/rs6000/rs6000.md ('type' attribute): Add htmsimple/dfp types.
++	('size' attribute): Add '128'.
++	Include power9.md.
++	(*mov<mode>_hardfloat32, *mov<mode>_hardfloat64, *movdi_internal32,
++	*movdi_internal64, *movdf_update1): Set size attribute to '64'.
++	(add<mode>3, sub<mode>3, mul<mode>3, div<mode>3, sqrt<mode>2,
++	copysign<mode>3, neg<mode>2_hw, abs<mode>2_hw, *nabs<mode>2_hw,
++	*fma<mode>4_hw, *fms<mode>4_hw, *nfma<mode>4_hw, *nfms<mode>4_hw,
++	extend<SFDF:mode><IEEE128:mode>2_hw, trunc<mode>df2_hw,
++	*xscvqp<su>wz_<mode>, *xscvqp<su>dz_<mode>, *xscv<su>dqp_<mode>,
++	*trunc<mode>df2_odd): Set size attribute to '128'.
++	(*cmp<mode>_hw): Change type to veccmp and set size attribute to '128'.
++	* config/rs6000/power6.md (power6-fp): Include dfp type.
++	* config/rs6000/power7.md (power7-fp): Likewise.
++	* config/rs6000/power8.md (power8-fp): Likewise.
++	* config/rs6000/power9.md: New file.
++	* config/rs6000/t-rs6000 (MD_INCLUDES): Add power9.md.
++	* config/rs6000/htm.md (*tabort, *tabort<wd>c, *tabort<wd>ci,
++	*trechkpt, *treclaim, *tsr, *ttest): Change type attribute to
++	htmsimple.
++	* config/rs6000/dfp.md (extendsddd2, truncddsd2, extendddtd2,
++	trunctddd2, adddd3, addtd3, subdd3, subtd3, muldd3, multd3, divdd3,
++	divtd3, *cmpdd_internal1, *cmptd_internal1, floatdidd2, floatditd2,
++	ftruncdd2, fixdddi2, ftrunctd2, fixtddi2, dfp_ddedpd_<mode>,
++	dfp_denbcd_<mode>, dfp_dxex_<mode>, dfp_diex_<mode>, dfp_dscli_<mode>,
++	dfp_dscri_<mode>): Change type attribute to dfp.
++	* config/rs6000/crypto.md (crypto_vshasigma<CR_char>): Change type
++	attribute to vecsimple.
++	* config/rs6000/rs6000.c (power9_cost): Update costs, cache size
++	and prefetch streams.
++	(rs6000_option_override_internal): Remove temporary code setting
++	tuning to power8.  Don't set rs6000_sched_groups for power9.
++	(last_scheduled_insn): Change to rtx_insn *.
++	(divide_cnt, vec_load_pendulum): New variables.
++	(rs6000_adjust_cost): Add Power9 to test for store->load separation.
++	(rs6000_issue_rate): Set issue rate for Power9.
++	(is_power9_pairable_vec_type): New.
++	(power9_sched_reorder2): New.
++	(rs6000_sched_reorder2): Call new function for Power9 specific
++	reordering.
++	(insn_must_be_first_in_group): Remove Power9.
++	(insn_must_be_last_in_group): Likewise.
++	(force_new_group): Likewise.
++	(rs6000_sched_init): Fix initialization of last_scheduled_insn.
++	Initialize divide_cnt/vec_load_pendulum.
++	(_rs6000_sched_context, rs6000_init_sched_context,
++	rs6000_set_sched_context): Handle context save/restore of new
++	variables.
++
++2016-07-05  Pat Haugen  <pthaugen at us.ibm.com>
++
++	Backport from mainline
++	2016-06-27  Pat Haugen  <pthaugen at us.ibm.com>
++
++	* config/rs6000/rs6000.md ('type' attribute): Add
++	veclogical,veccmpfx,vecexts,vecmove insn types.
++	(*abs<mode>2_fpr, *nabs<mode>2_fpr, *neg<mode>2_fpr, *extendsfdf2_fpr,
++	copysign<mode>3_fcpsgn, trunc<mode>df2_internal1, neg<mode>2_internal,
++	p8_fmrgow_<mode>, pack<mode>): Change type to fpsimple.
++	(*xxsel<mode>, copysign<mode>3_hard, neg<mode>2_hw, abs<mode>2_hw,
++	*nabs<mode>2_hw): Change type to vecmove.
++	(*and<mode>3_internal, *bool<mode>3_internal, *boolc<mode>3_internal,
++	*boolcc<mode>3_internal, *eqv<mode>3_internal,
++	*one_cmpl<mode>3_internal, *ieee_128bit_vsx_neg<mode>2_internal,
++	*ieee_128bit_vsx_abs<mode>2_internal,
++	*ieee_128bit_vsx_nabs<mode>2_internal, extendkftf2, trunctfkf2,
++	*ieee128_mfvsrd_64bit, *ieee128_mfvsrd_32bit, *ieee128_mtvsrd_64bit,
++	*ieee128_mtvsrd_32bit): Change type to veclogical.
++	(mov<mode>_hardfloat, *mov<mode>_hardfloat32, *mov<mode>_hardfloat64,
++	*movdi_internal32, *movdi_internal64): Update insn types.
++	* config/rs6000/vsx.md (*vsx_le_undo_permute_<mode>,
++	vsx_extract_<mode>): Change type to veclogical.
++	(*vsx_xxsel<mode>, *vsx_xxsel<mode>_uns): Change type to vecmove.
++	(vsx_sign_extend_qi_<mode>, *vsx_sign_extend_hi_<mode>,
++	*vsx_sign_extend_si_v2di): Change type to vecexts.
++	* config/rs6000/altivec.md (*altivec_mov<mode>, *altivec_movti): Change
++	type to veclogical.
++	(*altivec_eq<mode>, *altivec_gt<mode>, *altivec_gtu<mode>,
++	*altivec_vcmpequ<VI_char>_p, *altivec_vcmpgts<VI_char>_p,
++	*altivec_vcmpgtu<VI_char>_p): Change type to veccmpfx.
++	(*altivec_vsel<mode>, *altivec_vsel<mode>_uns): Change type to vecmove.
++	* config/rs6000/dfp.md (*negdd2_fpr, *absdd2_fpr, *nabsdd2_fpr,
++	negtd2, *abstd2_fpr, *nabstd2_fpr): Change type to fpsimple.
++	* config/rs6000/40x.md (ppc405-float): Add fpsimple.
++	* config/rs6000/440.md (ppc440-fp): Add fpsimple.
++	* config/rs6000/476.md (ppc476-fp): Add fpsimple.
++	* config/rs6000/601.md (ppc601-fp): Add fpsimple.
++	* config/rs6000/603.md (ppc603-fp): Add fpsimple.
++	* config/rs6000/6xx.md (ppc604-fp): Add fpsimple.
++	* config/rs6000/7xx.md (ppc750-fp): Add fpsimple.
++	(ppc7400-vecsimple): Add veclogical, vecmove, veccmpfx.
++	* config/rs6000/7450.md (ppc7450-fp): Add fpsimple.
++	(ppc7450-vecsimple): Add veclogical, vecmove.
++	(ppc7450-veccmp): Add veccmpfx.
++	* config/rs6000/8540.md (ppc8540_simple_vector): Add veclogical,
++	vecmove.
++	(ppc8540_vector_compare): Add veccmpfx.
++	* config/rs6000/a2.md (ppca2-fp): Add fpsimple.
++	* config/rs6000/cell.md (cell-fp): Add fpsimple.
++	(cell-vecsimple): Add veclogical, vecmove.
++	(cell-veccmp): Add veccmpfx.
++	* config/rs6000/e300c2c3.md (ppce300c3_fp): Add fpsimple.
++	* config/rs6000/e6500.md (e6500_vecsimple): Add veclogical, vecmove,
++	veccmpfx.
++	* config/rs6000/mpc.md (mpccore-fp): Add fpsimple.
++	* config/rs6000/power4.md (power4-fp): Add fpsimple.
++	(power4-vecsimple): Add veclogical, vecmove.
++	(power4-veccmp): Add veccmpfx.
++	* config/rs6000/power5.md (power5-fp): Add fpsimple.
++	* config/rs6000/power6.md (power6-fp): Add fpsimple.
++	(power6-vecsimple): Add veclogical, vecmove.
++	(power6-veccmp): Add veccmpfx.
++	* config/rs6000/power7.md (power7-fp): Add fpsimple.
++	(power7-vecsimple): Add veclogical, vecmove, veccmpfx.
++	* config/rs6000/power8.md (power8-fp): Add fpsimple.
++	(power8-vecsimple): Add veclogical, vecmove, veccmpfx.
++	* config/rs6000/rs64.md (rs64a-fp): Add fpsimple.
++	* config/rs6000/titan.md (titan_fp): Add fpsimple.
++	* config/rs6000/xfpu.md (fp-default, fp-addsub-s, fp-addsub-d): Add
++	fpsimple.
++	* config/rs6000/rs6000.c (rs6000_adjust_cost): Add TYPE_FPSIMPLE.
++
++2016-07-05  Kelvin Nilsen  <kelvin at gcc.gnu.org>
++
++	Backport from mainline r237391
++	2016-06-13  Kelvin Nilsen  <kelvin at gcc.gnu.org>
++
++	* config/rs6000/rs6000.h (RS6000_BTM_COMMON): Add the
++	RS6000_BTM_MODULO flag into the set of flags that are considered
++	to be part of the common configuration.
++
 +2016-07-04  Jakub Jelinek  <jakub at redhat.com>
 +
 +	PR c++/71739
@@ -7468,7 +9125,7 @@ Index: gcc/ChangeLog
  2016-04-27  Release Manager
  
  	* GCC 6.1.0 released.
-@@ -49,7 +1553,7 @@
+@@ -49,7 +2066,7 @@
  	constant boolean.
  
  2016-04-20  Andrew Pinski  <apinski at cavium.com>
@@ -7965,6 +9622,24 @@ Index: gcc/testsuite/gcc.target/powerpc/darn-2.c
 +}
 +
 +/* { dg-final { scan-assembler	   "darn" } } */
+Index: gcc/testsuite/gcc.target/powerpc/pr71493-2.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/pr71493-2.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/pr71493-2.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,13 @@
++/* { dg-do compile { target { powerpc*-*-linux* && ilp32 } } } */
++/* { dg-options "-O2 -msvr4-struct-return" } */
++
++struct S2 { double d; };
++
++struct S2 foo2 (void)
++{
++  struct S2 s = { 1.0 };
++  return s;
++}
++
++/* { dg-final { scan-assembler     "lwz" } } */
++/* { dg-final { scan-assembler-not "lfd" } } */
 Index: gcc/testsuite/gcc.target/powerpc/p9-minmax-2.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/p9-minmax-2.c	(.../tags/gcc_6_1_0_release)
@@ -8273,6 +9948,36 @@ Index: gcc/testsuite/gcc.target/powerpc/p9-vparity.c
 +/* { dg-final { scan-assembler "vprtybd" } } */
 +/* { dg-final { scan-assembler "vprtybq" } } */
 +/* { dg-final { scan-assembler "vprtybw" } } */
+Index: gcc/testsuite/gcc.target/powerpc/pr71763.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/pr71763.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/pr71763.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,25 @@
++// PR target/71763
++// { dg-do compile }
++// { dg-options "-O1 -mvsx" }
++
++int a, b;
++float c;
++
++void fn2(void);
++
++void fn1(void)
++{
++        long d;
++
++        for (d = 3; d; d--) {
++                for (a = 0; a <= 1; a++) {
++                        b &= 1;
++                        if (b) {
++                                for (;;) {
++                                        fn2();
++                                        c = d;
++                                }
++                        }
++                }
++        }
++}
 Index: gcc/testsuite/gcc.target/powerpc/p8vector-int128-1.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/p8vector-int128-1.c	(.../tags/gcc_6_1_0_release)
@@ -8577,6 +10282,27 @@ Index: gcc/testsuite/gcc.target/powerpc/copysign128-1.c
 +
 +  return 0;
 +}
+Index: gcc/testsuite/gcc.target/powerpc/signbit-1.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/signbit-1.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/signbit-1.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { 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 -mfloat128" } */
++
++int do_signbit_kf (__float128 a) { return __builtin_signbit (a); }
++int do_signbit_if (__ibm128 a) { return __builtin_signbit (a); }
++int do_signbit_tf (long double a) { return __builtin_signbit (a); }
++
++/* { dg-final { scan-assembler-not   "stxvd2x"  } } */
++/* { dg-final { scan-assembler-not   "stxvw4x"  } } */
++/* { dg-final { scan-assembler-not   "stxsd"    } } */
++/* { dg-final { scan-assembler-not   "stxsdx"   } } */
++/* { dg-final { scan-assembler-times "mfvsrd" 3 } } */
++/* { dg-final { scan-assembler-times "srdi"   3 } } */
 Index: gcc/testsuite/gcc.target/powerpc/vadsdub-1.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/vadsdub-1.c	(.../tags/gcc_6_1_0_release)
@@ -8628,6 +10354,29 @@ Index: gcc/testsuite/gcc.target/powerpc/vsrv-0.c
 +}
 +
 +/* { dg-final { scan-assembler "vsrv" } } */
+Index: gcc/testsuite/gcc.target/powerpc/signbit-2.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/signbit-2.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/signbit-2.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { 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 -mfloat128" } */
++
++int do_signbit_kf (__float128 *a) { return __builtin_signbit (*a); }
++
++/* { dg-final { scan-assembler-not   "stxvd2x"  } } */
++/* { dg-final { scan-assembler-not   "stxvw4x"  } } */
++/* { dg-final { scan-assembler-not   "stxsd"    } } */
++/* { dg-final { scan-assembler-not   "stxsdx"   } } */
++/* { dg-final { scan-assembler-not   "lxvd2x"   } } */
++/* { dg-final { scan-assembler-not   "lxvw4x"   } } */
++/* { dg-final { scan-assembler-not   "lxsd"     } } */
++/* { dg-final { scan-assembler-not   "lxsdx"    } } */
++/* { dg-final { scan-assembler-times "ld"     1 } } */
++/* { dg-final { scan-assembler-times "srdi"   1 } } */
 Index: gcc/testsuite/gcc.target/powerpc/vadsdub-2.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/vadsdub-2.c	(.../tags/gcc_6_1_0_release)
@@ -8834,6 +10583,183 @@ Index: gcc/testsuite/gcc.target/powerpc/ctz-3.c
 +/* { dg-final { scan-assembler-times "vctzw" 2 } } */
 +/* { dg-final { scan-assembler-not "cnttzd" } } */
 +/* { dg-final { scan-assembler-not "cnttzw" } } */
+Index: gcc/testsuite/gcc.target/powerpc/signbit-3.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/signbit-3.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/signbit-3.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,172 @@
++/* { dg-do run { target { powerpc*-*-linux* } } } */
++/* { dg-require-effective-target ppc_float128_sw } */
++/* { dg-options "-mcpu=power7 -O2 -mfloat128 -lm" } */
++
++#ifdef DEBUG
++#include <stdio.h>
++#endif
++
++#include <stddef.h>
++#include <stdint.h>
++#include <inttypes.h>
++#include <stdlib.h>
++#include <math.h>
++
++#if defined(__BIG_ENDIAN__)
++struct ieee128 {
++  uint64_t upper;
++  uint64_t lower;
++};
++
++#elif defined(__LITTLE_ENDIAN__)
++struct ieee128 {
++  uint64_t lower;
++  uint64_t upper;
++};
++
++#else
++#error "Unknown system"
++#endif
++
++union ieee_union {
++  __float128 f128;
++  struct ieee128 st128;
++};
++
++#ifdef DEBUG
++static int num_errors = 0;
++
++__attribute__((__noinline__))
++static void
++failure (int expected, int got, __float128 x)
++{
++  unsigned sign;
++  unsigned exponent;
++  uint64_t mantissa1;
++  uint64_t mantissa2;
++  uint64_t upper;
++  uint64_t lower;
++
++  union ieee_union u;
++
++  u.f128 = x;
++  upper  = u.st128.upper;
++  lower  = u.st128.lower;
++
++  sign      = (unsigned)((upper >> 63) & 1);
++  exponent  = (unsigned)((upper >> 48) & ((((uint64_t)1) << 16) - 1));
++  mantissa1 = (upper & ((((uint64_t)1) << 48) - 1));
++  mantissa2 = lower;
++
++  printf ("Expected %d, got %d, %c 0x%.4x 0x%.12" PRIx64 " 0x%.16" PRIx64,
++	  expected, got,
++	  sign ? '-' : '+',
++	  exponent,
++	  mantissa1,
++	  mantissa2);
++
++  num_errors++;
++}
++
++#else
++
++#define failure(E, G, F) abort ()
++#endif
++
++__attribute__((__noinline__))
++static void
++test_signbit_arg (__float128 f128, int expected)
++{
++  int sign = __builtin_signbit (f128);
++
++  if ((expected != 0 && sign == 0)
++      || (expected == 0 && sign != 0))
++    failure (f128, expected, sign);
++}
++
++__attribute__((__noinline__))
++static void
++test_signbit_mem (__float128 *ptr, int expected)
++{
++  int sign = __builtin_signbit (*ptr);
++
++  if ((expected != 0 && sign == 0)
++      || (expected == 0 && sign != 0))
++    failure (*ptr, expected, sign);
++}
++
++__attribute__((__noinline__))
++static void
++test_signbit_gpr (__float128 *ptr, int expected)
++{
++  __float128 f128 = *ptr;
++  int sign;
++
++  __asm__ (" # %0" : "+r" (f128));
++
++  sign = __builtin_signbit (f128);
++  if ((expected != 0 && sign == 0)
++      || (expected == 0 && sign != 0))
++    failure (f128, expected, sign);
++}
++
++__attribute__((__noinline__))
++static void
++test_signbit (__float128 f128, int expected)
++{
++#ifdef DEBUG
++  union ieee_union u;
++  u.f128 = f128;
++  printf ("Expecting %d, trying %-5g "
++	  "(0x%.16" PRIx64 " 0x%.16" PRIx64 ")\n",
++	  expected, (double)f128,
++	  u.st128.upper, u.st128.lower);
++#endif
++
++  test_signbit_arg (f128,  expected);
++  test_signbit_mem (&f128, expected);
++  test_signbit_gpr (&f128, expected);
++}
++
++int
++main (void)
++{
++  union ieee_union u;
++
++  test_signbit (+0.0q, 0);
++  test_signbit (+1.0q, 0);
++
++  test_signbit (-0.0q, 1);
++  test_signbit (-1.0q, 1);
++
++  test_signbit (__builtin_copysign (__builtin_infq (), +1.0q), 0);
++  test_signbit (__builtin_copysign (__builtin_infq (), -1.0q), 1);
++
++  test_signbit (__builtin_copysign (__builtin_nanq (""), +1.0q), 0);
++  test_signbit (__builtin_copysign (__builtin_nanq (""), -1.0q), 1);
++
++  /* force the bottom double word to have specific bits in the 'sign' bit to
++     make sure we are picking the right word.  */
++  u.f128 = 1.0q;
++  u.st128.lower = 0ULL;
++  test_signbit (u.f128, 0);
++
++  u.st128.lower = ~0ULL;
++  test_signbit (u.f128, 0);
++
++  u.f128 = -1.0q;
++  u.st128.lower = 0ULL;
++  test_signbit (u.f128, 1);
++
++  u.st128.lower = ~0ULL;
++  test_signbit (u.f128, 1);
++
++#ifdef DEBUG
++  printf ("%d error(s) were found\n", num_errors);
++  if (num_errors)
++    return num_errors;
++#endif
++
++  return 0;
++}
++
 Index: gcc/testsuite/gcc.target/powerpc/vslv-1.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/vslv-1.c	(.../tags/gcc_6_1_0_release)
@@ -8971,6 +10897,18 @@ Index: gcc/testsuite/gcc.target/powerpc/ctz-4.c
 +/* { dg-final { scan-assembler "vctzw" } } */
 +/* { dg-final { scan-assembler-not "cnttzd" } } */
 +/* { dg-final { scan-assembler-not "cnttzw" } } */
+Index: gcc/testsuite/gcc.target/powerpc/p9-lxvx-stxvx-3.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/p9-lxvx-stxvx-3.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/p9-lxvx-stxvx-3.c	(.../branches/gcc-6-branch)
+@@ -1,6 +1,6 @@
+ /* { dg-do compile { target { powerpc64le-*-* } } } */
+ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+-/* { dg-options "-mcpu=power9 -O3" } */
++/* { dg-options "-mcpu=power9 -O3 -mfloat128" } */
+ /* { dg-require-effective-target powerpc_p9vector_ok } */
+ /* { dg-final { scan-assembler "lxvx" } } */
+ /* { dg-final { scan-assembler "stxvx" } } */
 Index: gcc/testsuite/gcc.target/powerpc/pr47755.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/pr47755.c	(.../tags/gcc_6_1_0_release)
@@ -8984,6 +10922,26 @@ Index: gcc/testsuite/gcc.target/powerpc/pr47755.c
  /* { dg-final { scan-assembler-not "lxvd2x" } } */
  /* { dg-final { scan-assembler-not "lxvw4x" } } */
  /* { dg-final { scan-assembler-not "lvx" } } */
+Index: gcc/testsuite/gcc.target/powerpc/pr71720.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/pr71720.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/pr71720.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { 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" } */
++
++/* Verify that we generate xxspltw <reg>,<reg>,0 for V4SFmode splat.  */
++
++vector float
++splat_v4sf (float f)
++{
++  return (vector float) { f, f, f, f };
++}
++
++/* { dg-final { scan-assembler "xscvdpspn "      } } */
++/* { dg-final { scan-assembler "xxspltw .*,.*,0" } } */
 Index: gcc/testsuite/gcc.target/powerpc/pr71698.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/pr71698.c	(.../tags/gcc_6_1_0_release)
@@ -9002,6 +10960,34 @@ Index: gcc/testsuite/gcc.target/powerpc/pr71698.c
 +{
 +  testvad128 (1, g01d128);
 +}
+Index: gcc/testsuite/gcc.target/powerpc/divkc3-1.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/divkc3-1.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/divkc3-1.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,23 @@
++/* { dg-do run { target { powerpc64*-*-* && vsx_hw } } } */
++/* { dg-require-effective-target powerpc_p8vector_ok } */
++/* { dg-options "-mfloat128 -mvsx" } */
++
++void abort ();
++
++typedef __complex float __cfloat128 __attribute__((mode(KC)));
++
++__cfloat128 divide (__cfloat128 x, __cfloat128 y)
++{
++  return x / y;
++}
++
++__cfloat128 z, a;
++
++int main ()
++{
++  z = divide (5.0q + 5.0jq, 2.0q + 1.0jq);
++  a = 3.0q + 1.0jq;
++  if (z != a)
++    abort ();
++  return 0;
++}
 Index: gcc/testsuite/gcc.target/powerpc/vadsdu-0.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/vadsdu-0.c	(.../tags/gcc_6_1_0_release)
@@ -9352,6 +11338,1776 @@ Index: gcc/testsuite/gcc.target/powerpc/float128-complex-1.c
 +FLOAT128_CALL ()
 +LDOUBLE_CALL  ()
 +#endif
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-21.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-21.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-21.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_gt_dd requires" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-40.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-40.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-40.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-23.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-23.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-23.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  if (__builtin_dfp_dtstsfi_gt (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-25.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-25.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-25.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-61.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-61.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-61.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_ov_dd requires" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-63.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-63.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-63.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  if (__builtin_dfp_dtstsfi_ov (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-46.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-46.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-46.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_eq_td requires" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-65.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-65.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-65.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-48.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-48.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-48.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  if (__builtin_dfp_dtstsfi_eq (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-0.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-0.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-0.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-6.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-6.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-6.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_lt_td requires" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-8.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-8.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-8.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  if (__builtin_dfp_dtstsfi_lt (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-11.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-11.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-11.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt_dd (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_lt_dd requires" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-30.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-30.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-30.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt_dd (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-13.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-13.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-13.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  if (__builtin_dfp_dtstsfi_lt_dd (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-51.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-51.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-51.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq_dd (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_eq_dd requires" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-15.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-15.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-15.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt_td (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-70.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-70.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-70.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov_dd (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-53.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-53.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-53.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  if (__builtin_dfp_dtstsfi_eq_dd (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-36.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-36.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-36.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt_td (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_gt_td requires" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-55.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-55.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-55.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq_td (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-38.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-38.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-38.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  if (__builtin_dfp_dtstsfi_gt_td (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-76.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-76.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-76.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov_td (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_ov_td requires" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-78.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-78.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-78.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  if (__builtin_dfp_dtstsfi_ov_td (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-20.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-20.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-20.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-41.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-41.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-41.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_eq_dd requires" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-60.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-60.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-60.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-43.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-43.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-43.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  if (__builtin_dfp_dtstsfi_eq (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-26.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-26.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-26.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_gt_td requires" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-45.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-45.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-45.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-28.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-28.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-28.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  if (__builtin_dfp_dtstsfi_gt (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-66.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-66.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-66.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_ov_td requires" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-68.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-68.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-68.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  if (__builtin_dfp_dtstsfi_ov (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-1.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-1.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-1.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_lt_dd requires" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-3.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-3.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-3.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  if (__builtin_dfp_dtstsfi_lt (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-5.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-5.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-5.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-10.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-10.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-10.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt_dd (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-31.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-31.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-31.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt_dd (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_gt_dd requires" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-50.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-50.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-50.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq_dd (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-33.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-33.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-33.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  if (__builtin_dfp_dtstsfi_gt_dd (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-16.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-16.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-16.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_lt_td (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_lt_td requires" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-35.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-35.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-35.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt_td (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-71.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-71.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-71.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov_dd (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_ov_dd requires" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
++{
++  _Decimal64 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-18.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-18.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-18.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  if (__builtin_dfp_dtstsfi_lt_td (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-73.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-73.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-73.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal64 *p)
++{
++  _Decimal64 source = *p;
++
++  if (__builtin_dfp_dtstsfi_ov_dd (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfi" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-56.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-56.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-56.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power8" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_eq_td (5, source);	/* { dg-error "Builtin function __builtin_dtstsfi_eq_td requires" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_gt_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-75.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-75.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-75.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++/* This test should succeed on both 32- and 64-bit configurations.  */
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov_td (5, source);
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-58.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-58.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-58.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  if (__builtin_dfp_dtstsfi_eq_td (63, source))
++    return 3;
++  else
++    return 5;
++}
++
++/* { dg-final { scan-assembler	   "dtstsfiq" } } */
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
++
++
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-require-effective-target powerpc_p9vector_ok } */
++/* { dg-skip-if "" { powerpc*-*-aix* } } */
++/* { dg-options "-mcpu=power9" } */
++
++#include <altivec.h>
++
++int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
++{
++  _Decimal128 source = *p;
++
++  return __builtin_dfp_dtstsfi_ov_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
++}
+Index: gcc/testsuite/gcc.target/powerpc/dfp/dfp.exp
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/dfp/dfp.exp	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/dfp/dfp.exp	(.../branches/gcc-6-branch)
+@@ -0,0 +1,39 @@
++# Copyright (C) 2014-2016 Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++#
++# GCC is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3.  If not see
++# <http://www.gnu.org/licenses/>.
++
++# Exit immediately if this isn't a PowerPC target.
++if { ![istarget powerpc*-*-*] && ![istarget rs6000-*-*] } then {
++  return
++}
++
++global DEFAULT_CFLAGS
++if ![info exists DEFAULT_CFLAGS] then {
++  set DEFAULT_CFLAGS " -ansi -pedantic-errors"
++}
++
++# Load support procs.
++load_lib gcc-dg.exp
++load_lib torture-options.exp
++
++# Initialize.
++dg-init
++
++dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c*]] "" $DEFAULT_CFLAGS
++
++# All done.
++dg-finish
 Index: gcc/testsuite/gcc.target/powerpc/inf128-1.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/inf128-1.c	(.../tags/gcc_6_1_0_release)
@@ -9441,6 +13197,124 @@ Index: gcc/testsuite/gcc.target/powerpc/vadsdu-2.c
 +}
 +
 +/* { dg-final { scan-assembler "vabsduh" } } */
+Index: gcc/testsuite/gcc.target/powerpc/pr71805.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/pr71805.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/pr71805.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,113 @@
++/* { dg-require-effective-target p9vector_hw } */
++/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
++/* { dg-options "-mcpu=power9 -O3 --param tree-reassoc-width=1" } */
++
++/* Originally from gcc.dg/vect/pr45752.c.  */
++#include <stdarg.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++extern void abort (void);
++extern void exit (int);
++#ifdef __cplusplus
++}
++#endif
++
++#define M00 100
++#define M10 216
++#define M20 23
++#define M30 237
++#define M40 437
++
++#define M01 1322
++#define M11 13
++#define M21 27271
++#define M31 2280
++#define M41 284
++
++#define M02 74
++#define M12 191
++#define M22 500
++#define M32 111
++#define M42 1114
++
++#define M03 134
++#define M13 117
++#define M23 11
++#define M33 771
++#define M43 71
++
++#define M04 334
++#define M14 147
++#define M24 115
++#define M34 7716
++#define M44 16
++
++#define N 20
++
++void foo (unsigned int *__restrict__ pInput,
++          unsigned int *__restrict__ pOutput,
++          unsigned int *__restrict__ pInput2,
++          unsigned int *__restrict__ pOutput2)
++{
++  unsigned int i, a, b, c, d, e;
++
++  for (i = 0; i < N / 5; i++)
++    {
++       a = *pInput++;
++       b = *pInput++;
++       c = *pInput++;
++       d = *pInput++;
++       e = *pInput++;
++
++       *pOutput++ = M00 * a + M01 * b + M02 * c + M03 * d + M04 * e;
++       *pOutput++ = M10 * a + M11 * b + M12 * c + M13 * d + M14 * e;
++       *pOutput++ = M20 * a + M21 * b + M22 * c + M23 * d + M24 * e;
++       *pOutput++ = M30 * a + M31 * b + M32 * c + M33 * d + M34 * e;
++       *pOutput++ = M40 * a + M41 * b + M42 * c + M43 * d + M44 * e;
++
++
++       a = *pInput2++;
++       b = *pInput2++;
++       c = *pInput2++;
++       d = *pInput2++;
++       e = *pInput2++;
++
++       *pOutput2++ = M00 * a + M01 * b + M02 * c + M03 * d + M04 * e;
++       *pOutput2++ = M10 * a + M11 * b + M12 * c + M13 * d + M14 * e;
++       *pOutput2++ = M20 * a + M21 * b + M22 * c + M23 * d + M24 * e;
++       *pOutput2++ = M30 * a + M31 * b + M32 * c + M33 * d + M34 * e;
++       *pOutput2++ = M40 * a + M41 * b + M42 * c + M43 * d + M44 * e;
++
++    }
++}
++
++int main (int argc, const char* argv[])
++{
++  unsigned int input[N], output[N], i, input2[N], output2[N];
++  unsigned int check_results[N]
++    = {3208, 1334, 28764, 35679, 2789, 13028, 4754, 168364, 91254, 12399, 
++    22848, 8174, 307964, 146829, 22009, 32668, 11594, 447564, 202404, 31619 };
++  unsigned int check_results2[N]
++    = {7136, 2702, 84604, 57909, 6633, 16956, 6122, 224204, 113484, 16243, 
++    26776, 9542, 363804, 169059, 25853, 36596, 12962, 503404, 224634, 35463 };
++
++  for (i = 0; i < N; i++)
++    {
++      input[i] = i%256;
++      input2[i] = i + 2;
++      output[i] = 0;
++      output2[i] = 0;
++      __asm__ volatile ("");
++    }
++
++  foo (input, output, input2, output2);
++
++  for (i = 0; i < N; i++)
++    if (output[i] != check_results[i]
++        || output2[i] != check_results2[i])
++      abort ();
++
++  return 0;
++}
 Index: gcc/testsuite/gcc.target/powerpc/float128-complex-2.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/float128-complex-2.c	(.../tags/gcc_6_1_0_release)
@@ -10472,6 +14346,34 @@ Index: gcc/testsuite/gcc.target/powerpc/vadsdu-5.c
 +}
 +
 +/* { dg-final { scan-assembler "vabsdub" } } */
+Index: gcc/testsuite/gcc.target/powerpc/mulkc3-1.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/mulkc3-1.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/mulkc3-1.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,23 @@
++/* { dg-do run { target { powerpc64*-*-* && vsx_hw } } } */
++/* { dg-require-effective-target powerpc_p8vector_ok } */
++/* { dg-options "-mfloat128 -mvsx" } */
++
++void abort ();
++
++typedef __complex float __cfloat128 __attribute__((mode(KC)));
++
++__cfloat128 multiply (__cfloat128 x, __cfloat128 y)
++{
++  return x * y;
++}
++
++__cfloat128 z, a;
++
++int main ()
++{
++  z = multiply (2.0q + 1.0jq, 3.0q + 1.0jq);
++  a = 5.0q + 5.0jq;
++  if (z != a)
++    abort ();
++  return 0;
++}
 Index: gcc/testsuite/gcc.target/powerpc/vadsduw-2.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/powerpc/vadsduw-2.c	(.../tags/gcc_6_1_0_release)
@@ -10520,6 +14422,24 @@ Index: gcc/testsuite/gcc.target/powerpc/darn-1.c
 +}
 +
 +/* { dg-final { scan-assembler	   "darn" } } */
+Index: gcc/testsuite/gcc.target/powerpc/pr71493-1.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/powerpc/pr71493-1.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/powerpc/pr71493-1.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,13 @@
++/* { dg-do compile { target { powerpc*-*-linux* && ilp32 } } } */
++/* { dg-options "-O2 -msvr4-struct-return" } */
++
++struct S1 { float f; };
++
++struct S1 foo1 (void)
++{
++  struct S1 s = { 1.0f };
++  return s;
++}
++
++/* { dg-final { scan-assembler     "lwz" } } */
++/* { dg-final { scan-assembler-not "lfs" } } */
 Index: gcc/testsuite/gcc.target/arm/interrupt-1.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/arm/interrupt-1.c	(.../tags/gcc_6_1_0_release)
@@ -10762,6 +14682,42 @@ Index: gcc/testsuite/gcc.target/avr/torture/pr71103-2.c
 +#endif /* have __flash1 */
 +#endif /* have __memx */
 +
+Index: gcc/testsuite/gcc.target/avr/pr50739.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/avr/pr50739.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/avr/pr50739.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,7 @@
++/* { dg-do compile } */
++/* { dg-options "-fmerge-all-constants" } */
++
++char *ca = "123";
++
++const char a[] __attribute__((__progmem__))= "a";
++const char b[] __attribute__((__progmem__))= "b";
+Index: gcc/testsuite/gcc.target/s390/nolrl-1.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/s390/nolrl-1.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/s390/nolrl-1.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,19 @@
++/* Make sure the compiler does not try to use a relative long
++   instruction to load the string since it might not meet the
++   alignment requirements of the instruction.  */
++
++/* { dg-do compile } */
++/* { dg-options "-march=z10 -O3 -mzarch" } */
++
++extern void foo (char*);
++
++void
++bar ()
++{
++    unsigned char z[32];
++
++    __builtin_memcpy (z, "\001\000\000\000", 4);
++    foo (z);
++}
++
++/* { dg-final { scan-assembler-not "lrl" } } */
 Index: gcc/testsuite/gcc.target/sparc/fpcmpu.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/sparc/fpcmpu.c	(.../tags/gcc_6_1_0_release)
@@ -10986,6 +14942,93 @@ Index: gcc/testsuite/gcc.target/aarch64/pr70809_1.c
 +}
 +
 +/* { dg-final { scan-assembler-not "fmls\tv.*" } } */
+Index: gcc/testsuite/gcc.target/aarch64/simd/vminmaxnm_1.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/aarch64/simd/vminmaxnm_1.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.target/aarch64/simd/vminmaxnm_1.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,82 @@
++/* Test the `v[min|max]nm{q}_f*' AArch64 SIMD intrinsic.  */
++
++/* { dg-do run } */
++/* { dg-options "-O2" } */
++
++#include "arm_neon.h"
++
++extern void abort ();
++
++#define CHECK(T, N, R, E) \
++  {\
++    int i = 0;\
++    for (; i < N; i++)\
++      if (* (T *) &R[i] != * (T *) &E[i])\
++	abort ();\
++  }
++
++int
++main (int argc, char **argv)
++{
++  float32x2_t f32x2_input1 = vdup_n_f32 (-1.0);
++  float32x2_t f32x2_input2 = vdup_n_f32 (0.0);
++  float32x2_t f32x2_exp_minnm  = vdup_n_f32 (-1.0);
++  float32x2_t f32x2_exp_maxnm  = vdup_n_f32 (0.0);
++  float32x2_t f32x2_ret_minnm  = vminnm_f32 (f32x2_input1, f32x2_input2);
++  float32x2_t f32x2_ret_maxnm  = vmaxnm_f32 (f32x2_input1, f32x2_input2);
++
++  CHECK (uint32_t, 2, f32x2_ret_minnm, f32x2_exp_minnm);
++  CHECK (uint32_t, 2, f32x2_ret_maxnm, f32x2_exp_maxnm);
++
++  f32x2_input1 = vdup_n_f32 (__builtin_nanf (""));
++  f32x2_input2 = vdup_n_f32 (1.0);
++  f32x2_exp_minnm  = vdup_n_f32 (1.0);
++  f32x2_exp_maxnm  = vdup_n_f32 (1.0);
++  f32x2_ret_minnm  = vminnm_f32 (f32x2_input1, f32x2_input2);
++  f32x2_ret_maxnm  = vmaxnm_f32 (f32x2_input1, f32x2_input2);
++
++  CHECK (uint32_t, 2, f32x2_ret_minnm, f32x2_exp_minnm);
++  CHECK (uint32_t, 2, f32x2_ret_maxnm, f32x2_exp_maxnm);
++
++  float32x4_t f32x4_input1 = vdupq_n_f32 (-1024.0);
++  float32x4_t f32x4_input2 = vdupq_n_f32 (77.0);
++  float32x4_t f32x4_exp_minnm  = vdupq_n_f32 (-1024.0);
++  float32x4_t f32x4_exp_maxnm  = vdupq_n_f32 (77.0);
++  float32x4_t f32x4_ret_minnm  = vminnmq_f32 (f32x4_input1, f32x4_input2);
++  float32x4_t f32x4_ret_maxnm  = vmaxnmq_f32 (f32x4_input1, f32x4_input2);
++
++  CHECK (uint32_t, 4, f32x4_ret_minnm, f32x4_exp_minnm);
++  CHECK (uint32_t, 4, f32x4_ret_maxnm, f32x4_exp_maxnm);
++
++  f32x4_input1 = vdupq_n_f32 (-__builtin_nanf (""));
++  f32x4_input2 = vdupq_n_f32 (-1.0);
++  f32x4_exp_minnm  = vdupq_n_f32 (-1.0);
++  f32x4_exp_maxnm  = vdupq_n_f32 (-1.0);
++  f32x4_ret_minnm  = vminnmq_f32 (f32x4_input1, f32x4_input2);
++  f32x4_ret_maxnm  = vmaxnmq_f32 (f32x4_input1, f32x4_input2);
++
++  CHECK (uint32_t, 4, f32x4_ret_minnm, f32x4_exp_minnm);
++  CHECK (uint32_t, 4, f32x4_ret_maxnm, f32x4_exp_maxnm);
++
++  float64x2_t f64x2_input1 = vdupq_n_f64 (1.23);
++  float64x2_t f64x2_input2 = vdupq_n_f64 (4.56);
++  float64x2_t f64x2_exp_minnm  = vdupq_n_f64 (1.23);
++  float64x2_t f64x2_exp_maxnm  = vdupq_n_f64 (4.56);
++  float64x2_t f64x2_ret_minnm  = vminnmq_f64 (f64x2_input1, f64x2_input2);
++  float64x2_t f64x2_ret_maxnm  = vmaxnmq_f64 (f64x2_input1, f64x2_input2);
++
++  CHECK (uint64_t, 2, f64x2_ret_minnm, f64x2_exp_minnm);
++  CHECK (uint64_t, 2, f64x2_ret_maxnm, f64x2_exp_maxnm);
++
++  f64x2_input1 = vdupq_n_f64 (-__builtin_nan (""));
++  f64x2_input2 = vdupq_n_f64 (1.0);
++  f64x2_exp_minnm  = vdupq_n_f64 (1.0);
++  f64x2_exp_maxnm  = vdupq_n_f64 (1.0);
++  f64x2_ret_minnm  = vminnmq_f64 (f64x2_input1, f64x2_input2);
++  f64x2_ret_maxnm  = vmaxnmq_f64 (f64x2_input1, f64x2_input2);
++
++  CHECK (uint64_t, 2, f64x2_ret_minnm, f64x2_exp_minnm);
++  CHECK (uint64_t, 2, f64x2_ret_maxnm, f64x2_exp_maxnm);
++
++  return 0;
++}
 Index: gcc/testsuite/gcc.target/aarch64/tail_indirect_call_1.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/aarch64/tail_indirect_call_1.c	(.../tags/gcc_6_1_0_release)
@@ -12245,6 +16288,51 @@ Index: gcc/testsuite/opt55.ads
 +   function F (C : Rec2; B : Boolean) return Date;
 +
 +end Opt55;
+Index: gcc/testsuite/lib/target-supports.exp
+===================================================================
+--- a/src/gcc/testsuite/lib/target-supports.exp	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/lib/target-supports.exp	(.../branches/gcc-6-branch)
+@@ -2300,6 +2300,40 @@
+ 	float dummy = 1.0q;
+     } "$opts"]
+ }
++
++# Return 1 if the target supports __float128,
++# 0 otherwise.
++
++proc check_effective_target___float128 { } {
++    if { [istarget powerpc*-*-*] } {
++	return [check_ppc_float128_sw_available]
++    }
++    if { [istarget ia64-*-*]
++	 || [istarget i?86-*-*]
++	 || [istarget x86_64-*-*] } {
++	return 1
++    }
++    return 0
++}
++
++proc add_options_for___float128 { flags } {
++    if { [istarget powerpc*-*-*] } {
++	return "$flags -mfloat128 -mvsx"
++    }
++    return "$flags"
++}
++
++# Return 1 if the target supports any special run-time requirements
++# for __float128 or _Float128,
++# 0 otherwise.
++
++proc check_effective_target_base_quadfloat_support { } {
++    if { [istarget powerpc*-*-*] } {
++	return [check_vsx_hw_available]
++    }
++    return 1
++}
++
+ # Return 1 if the target supports compiling fixed-point,
+ # 0 otherwise.
+ 
 Index: gcc/testsuite/gfortran.dg/pr70931.f90
 ===================================================================
 --- a/src/gcc/testsuite/gfortran.dg/pr70931.f90	(.../tags/gcc_6_1_0_release)
@@ -12358,6 +16446,21 @@ Index: gcc/testsuite/gfortran.dg/gomp/pr70855.f90
 +!$omp end workshare
 +!$omp end parallel
 +end program pr70855
+Index: gcc/testsuite/gfortran.dg/gomp/pr71758.f90
+===================================================================
+--- a/src/gcc/testsuite/gfortran.dg/gomp/pr71758.f90	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gfortran.dg/gomp/pr71758.f90	(.../branches/gcc-6-branch)
+@@ -0,0 +1,10 @@
++! PR middle-end/71758
++
++subroutine pr71758 (p)
++  integer(8) :: i
++  integer :: p(20)
++  i = 0
++  !$omp target device(i)
++  !$omp end target
++  !$omp target update to(p(1:1)) device(i)
++end subroutine
 Index: gcc/testsuite/gfortran.dg/gomp/order-1.f90
 ===================================================================
 --- a/src/gcc/testsuite/gfortran.dg/gomp/order-1.f90	(.../tags/gcc_6_1_0_release)
@@ -12773,6 +16876,71 @@ Index: gcc/testsuite/gfortran.dg/goacc/asyncwait-4.f95
 +
 +  !$acc wait,async ! { dg-error "Unclassifiable OpenACC directive" }
  end program asyncwait
+Index: gcc/testsuite/gfortran.dg/goacc/pr71704.f90
+===================================================================
+--- a/src/gcc/testsuite/gfortran.dg/goacc/pr71704.f90	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gfortran.dg/goacc/pr71704.f90	(.../branches/gcc-6-branch)
+@@ -0,0 +1,60 @@
++! PR fortran/71704
++! { dg-do compile }
++
++real function f1 ()
++!$acc routine (f1)
++  f1 = 1
++end
++
++real function f2 (a)
++  integer a
++  !$acc enter data copyin(a)
++  f2 = 1
++end
++
++real function f3 (a)
++  integer a
++!$acc enter data copyin(a)
++  f3 = 1
++end
++
++real function f4 ()
++!$acc wait
++  f4 = 1
++end
++
++real function f5 (a)
++  integer a
++!$acc update device(a)
++  f5 = 1
++end
++
++real function f6 ()
++!$acc parallel
++!$acc end parallel
++  f6 = 1
++end
++
++real function f7 ()
++!$acc kernels
++!$acc end kernels
++  f7 = 1
++end
++
++real function f8 ()
++!$acc data
++!$acc end data
++  f8 = 1
++end
++
++real function f9 ()
++!$acc host_data
++!$acc end host_data
++  f8 = 1
++end
++
++real function f10 (a)
++  integer a
++!$acc declare present (a)
++  f8 = 1
++end
 Index: gcc/testsuite/gfortran.dg/goacc/nested-function-1.f90
 ===================================================================
 --- a/src/gcc/testsuite/gfortran.dg/goacc/nested-function-1.f90	(.../tags/gcc_6_1_0_release)
@@ -13447,6 +17615,22 @@ Index: gcc/testsuite/gfortran.dg/dec_union_4.f90
 +if ( r4.l  .ne.               '.D' ) call aborts ("al")
 +
 +end
+Index: gcc/testsuite/gfortran.dg/dependency_46.f90
+===================================================================
+--- a/src/gcc/testsuite/gfortran.dg/dependency_46.f90	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gfortran.dg/dependency_46.f90	(.../branches/gcc-6-branch)
+@@ -0,0 +1,11 @@
++! { dg-do compile }
++! PR 71783 - this used to ICE due to a missing charlen for the temporary.
++! Test case by Toon Moene.
++
++SUBROUTINE prtdata(ilen)
++  INTEGER :: ilen
++  character(len=ilen), allocatable :: cline(:)
++  allocate(cline(2))
++  cline(1) = 'a'
++  cline(2) = cline(1)
++END SUBROUTINE prtdata
 Index: gcc/testsuite/gfortran.dg/dec_structure_2.f90
 ===================================================================
 --- a/src/gcc/testsuite/gfortran.dg/dec_structure_2.f90	(.../tags/gcc_6_1_0_release)
@@ -13852,6 +18036,41 @@ Index: gcc/testsuite/gfortran.dg/dec_structure_1.f90
 +endif
 +
 +end
+Index: gcc/testsuite/gfortran.dg/null_9.f90
+===================================================================
+--- a/src/gcc/testsuite/gfortran.dg/null_9.f90	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gfortran.dg/null_9.f90	(.../branches/gcc-6-branch)
+@@ -0,0 +1,30 @@
++! { dg-do run }
++
++MODULE fold_convert_loc_ice
++  IMPLICIT NONE
++  PRIVATE
++
++  TYPE, PUBLIC :: ta
++    PRIVATE
++    INTEGER :: a_comp
++  END TYPE ta
++
++  TYPE, PUBLIC :: tb
++    TYPE(ta), ALLOCATABLE :: b_comp
++  END TYPE tb
++
++  PUBLIC :: proc
++CONTAINS
++  SUBROUTINE proc
++    TYPE(tb) :: b
++
++    b = tb(null())
++    if (allocated( b%b_comp )) call abort()
++  END SUBROUTINE proc
++END MODULE fold_convert_loc_ice
++
++  USE fold_convert_loc_ice
++
++  call proc()
++END
++
 Index: gcc/testsuite/gfortran.dg/pr71047.f08
 ===================================================================
 --- a/src/gcc/testsuite/gfortran.dg/pr71047.f08	(.../tags/gcc_6_1_0_release)
@@ -14159,6 +18378,52 @@ Index: gcc/testsuite/gfortran.dg/dec_union_2.f90
 +endif
 +
 +end
+Index: gcc/testsuite/gfortran.dg/select_type_35.f03
+===================================================================
+--- a/src/gcc/testsuite/gfortran.dg/select_type_35.f03	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gfortran.dg/select_type_35.f03	(.../branches/gcc-6-branch)
+@@ -0,0 +1,41 @@
++! { dg-do run }
++!
++! Contributed by Nathanael Huebbe
++! Check fix for PR/70842
++
++program foo
++
++  TYPE, ABSTRACT :: t_Intermediate
++  END TYPE t_Intermediate
++
++  type, extends(t_Intermediate) :: t_Foo
++    character(:), allocatable :: string
++  end type t_Foo
++
++  class(t_Foo), allocatable :: obj
++
++  allocate(obj)
++  obj%string = "blabarfoo"
++
++  call bar(obj)
++
++  deallocate(obj)
++contains
++  subroutine bar(me)
++    class(t_Intermediate), target :: me
++
++    class(*), pointer :: alias
++
++    select type(me)
++      type is(t_Foo)
++      if (len(me%string) /= 9) call abort()
++    end select
++
++    alias => me
++    select type(alias)
++      type is(t_Foo)
++        if (len(alias%string) /= 9) call abort()
++    end select
++  end subroutine bar
++end program foo
++
 Index: gcc/testsuite/gfortran.dg/dec_union_6.f90
 ===================================================================
 --- a/src/gcc/testsuite/gfortran.dg/dec_union_6.f90	(.../tags/gcc_6_1_0_release)
@@ -14271,6 +18536,24 @@ Index: gcc/testsuite/gfortran.dg/dec_structure_4.f90
 +endif
 +
 +end
+Index: gcc/testsuite/gfortran.dg/pr71688.f90
+===================================================================
+--- a/src/gcc/testsuite/gfortran.dg/pr71688.f90	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gfortran.dg/pr71688.f90	(.../branches/gcc-6-branch)
+@@ -0,0 +1,13 @@
++! { dg-do compile }
++! { dg-options "-fcoarray=lib" }
++
++program p
++   call s
++contains
++   subroutine s
++      real :: x[*] = 1
++      block
++      end block
++      x = 2
++   end
++end
 Index: gcc/testsuite/gfortran.dg/dec_structure_8.f90
 ===================================================================
 --- a/src/gcc/testsuite/gfortran.dg/dec_structure_8.f90	(.../tags/gcc_6_1_0_release)
@@ -14336,6 +18619,24 @@ Index: gcc/testsuite/gfortran.dg/dec_structure_8.f90
 +end structure
 +
 +end
+Index: gcc/testsuite/gfortran.dg/deferred_character_17.f90
+===================================================================
+--- a/src/gcc/testsuite/gfortran.dg/deferred_character_17.f90	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gfortran.dg/deferred_character_17.f90	(.../branches/gcc-6-branch)
+@@ -0,0 +1,13 @@
++!{ dg-do run }
++
++! Check fix for PR fortran/71623
++
++program allocatemvce
++  implicit none
++  character(len=:), allocatable :: string
++  integer, dimension(4), target :: array = [1,2,3,4]
++  integer, dimension(:), pointer :: array_ptr
++  array_ptr => array
++  ! The allocate used to segfault
++  allocate(character(len=size(array_ptr))::string)
++end program allocatemvce
 Index: gcc/testsuite/gfortran.dg/dec_union_1.f90
 ===================================================================
 --- a/src/gcc/testsuite/gfortran.dg/dec_union_1.f90	(.../tags/gcc_6_1_0_release)
@@ -14617,6 +18918,45 @@ Index: gcc/testsuite/gfortran.dg/dec_structure_11.f90
 +j = .i           ! { dg-error "Invalid character in name" }
 +
 +end
+Index: gcc/testsuite/gfortran.dg/pr71764.f90
+===================================================================
+--- a/src/gcc/testsuite/gfortran.dg/pr71764.f90	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gfortran.dg/pr71764.f90	(.../branches/gcc-6-branch)
+@@ -0,0 +1,34 @@
++! { dg-do run }
++! PR71764 
++program p
++   use iso_c_binding, only: c_ptr, c_null_ptr, c_ptr, c_associated, c_loc
++   logical, target :: rls
++   real, target :: t = 3.14
++   type(c_ptr) :: nullptr,c
++   real, pointer :: k
++   nullptr = c_null_ptr
++   c = nullptr
++   rls = c_associated(c)
++   if (rls) call abort
++   if (c_associated(c)) call abort
++   c = c_loc(rls)
++   if (.not. c_associated(c)) call abort
++   c = nullptr
++   if (c_associated(c)) call abort
++   c = c_loc(t)
++   k => t
++   call association_test(k, c)
++contains
++  subroutine association_test(a,b)
++    use iso_c_binding, only: c_associated, c_loc, c_ptr
++    implicit none
++    real, pointer :: a
++    type(c_ptr) :: b
++    if(c_associated(b, c_loc(a))) then
++       return
++    else
++       call abort
++    end if
++  end subroutine association_test
++end
++
 Index: gcc/testsuite/gfortran.dg/dec_structure_7.f90
 ===================================================================
 --- a/src/gcc/testsuite/gfortran.dg/dec_structure_7.f90	(.../tags/gcc_6_1_0_release)
@@ -14848,6 +19188,47 @@ Index: gcc/testsuite/gcc.c-torture/execute/pr71554.c
 +    __builtin_abort ();
 +  return 0;
 +}
+Index: gcc/testsuite/gcc.c-torture/compile/pr71916.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.c-torture/compile/pr71916.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.c-torture/compile/pr71916.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,36 @@
++/* PR rtl-optimization/71916 */
++
++int a, b, c, d, f, g;
++short h;
++
++short
++foo (short p1)
++{
++  return a >= 2 || p1 > 7 >> a ? p1 : p1 << a;
++}
++
++void
++bar (void)
++{
++  for (;;)
++    {
++      int i, j[3];
++      h = b >= 2 ? d : d >> b;
++      if (foo (f > h ^ c))
++	{
++	  d = 0;
++	  while (f <= 2)
++	    {
++	      char k[2];
++	      for (;;)
++		k[i++] = 7;
++	    }
++	}
++      else
++	for (;;)
++	  g = j[2];
++      if (g)
++	for (;;)
++	  ;
++    }
++}
 Index: gcc/testsuite/gcc.c-torture/compile/pr71693.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.c-torture/compile/pr71693.c	(.../tags/gcc_6_1_0_release)
@@ -15254,6 +19635,22 @@ Index: gcc/testsuite/gcc.dg/goacc/pr71373.c
 +
 +// Adding right brace '}' here, to make this compile.
 +}
+Index: gcc/testsuite/gcc.dg/debug/dwarf2/pr71855.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/debug/dwarf2/pr71855.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/debug/dwarf2/pr71855.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,11 @@
++/* { dg-do compile } */
++/* { dg-options "-O0 -g -dA" } */
++
++// Test that there is only one DW_TAG_unspecified_parameters DIE.
++
++void
++foo (const char *format, ...)
++{
++}
++
++// { dg-final { scan-assembler-times "DIE.*DW_TAG_unspecified_parameters" 1 } }
 Index: gcc/testsuite/gcc.dg/ubsan/bounds-3.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.dg/ubsan/bounds-3.c	(.../tags/gcc_6_1_0_release)
@@ -15281,6 +19678,36 @@ Index: gcc/testsuite/gcc.dg/ubsan/bounds-3.c
 +}
 +
 +/* { dg-output "index 2 out of bounds for type 'S \\\[2\\\]'" } */
+Index: gcc/testsuite/gcc.dg/pr71518.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/pr71518.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/pr71518.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,25 @@
++/* PR tree-optimization/71518 */
++/* { dg-options "-O3" } */
++
++int a, *b[9], c, d, e; 
++
++static int
++fn1 ()
++{
++  for (c = 6; c >= 0; c--)
++    for (d = 0; d < 2; d++)
++      {
++        b[d * 2 + c] = 0;
++        e = a > 1 ? : 0;
++        if (e == 2) 
++          return 0;
++      }
++  return 0;
++}
++
++int
++main ()
++{
++  fn1 ();
++  return 0; 
++}
 Index: gcc/testsuite/gcc.dg/pr71006.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.dg/pr71006.c	(.../tags/gcc_6_1_0_release)
@@ -15363,6 +19790,22 @@ Index: gcc/testsuite/gcc.dg/graphite/pr69068.c
 +    for (en = 0; en < 2; ++en)
 +      zh[en] = ((qo == 0) || (((qo * 2) != 0))) ? 1 : -1;
 +}
+Index: gcc/testsuite/gcc.dg/align-3.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/align-3.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/align-3.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,11 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -fdump-rtl-expand" } */
++
++typedef struct { char a[2]; } __attribute__((__packed__)) TU2;
++unsigned short get16_unaligned(const void *p) {
++    unsigned short v;
++    *(TU2 *)(void *)(&v) = *(const TU2 *)p;
++    return v;
++}
++
++/* { dg-final { scan-rtl-dump "MEM\[^\n\r\]*A8\\\]" "expand" } } */
 Index: gcc/testsuite/gcc.dg/pr71558.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.dg/pr71558.c	(.../tags/gcc_6_1_0_release)
@@ -15457,6 +19900,193 @@ Index: gcc/testsuite/gcc.dg/torture/pr70935.c
 +  rp = 0;
 +  goto ka;
 +}
+Index: gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c	(.../branches/gcc-6-branch)
+@@ -1,7 +1,10 @@
+ /* Test for "invalid" exceptions from __float128 comparisons.  */
+-/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
++/* { dg-do run } */
+ /* { dg-options "" } */
++/* { dg-require-effective-target __float128 } */
++/* { dg-require-effective-target base_quadfloat_support } */
+ /* { dg-require-effective-target fenv_exceptions } */
++/* { dg-add-options __float128 } */
+ 
+ #include <fenv.h>
+ #include <stdlib.h>
+Index: gcc/testsuite/gcc.dg/torture/float128-div-underflow.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/float128-div-underflow.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/float128-div-underflow.c	(.../branches/gcc-6-branch)
+@@ -1,7 +1,10 @@
+ /* Test for spurious underflow from __float128 division.  */
+-/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
++/* { dg-do run } */
+ /* { dg-options "" } */
++/* { dg-require-effective-target __float128 } */
++/* { dg-require-effective-target base_quadfloat_support } */
+ /* { dg-require-effective-target fenv_exceptions } */
++/* { dg-add-options __float128 } */
+ 
+ #include <fenv.h>
+ #include <stdlib.h>
+Index: gcc/testsuite/gcc.dg/torture/float128-extend-nan.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/float128-extend-nan.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/float128-extend-nan.c	(.../branches/gcc-6-branch)
+@@ -1,7 +1,10 @@
+ /* Test extensions to __float128 quiet signaling NaNs.  */
+-/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
++/* { dg-do run } */
+ /* { dg-options "-fsignaling-nans" } */
++/* { dg-require-effective-target __float128 } */
++/* { dg-require-effective-target base_quadfloat_support } */
+ /* { dg-require-effective-target fenv_exceptions } */
++/* { dg-add-options __float128 } */
+ 
+ #include <fenv.h>
+ #include <float.h>
+Index: gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode-2.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode-2.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode-2.c	(.../branches/gcc-6-branch)
+@@ -1,9 +1,12 @@
+ /* Test floating-point conversions.  __float128 type with TImode: bug
+    53317.  */
+ /* Origin: Joseph Myers <joseph at codesourcery.com> */
+-/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
++/* { dg-do run } */
++/* { dg-require-effective-target __float128 } */
++/* { dg-require-effective-target base_quadfloat_support } */
+ /* { dg-require-effective-target int128 } */
+ /* { dg-options "" } */
++/* { dg-add-options __float128 } */
+ 
+ extern void abort (void);
+ extern void exit (int);
+Index: gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c	(.../branches/gcc-6-branch)
+@@ -1,7 +1,10 @@
+ /* Test floating-point conversions.  __float128 type with TImode.  */
+ /* Origin: Joseph Myers <joseph at codesourcery.com> */
+-/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
++/* { dg-do run } */
++/* { dg-require-effective-target __float128 } */
++/* { dg-require-effective-target base_quadfloat_support } */
+ /* { dg-options "" } */
++/* { dg-add-options __float128 } */
+ 
+ #include "fp-int-convert.h"
+ 
+Index: gcc/testsuite/gcc.dg/torture/pr71423.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/pr71423.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/pr71423.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do run } */
++
++struct S1
++{
++  int f1:1;
++};
++
++volatile struct S1 b = { 0 };
++
++int
++main ()
++{
++  char c = b.f1;
++  b.f1 = 1; 
++
++  if (b.f1 > -1 || c)
++    __builtin_abort (); 
++
++  return 0; 
++}
+Index: gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode-3.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode-3.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode-3.c	(.../branches/gcc-6-branch)
+@@ -1,8 +1,11 @@
+ /* Test for correct rounding of conversions from __int128 to
+    __float128.  */
+-/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
++/* { dg-do run } */
++/* { dg-require-effective-target __float128 } */
++/* { dg-require-effective-target base_quadfloat_support } */
+ /* { dg-require-effective-target int128 } */
+ /* { dg-options "-frounding-math" } */
++/* { dg-add-options __float128 } */
+ 
+ #include <fenv.h>
+ #include <stdlib.h>
+Index: gcc/testsuite/gcc.dg/torture/pr71522.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/pr71522.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/pr71522.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,27 @@
++/* { dg-do run } */
++
++#if __SIZEOF_LONG_DOUBLE__ == 16
++#define STR "AAAAAAAAAAAAAAA"
++#elif __SIZEOF_LONG_DOUBLE__ == 12
++#define STR "AAAAAAAAAAA"
++#elif __SIZEOF_LONG_DOUBLE__ == 8
++#define STR "AAAAAAA"
++#elif __SIZEOF_LONG_DOUBLE__ == 4
++#define STR "AAA"
++#else
++#define STR "A"
++#endif
++
++int main()
++{
++  long double d;
++  char s[sizeof d];
++
++  __builtin_memcpy(&d, STR, sizeof d);
++  __builtin_memcpy(&s, &d, sizeof s);
++
++  if (__builtin_strncmp (s, STR, sizeof s) != 0)
++    __builtin_abort ();
++
++  return 0;
++}
+Index: gcc/testsuite/gcc.dg/torture/pr71452.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/pr71452.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/pr71452.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,10 @@
++/* { dg-do run } */
++
++int main()
++{
++  _Bool b;
++  *(char *)&b = 123;
++  if (*(char *)&b != 123)
++    __builtin_abort ();
++  return 0;
++}
+Index: gcc/testsuite/gcc.dg/torture/pr71606.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/pr71606.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/pr71606.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,11 @@
++_Complex a;
++void fn1 ();
++
++int main () {
++  fn1 (a);
++  return 0;
++}
++
++void fn1 (__complex__ long double p1) {
++  __imag__ p1 = 6.0L;
++}
 Index: gcc/testsuite/gcc.dg/torture/pr70941.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.dg/torture/pr70941.c	(.../tags/gcc_6_1_0_release)
@@ -15581,6 +20211,38 @@ Index: gcc/testsuite/gcc.dg/tree-ssa/pr70919.c
 +
 +  return 0;
 +}
+Index: gcc/testsuite/gcc.dg/tree-ssa/vrp101.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/tree-ssa/vrp101.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/tree-ssa/vrp101.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,13 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -fdump-tree-optimized" } */
++
++int x = 1;
++
++int main ()
++{
++  int t = (1/(1>=x))>>1;
++  if (t != 0) __builtin_abort();
++  return 0;
++}
++
++/* { dg-final { scan-tree-dump "<bb 2>:\[\n\r \]*return 0;" "optimized" } } */
+Index: gcc/testsuite/gcc.dg/const-float128.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/const-float128.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/const-float128.c	(.../branches/gcc-6-branch)
+@@ -1,6 +1,8 @@
+ /* Test 'q' and 'Q' suffixes on __float128 type constants.  */
+-/* { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } } */
++/* { dg-do compile } */
++/* { dg-require-effective-target __float128 } */
+ /* { dg-options "" } */
++/* { dg-add-options __float128 } */
+ 
+ __float128 a = 123.456789q;
+ __float128 b = 123.456789Q;
 Index: gcc/testsuite/gcc.dg/ipa/pr70646.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.dg/ipa/pr70646.c	(.../tags/gcc_6_1_0_release)
@@ -15626,6 +20288,19 @@ Index: gcc/testsuite/gcc.dg/ipa/pr70646.c
 +
 + return 0;
 +}
+Index: gcc/testsuite/gcc.dg/const-float128-ped.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/const-float128-ped.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/const-float128-ped.c	(.../branches/gcc-6-branch)
+@@ -1,5 +1,7 @@
+ /* Test 'q' suffix with -pedantic on __float128 type constants.  */
+-/* { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } } */
++/* { dg-do compile } */
++/* { dg-require-effective-target __float128 } */
+ /* { dg-options "-pedantic" } */
++/* { dg-add-options __float128 } */
+ 
+ __float128 a = 123.456789q; /* { dg-warning "non-standard suffix on floating constant" } */
 Index: gcc/testsuite/gcc.dg/vect/tree-vect.h
 ===================================================================
 --- a/src/gcc/testsuite/gcc.dg/vect/tree-vect.h	(.../tags/gcc_6_1_0_release)
@@ -15679,6 +20354,31 @@ Index: gcc/testsuite/gcc.dg/vect/pr66636.c
  {
    int i;
    for (i = 0; i < 256; ++i)
+Index: gcc/testsuite/gcc.dg/vect/pr71264.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/vect/pr71264.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/vect/pr71264.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++/* { dg-do compile } */
++/* { dg-require-effective-target vect_int } */
++
++typedef unsigned char uint8_t;
++typedef uint8_t footype __attribute__((vector_size(4)));
++
++void test(uint8_t *ptr, uint8_t *mask)
++{
++  footype mv;
++  __builtin_memcpy(&mv, mask, sizeof(mv));
++  for (unsigned i = 0; i < 16; i += 4)
++    {
++      footype temp;
++      __builtin_memcpy(&temp, &ptr[i], sizeof(temp));
++      temp ^= mv;
++      __builtin_memcpy(&ptr[i], &temp, sizeof(temp));
++    }
++}
++
++/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
 Index: gcc/testsuite/gcc.dg/vect/pr71259.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.dg/vect/pr71259.c	(.../tags/gcc_6_1_0_release)
@@ -15712,6 +20412,25 @@ Index: gcc/testsuite/gcc.dg/vect/pr71259.c
 +	  __builtin_abort ();
 +  return 0;
 +}
+Index: gcc/testsuite/gcc.dg/vect/pr71823.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/vect/pr71823.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/gcc.dg/vect/pr71823.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* PR tree-optimization/71823 */
++/* { dg-do compile } */
++/* { dg-additional-options "-mfma" { target i?86-*-* x86_64-*-* } } */
++
++float a[4], b[4];
++
++int
++main ()
++{
++  int i;
++  for (i = 0; i < 4; ++i)
++    b[i] = __builtin_fma (1024.0f, 1024.0f, a[i]);
++  return 0;
++}
 Index: gcc/testsuite/gcc.dg/pr71581.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.dg/pr71581.c	(.../tags/gcc_6_1_0_release)
@@ -15757,7 +20476,381 @@ Index: gcc/testsuite/ChangeLog
 ===================================================================
 --- a/src/gcc/testsuite/ChangeLog	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/testsuite/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,912 @@
+@@ -1,3 +1,1286 @@
++2016-07-22  Andre Vehreschild  <vehre at gcc.gnu.org>
++
++	Backported from trunk:
++	PR fortran/71807
++	* gfortran.dg/null_9.f90: New test.
++
++2016-07-22  Andre Vehreschild  <vehre at gcc.gnu.org>
++
++	Backport from trunk:
++	PR fortran/70842
++	* gfortran.dg/select_type_35.f03: New test.
++
++2016-07-21  Jakub Jelinek  <jakub at redhat.com>
++
++	PR c++/71728
++	* g++.dg/other/pr71728.C: New test.
++
++	PR c++/71941
++	* g++.dg/gomp/pr71941.C: New test.
++
++2016-07-21  Patrick Palka  <ppalka at gcc.gnu.org>
++
++	PR c++/70822
++	PR c++/70106
++	* g++.dg/cpp1y/auto-fn32.C: New test.
++	* g++.dg/cpp1y/paren4.C: New test.
++
++2016-07-20  Jakub Jelinek  <jakub at redhat.com>
++
++	PR c++/71909
++	* g++.dg/parse/pr71909.C: New test.
++	* g++.dg/tm/pr71909.C: New test.
++
++2016-07-20  Martin Jambor  <mjambor at suse.cz>
++
++        PR fortran/71688
++        gfortran.dg/pr71688.f90: New test.
++
++2016-07-19  Jakub Jelinek  <jakub at redhat.com>
++
++	PR rtl-optimization/71916
++	* gcc.c-torture/compile/pr71916.c: New test.
++
++	PR middle-end/71874
++	* g++.dg/torture/pr71874.C: New test.
++
++	Backported from mainline
++	2016-07-18  Jakub Jelinek  <jakub at redhat.com>
++
++	PR c++/71835
++	* g++.dg/conversion/ambig3.C: New test.
++
++	PR c++/71828
++	* g++.dg/cpp0x/constexpr-71828.C: New test.
++
++	PR c++/71822
++	* g++.dg/template/defarg21.C: New test.
++
++	PR c++/71871
++	* g++.dg/ext/vector31.C: New test.
++
++	2016-07-07  Jakub Jelinek  <jakub at redhat.com>
++		    Kai Tietz  <ktietz70 at googlemail.com>
++
++	PR c++/70869
++	PR c++/71054
++	* g++.dg/cpp0x/pr70869.C: New test.
++	* g++.dg/cpp0x/pr71054.C: New test.
++
++2016-07-18  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	Back port from mainline
++	2016-07-18  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	PR target/71493
++	* gcc.target/powerpc/pr71493-1.c: New test.
++	* gcc.target/powerpc/pr71493-2.c: Likewise.
++
++2016-07-18  Andreas Krebbel  <krebbel at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-18  Andreas Krebbel  <krebbel at linux.vnet.ibm.com>
++
++	* gcc.target/s390/nolrl-1.c: New test.
++
++2016-07-15  Jerry DeLisle  <jvdelisle at gcc.gnu.org>
++
++	Backport from trunk:
++	PR fortran/71764
++	* gfortran.dg/pr71764.f90: New test.
++
++2016-07-15  Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-15  Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	* g++.dg/pr70098.C: Remove XFAIL for powerpc64_no_dm.
++	* gcc.target/powerpc/pr71763.c: Likewise.
++
++2016-07-15  Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-15  Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	* gcc.target/powerpc/divkc3-1.c: Require p8vector support.
++	* gcc.target/powerpc/mulkc3-1.c: Likewise.
++
++2016-07-14  Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-12  Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	* gcc.target/powerpc/divkc3-1.c: New.
++	* gcc.target/powerpc/mulkc3-1.c: New.
++
++2016-07-14  Alan Modra  <amodra at gmail.com>
++
++	PR target/71733
++	* gcc.target/powerpc/p9-novsx.c: New.
++
++2016-07-13  Andre Vehreschild  <vehre at gcc.gnu.org>
++
++	Backport from trunk:
++	PR fortran/71623
++	* gfortran.dg/deferred_character_17.f90: New test.
++
++2016-07-13  Ilya Enkovich  <ilya.enkovich at intel.com>
++
++	Backport from mainline r238086.
++	2016-07-07  Ilya Enkovich  <ilya.enkovich at intel.com>
++
++	PR ipa/71624
++	* g++.dg/pr71624.C: New test.
++
++2016-07-12  Michael Meissner  <meissner at linux.vnet.ibm.com>
++	    Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-05  Michael Meissner  <meissner at linux.vnet.ibm.com>
++	            Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	* gcc.target/powerpc/signbit-1.c: New test.
++	* gcc.target/powerpc/signbit-2.c: New test.
++	* gcc.target/powerpc/signbit-3.c: New test.
++
++2016-07-12  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-12  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	PR target/71805
++	* gcc.target/powerpc/pr71805.c: New test.
++
++2016-07-12  Segher Boessenkool  <segher at kernel.crashing.org>
++
++	Backport from mainline
++	2016-07-06  Segher Boessenkool  <segher at kernel.crashing.org>
++
++	PR target/70098
++	PR target/71763
++	* gcc.target/powerpc/pr71763.c: New file.
++
++2016-07-11  Jakub Jelinek  <jakub at redhat.com>
++
++	PR middle-end/71758
++	* c-c++-common/gomp/pr71758.c: New test.
++	* gfortran.dg/gomp/pr71758.f90: New test.
++
++	PR tree-optimization/71823
++	* gcc.dg/vect/pr71823.c: New test.
++
++2016-07-11  Yuri Rumyantsev  <ysrumyan at gmail.com>
++
++	Backport from mainline r238055.
++	2016-07-06  Yuri Rumyantsev  <ysrumyan at gmail.com>
++
++	PR tree-optimization/71518
++        * gcc.dg/pr71518.c: New test.
++
++2016-07-09  Thomas Koenig  <tkoenig at gcc.gnu.org>
++
++	Backport from trunk:
++	PR fortran/71783
++	* gfortran.dg/dependency_46.f90:  New test.
++
++2016-07-08  Cesar Philippidis  <cesar at codesourcery.com>
++
++	Backport from trunk:
++	2016-07-08  Cesar Philippidis  <cesar at codesourcery.com>
++
++	* gfortran.dg/goacc/pr71704.f90: New test.
++
++2016-07-08  Martin Liska  <mliska at suse.cz>
++
++	Backported from mainline
++	2016-07-08  Martin Liska  <mliska at suse.cz>
++
++	* gcc.dg/torture/pr71606.c: New test.
++
++2016-07-08  Jiong Wang  <jiong.wang at arm.com>
++
++	Back port from the trunk
++	2016-07-08  Jiong Wang  <jiong.wang at arm.com>
++
++	* gcc.target/aarch64/simd/vminmaxnm_1.c: New.
++
++2016-07-08  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	Back port from trunk
++	2016-07-08  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	PR target/71806
++	* gcc.target/powerpc/p9-lxvx-stxvx-3.c: Add -mfloat128 option.
++
++2016-07-07  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	Back port from the trunk
++	2016-07-01  Michael Meissner  <meissner at linux.vnet.ibm.com>
++
++	PR target/71720
++	* gcc.target/powerpc/pr71720.c: New test.
++
++2016-07-07  Kelvin Nilsen  <kelvin at gcc.gnu.org>
++
++	Backport from mainline r237885
++	2016-06-30  Kelvin Nilsen  <kelvin at gcc.gnu.org>
++
++	* gcc.target/powerpc/dfp/dfp.exp: New dejagnu test script.
++	* gcc.target/powerpc/dfp/dtstsfi-0.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-1.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-10.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-11.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-12.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-13.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-14.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-15.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-16.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-17.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-18.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-19.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-2.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-20.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-21.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-22.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-23.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-24.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-25.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-26.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-27.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-28.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-29.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-3.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-30.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-31.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-32.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-33.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-34.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-35.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-36.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-37.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-38.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-39.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-4.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-40.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-41.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-42.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-43.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-44.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-45.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-46.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-47.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-48.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-49.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-5.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-50.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-51.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-52.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-53.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-54.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-55.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-56.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-57.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-58.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-59.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-6.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-60.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-61.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-62.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-63.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-64.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-65.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-66.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-67.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-68.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-69.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-7.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-70.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-71.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-72.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-73.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-74.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-75.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-76.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-77.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-78.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-79.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-8.c: New test.
++	* gcc.target/powerpc/dfp/dtstsfi-9.c: New test.
++
++2016-07-07  Richard Biener  <rguenther at suse.de>
++
++	Backport from mainline
++	2016-06-13  Richard Biener  <rguenther at suse.de>
++
++	PR middle-end/64516
++	* gcc.dg/align-3.c: New testcase.
++
++2016-07-07  Richard Biener  <rguenther at suse.de>
++
++	Backport from mainline
++	2016-05-25  Richard Biener  <rguenther at suse.de>
++
++	PR tree-optimization/71264
++	* gcc.dg/vect/pr71264.c: New testcase.
++
++	2016-06-07  Richard Biener  <rguenther at suse.de>
++
++	PR middle-end/71423
++	* gcc.dg/torture/pr71423.c: New testcase.
++
++	2016-06-14  Richard Biener  <rguenther at suse.de>
++
++	PR tree-optimization/71521
++	* gcc.dg/tree-ssa/vrp101.c: New testcase.
++
++	2016-06-08  Richard Biener  <rguenther at suse.de>
++
++	PR tree-optimization/71452
++	* gcc.dg/torture/pr71452.c: New testcase.
++
++	2016-06-14  Richard Biener  <rguenther at suse.de>
++
++	PR tree-optimization/71522
++	* gcc.dg/torture/pr71522.c: New testcase.
++
++2016-07-06  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj at atmel.com>
++
++	Backport from mainline
++	2016-07-06  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj at atmel.com>
++
++	PR target/50739	
++	* gcc.target/avr/pr50739.c: New test.
++
++2016-07-05  Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	Backport from mainline
++	2016-07-01  Bill Schmidt  <wschmidt at linux.vnet.ibm.com>
++
++	* gcc.dg/const-float128-ped.c: Require __float128 effective
++	target and options.
++	* gcc.dg/const-float128.c: Likewise.
++	* gcc.dg/torture/float128-cmp-invalid.c: Require
++	__float128 and base_quadfloat_support effective targets, and
++	__float128 options.
++	* gcc.dg/torture/float128-div-underflow.c: Likewise.
++	* gcc.dg/torture/float128-extend-nan.c: Likewise.
++	* gcc.dg/torture/fp-int-convert-float128-timode-2.c: Likewise.
++	* gcc.dg/torture/fp-int-convert-float128-timode-3.c: Likewise.
++	* gcc.dg/torture/fp-int-convert-float128-timode.c: Likewise.
++	* lib/target-supports.exp (check_effective_target___float128):
++	New.
++	(add_options_for___float128): New.
++	(check_effective_target_base_quadword_support): New.
++
 +2016-07-04  Jakub Jelinek  <jakub at redhat.com>
 +
 +	PR c++/71739
@@ -16953,6 +22046,82 @@ Index: gcc/testsuite/g++.dg/ubsan/null-7.C
 +              << A() << A() << A() << A() << A() << A() << A() << A() << A()
 +              << A() << A() << A() << A() << A() << A() << A() << A() << A();
 +}
+Index: gcc/testsuite/g++.dg/parse/pr71909.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/parse/pr71909.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/parse/pr71909.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,22 @@
++// PR c++/71909
++// { dg-do compile }
++
++struct S
++{
++  S () try : m (0) {}
++  catch (...) {}
++  void foo () try {}
++  catch (int) {}
++  catch (...) {}
++  int m;
++};
++
++struct T
++{
++  T () : m (0) {}
++  catch (...) {}	// { dg-error "expected unqualified-id before" }
++  void foo () {}
++  catch (int) {}	// { dg-error "expected unqualified-id before" }
++  catch (...) {}	// { dg-error "expected unqualified-id before" }
++  int m;
++};
+Index: gcc/testsuite/g++.dg/tm/pr71909.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/tm/pr71909.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/tm/pr71909.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,18 @@
++// PR c++/71909
++// { dg-do compile { target c++11 } }
++// { dg-options "-fgnu-tm" }
++
++struct S
++{
++  S () __transaction_atomic [[outer]] try : m {0} {} catch (int) {} catch (...) {}
++  int m;
++};
++
++struct T
++{
++  T () __transaction_atomic __attribute__((outer)) try : m {0} {} catch (int) {} catch (...) {}
++  int m;
++};
++
++void foo () __transaction_atomic [[outer]] try {} catch (int) {} catch (...) {}
++void bar () __transaction_atomic __attribute__((outer)) try {} catch (int) {} catch (...) {}
+Index: gcc/testsuite/g++.dg/cpp0x/initlist-base2.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/initlist-base2.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/initlist-base2.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,21 @@
++// PR c++/55922
++// { dg-do run { target c++11 } }
++
++bool called = false;
++
++struct Base {
++  Base() { if (called) throw 1; called = true; }
++};
++
++struct B1 : virtual Base {
++  B1() { }
++};
++
++struct C : B1, virtual Base {
++  C() : B1{}
++  { }
++};
++
++int main() {
++  C c;
++}
 Index: gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C	(.../tags/gcc_6_1_0_release)
@@ -16968,6 +22137,39 @@ Index: gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C
 +  static_cast<void(*)()>([=]{});  // { dg-error "invalid static_cast" }
 +  static_cast<void(*)()>([&]{});  // { dg-error "invalid static_cast" }
 +}
+Index: gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice16.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice16.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice16.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,8 @@
++// PR c++/70781
++// { dg-do compile { target c++11 } }
++
++template < typename T >
++void foo ()
++{
++  T ([=] (S) { [=] {}; }); 	// { dg-error "" }
++}
+Index: gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce3.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce3.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce3.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++// PR c++/69223
++// { dg-do compile { target c++11 } }
++
++template <class T> struct A
++{
++  T x[20];
++};
++
++int main()
++{
++  auto l = [](const A<int>& i){ return i; };
++  A<int> a;
++
++  l(a);
++}
 Index: gcc/testsuite/g++.dg/cpp0x/inh-ctor20.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/cpp0x/inh-ctor20.C	(.../tags/gcc_6_1_0_release)
@@ -17017,6 +22219,94 @@ Index: gcc/testsuite/g++.dg/cpp0x/constexpr-array16.C
 +void Foo() {
 +	new BarContainer();
 +}
+Index: gcc/testsuite/g++.dg/cpp0x/range-for8.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/range-for8.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/range-for8.C	(.../branches/gcc-6-branch)
+@@ -7,9 +7,9 @@
+ 
+ void test()
+ {
+-    for (struct S { } *x : { (S*)0, (S*)0 } )
++    for (struct S { } *x : { (S*)0, (S*)0 } ) // { dg-error "types may not be defined" }
+         ;
+ 
+-    for (struct S { } x : { S(), S() } )
++    for (struct S { } x : { S(), S() } ) // { dg-error "types may not be defined" }
+         ;
+ }
+Index: gcc/testsuite/g++.dg/cpp0x/variadic-mangle2a.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/variadic-mangle2a.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/variadic-mangle2a.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,19 @@
++// Testcase from cxx-abi-dev.
++// { dg-do compile { target c++11 } }
++// { dg-options "-fabi-version=9" }
++
++struct A {
++  template<int...T> using N = int[sizeof...(T)];
++  template<int...A> void f(N<A...> &);
++
++  template<typename...T> using M = int[sizeof...(T)];
++  template<typename...A> void g(M<A...> &);
++};
++void g(A a)
++{
++  int arr[3];
++  // { dg-final { scan-assembler "_ZN1A1fIJLi1ELi2ELi3EEEEvRAszspT__i" } }
++  a.f<1,2,3>(arr);
++  // { dg-final { scan-assembler "_ZN1A1gIJiiiEEEvRAstDpT__i" } }
++  a.g<int,int,int>(arr);
++}
+Index: gcc/testsuite/g++.dg/cpp0x/pr70869.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/pr70869.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/pr70869.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,25 @@
++// PR c++/70869
++// { dg-do run { target c++11 } }
++
++#include <initializer_list>
++
++struct A
++{
++  int f () { return 1; }
++  int g () { return 2; }
++  int h () { return 3; }
++};
++
++int
++main ()
++{
++  int cnt = 0;
++  for (const auto &m : { &A::f, &A::g, &A::h })
++    {
++      A a;
++      if ((a.*m) () != ++cnt)
++	__builtin_abort ();
++    }
++  if (cnt != 3)
++    __builtin_abort ();
++}
+Index: gcc/testsuite/g++.dg/cpp0x/alignas7.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/alignas7.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/alignas7.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,13 @@
++// PR c++/71513
++// { dg-do compile { target c++11 } }
++
++template < int N, typename T >
++struct A
++{
++  enum alignas (N) E : T;
++};
++
++#define SA(X) static_assert((X), #X)
++
++constexpr int al = alignof(double);
++SA(alignof(A<al,char>::E) == al);
 Index: gcc/testsuite/g++.dg/cpp0x/Wunused-variable-1.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/cpp0x/Wunused-variable-1.C	(.../tags/gcc_6_1_0_release)
@@ -17059,6 +22349,91 @@ Index: gcc/testsuite/g++.dg/cpp0x/Wunused-variable-1.C
 +{
 +  bar <0> ();
 +}
+Index: gcc/testsuite/g++.dg/cpp0x/decltype65.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/decltype65.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/decltype65.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,11 @@
++// PR c++/71511
++// { dg-do compile { target c++11 } }
++
++template < typename T >
++class A
++{
++  static int i;
++};
++
++//okay: template < typename T > int A <T>::i = 100;
++template < typename T > int decltype (A < T > ())::i = 100; // { dg-error "decltype" }
+Index: gcc/testsuite/g++.dg/cpp0x/sfinae57.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/sfinae57.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/sfinae57.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,16 @@
++// PR c++/71495
++// { dg-do compile { target c++11 } }
++
++struct A;
++template <class T> void f(T);	// { dg-bogus "initializing" }
++template <class T> T&& declval();
++struct B
++{
++  template <class T, class U> static decltype(f<T>(declval<U>())) g(int);
++  template <class T, class U> void g(...);
++} b;
++
++int main()
++{
++  b.g<A,A>(42);
++}
+Index: gcc/testsuite/g++.dg/cpp0x/initlist-base3.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/initlist-base3.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/initlist-base3.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,17 @@
++// PR c++/71774
++// { dg-do compile { target c++11 } }
++
++class Meow
++{
++  protected:
++    Meow() =default;        
++    virtual void f() {}
++};
++
++class Purr : public Meow
++{
++  public:
++    Purr()
++      : Meow{}
++    {}  
++};
+Index: gcc/testsuite/g++.dg/cpp0x/pr71054.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/pr71054.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/pr71054.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,21 @@
++// PR c++/71054
++// { dg-do compile { target c++11 } }
++
++#include <initializer_list>
++
++template <typename D, typename T = decltype (&D::U)>
++struct S
++{
++  struct A
++  {
++    int a;
++    int b;
++    T p;
++  };
++  S () { std::initializer_list<A> a{ {0, 0, &D::V} }; }
++};
++struct R {
++  void V (int);
++  void U (int);
++};
++S<R> b;
 Index: gcc/testsuite/g++.dg/cpp0x/inh-ctor21.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/cpp0x/inh-ctor21.C	(.../tags/gcc_6_1_0_release)
@@ -17093,6 +22468,152 @@ Index: gcc/testsuite/g++.dg/cpp0x/pr71739.C
 +
 +template <int N> struct alignas(N) A;
 +template <int N> struct alignas(N) A {};
+Index: gcc/testsuite/g++.dg/cpp0x/constexpr-array17.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/constexpr-array17.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/constexpr-array17.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,61 @@
++// PR c++/71092
++// { dg-do compile { target c++11 } }
++
++template <typename _Default> struct A { using type = _Default; };
++template <typename _Default, template <typename> class>
++using __detected_or = A<_Default>;
++template <typename _Default, template <typename> class _Op>
++using __detected_or_t = typename __detected_or<_Default, _Op>::type;
++template <typename _Tp> struct B { typedef _Tp value_type; };
++struct C {
++  template <typename _Tp> using __pointer = typename _Tp::pointer;
++};
++template <typename _Alloc> struct J : C {
++  using pointer = __detected_or_t<typename _Alloc::value_type *, __pointer>;
++};
++template <typename _T1> void _Construct(_T1 *) { new _T1; }
++struct D {
++  template <typename _ForwardIterator, typename _Size>
++  static _ForwardIterator __uninit_default_n(_ForwardIterator p1, _Size) {
++    _Construct(p1);
++  }
++};
++template <typename _ForwardIterator, typename _Size>
++void __uninitialized_default_n(_ForwardIterator p1, _Size) {
++  D::__uninit_default_n(p1, 0);
++}
++template <typename _ForwardIterator, typename _Size, typename _Tp>
++void __uninitialized_default_n_a(_ForwardIterator p1, _Size, _Tp) {
++  __uninitialized_default_n(p1, 0);
++}
++template <typename> struct __shared_ptr {
++  constexpr __shared_ptr() : _M_ptr(), _M_refcount() {}
++  int _M_ptr;
++  int _M_refcount;
++};
++template <typename _Alloc> struct F {
++  typedef _Alloc _Tp_alloc_type;
++  struct G {
++    typename J<_Tp_alloc_type>::pointer _M_start;
++    G(_Tp_alloc_type);
++  };
++  F(int, _Alloc p2) : _M_impl(p2) {}
++  G _M_impl;
++};
++template <typename _Tp, typename _Alloc = B<_Tp>> struct K : F<_Alloc> {
++  typedef _Alloc allocator_type;
++  K(int, allocator_type p2 = allocator_type()) : F<_Alloc>(0, p2) {
++    __uninitialized_default_n_a(this->_M_impl._M_start, 0, 0);
++  }
++};
++struct H {
++  H();
++  struct I {
++    __shared_ptr<int> trigger[1];
++  };
++  __shared_ptr<int> resetTrigger_;
++  K<I> states_;
++  __shared_ptr<int> triggerManager_;
++};
++__shared_ptr<int> a;
++H::H() : states_(0), triggerManager_(a) {}
+Index: gcc/testsuite/g++.dg/cpp0x/variadic-mangle1a.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/variadic-mangle1a.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/variadic-mangle1a.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,12 @@
++// Test for sZ mangling.
++// { dg-do compile { target c++11 } }
++// { dg-final { scan-assembler "_Z1fIJidEEv1AIXstDpT_EE" } }
++// { dg-options -fabi-version=9 }
++
++template <int I> struct A { };
++template <typename... Ts> void f(A<sizeof...(Ts)>);
++
++int main()
++{
++  f<int,double>(A<2>());
++}
+Index: gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem6.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem6.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem6.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,13 @@
++// PR c++/71896
++// { dg-do compile { target c++11 } }
++
++struct Foo {
++  int x;
++};
++
++constexpr bool compare(int Foo::*t) { return t == &Foo::x; }
++
++constexpr bool b = compare(&Foo::x);
++
++#define SA(X) static_assert ((X),#X)
++SA(b);
+Index: gcc/testsuite/g++.dg/cpp0x/initlist-template1.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/initlist-template1.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/initlist-template1.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,15 @@
++// PR c++/70824
++// { dg-do compile { target c++11 } }
++
++#include <initializer_list>
++
++constexpr
++int
++max(std::initializer_list<int> __l)
++{ return *__l.begin(); }
++
++template <class Src>
++void
++a() {
++  const int v =  max({1});
++}
+Index: gcc/testsuite/g++.dg/cpp0x/variadic-mangle3a.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/variadic-mangle3a.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/variadic-mangle3a.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,11 @@
++// Testcase from cxx-abi-dev.
++// { dg-do compile { target c++11 } }
++// { dg-options -fabi-version=9 }
++// { dg-final { scan-assembler "_ZN1A1fIJiiEiJiiiEEEvRAstDpT1__iT0_S2_" } }
++
++struct A {
++  template<typename...T> using N = int[sizeof...(T)];
++  template<typename...A, typename B, typename...C>
++      void f(N<A..., B, C...> &, B, C...);
++};
++void g(A a) { int arr[6]; a.f<int, int>(arr, 1, 2, 3, 4); }
+Index: gcc/testsuite/g++.dg/cpp0x/conv-tmpl1.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/conv-tmpl1.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/conv-tmpl1.C	(.../branches/gcc-6-branch)
+@@ -1,3 +1,4 @@
++// Test for Core 2189.
+ // { dg-do compile { target c++11 } }
+ 
+ template <class T>
 Index: gcc/testsuite/g++.dg/cpp0x/constexpr-recursion2.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion2.C	(.../tags/gcc_6_1_0_release)
@@ -17104,6 +22625,21 @@ Index: gcc/testsuite/g++.dg/cpp0x/constexpr-recursion2.C
  
  struct Z
  {
+Index: gcc/testsuite/g++.dg/cpp0x/variadic-mangle3.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/variadic-mangle3.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/variadic-mangle3.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,10 @@
++// Testcase from cxx-abi-dev.
++// { dg-do compile { target c++11 } }
++// { dg-final { scan-assembler "_ZN1A1fIJiiEiJiiiEEEvRAsPDpT_T0_DpT1_E_iS3_S5_" } }
++
++struct A {
++  template<typename...T> using N = int[sizeof...(T)];
++  template<typename...A, typename B, typename...C>
++      void f(N<A..., B, C...> &, B, C...);
++};
++void g(A a) { int arr[6]; a.f<int, int>(arr, 1, 2, 3, 4); }
 Index: gcc/testsuite/g++.dg/cpp0x/auto48.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/cpp0x/auto48.C	(.../tags/gcc_6_1_0_release)
@@ -17117,6 +22653,97 @@ Index: gcc/testsuite/g++.dg/cpp0x/auto48.C
 +{
 +  auto f = [&] { return f; };  // { dg-error "before deduction" }
 +}
+Index: gcc/testsuite/g++.dg/cpp0x/range-for31.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/range-for31.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/range-for31.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,9 @@
++// PR c++/71604
++// { dg-do compile { target c++11 } }
++
++void foo ()
++{
++  int a[2] = { 1, 2 };
++  for (struct S { S (int) {} } S : a) // { dg-error "types may not be defined" }
++    ;
++}
+Index: gcc/testsuite/g++.dg/cpp0x/alias-decl-55.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/alias-decl-55.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/alias-decl-55.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,23 @@
++// PR c++/71718
++// { dg-do compile { target c++11 } }
++
++template <typename T>
++class A : T{};
++
++template <typename T>
++using sp = A<T>;
++
++struct Base {};
++
++template <typename T, int num = 1>
++const sp<T>
++rec() 			// { dg-error "depth" }
++{
++  return rec<T, num - 1>();
++}
++
++static void f(void) {
++  rec<Base>();
++}
++
++// { dg-prune-output "compilation terminated" }
+Index: gcc/testsuite/g++.dg/cpp0x/decltype66.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/decltype66.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/decltype66.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,19 @@
++// PR c++/71350
++// { dg-do compile { target c++11 } }
++
++template<typename T, unsigned int N>
++struct Array
++{
++    T data[N];
++};
++
++template<typename T>
++struct Foo
++{
++    int operator[](const Array<int, 2>& i) const { return 0; }
++    auto bar() -> decltype((*this)[{1,2}] * 0) {
++      return *this;		// { dg-error "cannot convert" }
++    }
++};
++
++template struct Foo<int>;
+Index: gcc/testsuite/g++.dg/cpp0x/constexpr-71828.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp0x/constexpr-71828.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp0x/constexpr-71828.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,5 @@
++// PR c++/71828
++// { dg-do compile { target c++11 } }
++
++constexpr _Complex int a { 1, 2 };
++static_assert (& __imag a != &__real a, "");
+Index: gcc/testsuite/g++.dg/torture/pr71452.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/torture/pr71452.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/torture/pr71452.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,10 @@
++// { dg-do run }
++
++int main()
++{
++  bool b;
++  *(char *)&b = 123;
++  if (*(char *)&b != 123)
++    __builtin_abort ();
++  return 0;
++}
 Index: gcc/testsuite/g++.dg/torture/pr71002.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/torture/pr71002.C	(.../tags/gcc_6_1_0_release)
@@ -17341,6 +22968,63 @@ Index: gcc/testsuite/g++.dg/torture/pr71448.C
 +static_assert (3 + bar > bar, "check");
 +static_assert (bar < 2 + bar, "check");
 +static_assert (bar < bar + 3, "check");
+Index: gcc/testsuite/g++.dg/torture/pr71874.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/torture/pr71874.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/torture/pr71874.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,12 @@
++// PR middle-end/71874
++// { dg-do run }
++
++int
++main ()
++{
++  char str[] = "abcdefghijklmnopqrstuvwxyzABCDEF";
++  __builtin_memmove (str + 20, str + 15, 11);
++  if (__builtin_strcmp (str, "abcdefghijklmnopqrstpqrstuvwxyzF") != 0)
++    __builtin_abort ();
++  return 0;
++}
+Index: gcc/testsuite/g++.dg/pr71624.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/pr71624.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/pr71624.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,35 @@
++/* PR71624 */
++// { dg-do compile { target i?86-*-* x86_64-*-* } }
++/* { dg-options "-fcheck-pointer-bounds -mmpx -O2" } */
++
++class c1
++{
++public:
++  virtual int fn1 () const;
++  int fn2 (const int *) const;
++};
++
++class c2
++{
++  int fn1 ();
++  c1 obj;
++};
++
++int
++c1::fn1 () const
++{
++  return 0;
++}
++
++int
++c1::fn2 (const int *) const
++{
++  return this->fn1 ();
++}
++
++int
++c2::fn1 ()
++{
++  return obj.fn2 (0);
++}
++
 Index: gcc/testsuite/g++.dg/ipa/ipa-pta-2.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/ipa/ipa-pta-2.C	(.../tags/gcc_6_1_0_release)
@@ -17383,6 +23067,19 @@ Index: gcc/testsuite/g++.dg/ipa/ipa-pta-2.C
 +    abort ();
 +  return 0;
 +}
+Index: gcc/testsuite/g++.dg/pr70098.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/pr70098.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/pr70098.C	(.../branches/gcc-6-branch)
+@@ -2,8 +2,6 @@
+ // { dg-do compile }
+ // { dg-options -O2 }
+ // { dg-require-effective-target c++11 }
+-// { dg-xfail-if "PR70098" { lp64 && powerpc64_no_dm } }
+-// { dg-prune-output ".*internal compiler error.*" }
+ 
+ template < typename > struct traits;
+ template < typename, int _Rows, int _Cols, int = 0, int = _Rows,
 Index: gcc/testsuite/g++.dg/pr71389.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/pr71389.C	(.../tags/gcc_6_1_0_release)
@@ -17429,6 +23126,21 @@ Index: gcc/testsuite/g++.dg/cpp1y/lambda-conv1.C
 +  static_cast<float(*)(float)>([=](auto x){ return x; });  // { dg-error "invalid static_cast" }
 +  static_cast<float(*)(float)>([&](auto x){ return x; });  // { dg-error "invalid static_cast" }
 +}
+Index: gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C	(.../branches/gcc-6-branch)
+@@ -42,8 +42,8 @@
+ #  error "__cpp_attributes" // { dg-error "error" }
+ #endif
+ 
+-#ifndef __cpp_rvalue_reference
+-#  error "__cpp_rvalue_reference" // { dg-error "error" }
++#ifndef __cpp_rvalue_references
++#  error "__cpp_rvalue_references" // { dg-error "error" }
+ #endif
+ 
+ #ifndef __cpp_variadic_templates
 Index: gcc/testsuite/g++.dg/cpp1y/var-templ52.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/cpp1y/var-templ52.C	(.../tags/gcc_6_1_0_release)
@@ -17508,6 +23220,86 @@ Index: gcc/testsuite/g++.dg/cpp1y/var-templ39a.C
 +  // { dg-final { scan-assembler "_Z3fooIA2_A5_A3_dE" } }
 +  assert(!foo<double[2][5][3]>);
 +}
+Index: gcc/testsuite/g++.dg/cpp1y/var-templ53.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp1y/var-templ53.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp1y/var-templ53.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,10 @@
++// PR c++/71630
++// { dg-do compile { target c++14 } }
++
++template <class T>
++extern T pi;
++
++int main()
++{
++  return pi<int>;
++}
+Index: gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv2.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv2.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv2.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,26 @@
++// PR c++/71117
++// { dg-do compile { target c++14 } }
++
++template <class T> T&& declval() noexcept;
++template <class, class>
++constexpr bool is_same = false;
++template <class T>
++constexpr bool is_same<T, T> = true;
++
++template <class F>
++struct indirected : F {
++    indirected(F f) : F(f) {}
++    template <class I>
++    auto operator()(I i) -> decltype(declval<F&>()(*i)) {
++        return static_cast<F&>(*this)(*i);
++    }
++};
++
++int main() {
++    auto f = [](auto rng) {
++        static_assert(is_same<decltype(rng), int>, "");
++        return 42;
++    };
++    indirected<decltype(f)> i(f);
++    static_assert(is_same<decltype(i(declval<int*>())), int>, "");
++}
+Index: gcc/testsuite/g++.dg/cpp1y/feat-cxx11.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp1y/feat-cxx11.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp1y/feat-cxx11.C	(.../branches/gcc-6-branch)
+@@ -77,10 +77,10 @@
+ #  error "__cpp_attributes != 200809"
+ #endif
+ 
+-#ifndef __cpp_rvalue_reference
+-#  error "__cpp_rvalue_reference"
+-#elif __cpp_rvalue_reference != 200610
+-#  error "__cpp_rvalue_reference != 200610"
++#ifndef __cpp_rvalue_references
++#  error "__cpp_rvalue_references"
++#elif __cpp_rvalue_references != 200610
++#  error "__cpp_rvalue_references != 200610"
+ #endif
+ 
+ #ifndef __cpp_variadic_templates
+Index: gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv3.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv3.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv3.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,10 @@
++// PR c++/70942
++// { dg-do compile { target c++14 } }
++
++int main()
++{
++    int x = 0;
++    [](auto&& xv){
++        static_cast<decltype(xv)>(xv) = 1;
++    }(x);
++}
 Index: gcc/testsuite/g++.dg/cpp1y/auto-fn31.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/cpp1y/auto-fn31.C	(.../tags/gcc_6_1_0_release)
@@ -17531,6 +23323,82 @@ Index: gcc/testsuite/g++.dg/cpp1y/var-templ39.C
  
  template <class>
  constexpr bool foo = false;
+Index: gcc/testsuite/g++.dg/cpp1y/paren4.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp1y/paren4.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp1y/paren4.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++// PR c++/70822
++// { dg-do compile { target c++14 } }
++
++struct a
++{
++  static int b;
++};
++
++template <typename>
++void
++foo ()
++{
++  &(a::b);
++}
+Index: gcc/testsuite/g++.dg/cpp1y/feat-cxx14.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp1y/feat-cxx14.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp1y/feat-cxx14.C	(.../branches/gcc-6-branch)
+@@ -70,10 +70,10 @@
+ #  error "__cpp_attributes != 200809"
+ #endif
+ 
+-#ifndef __cpp_rvalue_reference
+-#  error "__cpp_rvalue_reference"
+-#elif __cpp_rvalue_reference != 200610
+-#  error "__cpp_rvalue_reference != 200610"
++#ifndef __cpp_rvalue_references
++#  error "__cpp_rvalue_references"
++#elif __cpp_rvalue_references != 200610
++#  error "__cpp_rvalue_references != 200610"
+ #endif
+ 
+ #ifndef __cpp_variadic_templates
+Index: gcc/testsuite/g++.dg/cpp1y/auto-fn32.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp1y/auto-fn32.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp1y/auto-fn32.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,33 @@
++// { dg-do compile { target c++14 } }
++
++template<class,class> struct same_type;
++template<class T> struct same_type<T,T> {};
++
++struct A
++{
++  static int b;
++  int c;
++
++  template <int>
++  decltype(auto) f() { return A::c; }
++
++  template <int>
++  decltype(auto) g() { return (A::c); }
++};
++
++A a;
++
++template <int>
++decltype(auto) f() { return A::b; }
++
++template <int>
++decltype(auto) g() { return (A::b); }
++
++int main()
++{
++  same_type<decltype(f<0>()), int>();
++  same_type<decltype(g<0>()), int&>();
++
++  same_type<decltype(a.f<0>()), int>();
++  same_type<decltype(a.g<0>()), int&>();
++}
 Index: gcc/testsuite/g++.dg/cpp1y/lambda-generic-static1.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/cpp1y/lambda-generic-static1.C	(.../tags/gcc_6_1_0_release)
@@ -17589,6 +23457,74 @@ Index: gcc/testsuite/g++.dg/cpp1y/var-templ51.C
 +    b<int*>;
 +    b<double*>;
 +}
+Index: gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C	(.../branches/gcc-6-branch)
+@@ -58,10 +58,10 @@
+ #  error "__cpp_attributes != 200809"
+ #endif
+ 
+-#ifndef __cpp_rvalue_reference
+-#  error "__cpp_rvalue_reference"
+-#elif __cpp_rvalue_reference != 200610
+-#  error "__cpp_rvalue_reference != 200610"
++#ifndef __cpp_rvalue_references
++#  error "__cpp_rvalue_references"
++#elif __cpp_rvalue_references != 200610
++#  error "__cpp_rvalue_references != 200610"
+ #endif
+ 
+ #ifndef __cpp_variadic_templates
+Index: gcc/testsuite/g++.dg/cpp1z/fold-mangle.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/cpp1z/fold-mangle.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/cpp1z/fold-mangle.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,20 @@
++// PR c++/71711
++// { dg-options -std=c++1z }
++
++template < int > struct A {};
++template < int ... N > void unary_left (A < (... + N) >);
++template < int ... N > void unary_right (A < (N + ...) >);
++template < int ... N > void binary_left (A < (42 + ... + N) >);
++template < int ... N > void binary_right (A < (N + ... + 42) >);
++
++void bar ()
++{
++  // { dg-final { scan-assembler "_Z10unary_leftIJLi1ELi2ELi3EEEv1AIXflplT_EE" } }
++  unary_left < 1, 2, 3 > ({});
++  // { dg-final { scan-assembler "_Z11unary_rightIJLi1ELi2ELi3EEEv1AIXfrplT_EE" } }
++  unary_right < 1, 2, 3 > ({});
++  // { dg-final { scan-assembler "_Z11binary_leftIJLi1ELi2ELi3EEEv1AIXfLplLi42ET_EE" } }
++  binary_left < 1, 2, 3 > ({});
++  // { dg-final { scan-assembler "_Z12binary_rightIJLi1ELi2ELi3EEEv1AIXfRplT_Li42EEE" } }
++  binary_right < 1, 2, 3 > ({});
++}
+Index: gcc/testsuite/g++.dg/ext/array3.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/ext/array3.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/ext/array3.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,19 @@
++// PR c++/70709
++// { dg-options "" }
++
++struct A
++{
++  A (int);
++};
++
++struct B
++{
++  B () {} 
++  A a[0];
++};
++
++struct C
++{
++  C () {} 
++  B a[0];
++};
 Index: gcc/testsuite/g++.dg/ext/flexary16.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/ext/flexary16.C	(.../tags/gcc_6_1_0_release)
@@ -17631,6 +23567,40 @@ Index: gcc/testsuite/g++.dg/ext/flexary16.C
 +{
 +  return s->array [0].u;
 +}
+Index: gcc/testsuite/g++.dg/ext/vector31.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/ext/vector31.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/ext/vector31.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,29 @@
++// PR c++/71871
++// { dg-do compile }
++
++typedef unsigned int V __attribute__ ((__vector_size__ (32)));
++
++template <int N>
++void
++foo (V *x)
++{
++  V a = *x;
++  a = a ? a : -1;
++  *x = a;
++}
++
++template <typename T>
++void
++bar (T *x)
++{
++  T a = *x;
++  a = a ? a : -1;
++  *x = a;
++}
++
++void
++test (V *x, V *y)
++{
++  foo<0> (x);
++  bar<V> (y);
++}
 Index: gcc/testsuite/g++.dg/vect/simd-clone-6.cc
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/vect/simd-clone-6.cc	(.../tags/gcc_6_1_0_release)
@@ -17746,6 +23716,33 @@ Index: gcc/testsuite/g++.dg/gomp/declare-simd-6.C
 +int f15 (S a);
 +#pragma omp declare simd linear(a:1)			// { dg-error "applied to non-integral non-pointer variable" }
 +int f16 (S a);
+Index: gcc/testsuite/g++.dg/gomp/pr71941.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/gomp/pr71941.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/gomp/pr71941.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,22 @@
++// PR c++/71941
++// { dg-do compile }
++// { dg-options "-fopenmp" }
++
++struct A { A (); A (A &); ~A (); };
++
++template <int N>
++struct B
++{
++  struct C { A a; C () : a () {} };
++  C c;
++  void foo ();
++};
++
++void
++bar ()
++{
++  B<0> b;
++#pragma omp task
++  for (int i = 0; i < 2; i++)
++    b.foo ();
++}
 Index: gcc/testsuite/g++.dg/init/pr71516.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/init/pr71516.C	(.../tags/gcc_6_1_0_release)
@@ -17761,6 +23758,38 @@ Index: gcc/testsuite/g++.dg/init/pr71516.C
 +};
 +A B::a = A();	// { dg-error "has initializer but incomplete type|invalid use of incomplete type" }
 +struct A {};
+Index: gcc/testsuite/g++.dg/init/elide5.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/init/elide5.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/init/elide5.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,27 @@
++// PR c++/71913
++// { dg-do link { target c++11 } }
++
++void* operator new(unsigned long, void* p) { return p; }
++
++struct IndirectReturn {
++  IndirectReturn() {}
++  // Undefined so we get a link error if the indirect return value is copied
++  IndirectReturn(const IndirectReturn&);
++  IndirectReturn& operator=(const IndirectReturn&) = delete;
++  ~IndirectReturn() {}
++};
++
++IndirectReturn foo() { return IndirectReturn(); }
++
++void bar(void* ptr) {
++  new (ptr) IndirectReturn(foo());
++}
++
++alignas (alignof (IndirectReturn))
++unsigned char c[sizeof(IndirectReturn)];
++
++int main()
++{
++  bar(c);
++}
++
 Index: gcc/testsuite/g++.dg/other/i386-10.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/other/i386-10.C	(.../tags/gcc_6_1_0_release)
@@ -17778,6 +23807,40 @@ Index: gcc/testsuite/g++.dg/other/i386-10.C
 +
 +    r = __builtin_ia32_aeskeygenassist128 (r, (int)(index));
 +}
+Index: gcc/testsuite/g++.dg/other/pr71728.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/other/pr71728.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/other/pr71728.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,11 @@
++// PR c++/71728
++// { dg-do compile }
++// { dg-options "-std=gnu++14 -Wall" }
++
++int
++foo ()
++{
++  if (({ goto test; test: 1; }) != 1)
++    return 1;
++  return 2;
++}
+Index: gcc/testsuite/g++.dg/conversion/ambig3.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/conversion/ambig3.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/conversion/ambig3.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,13 @@
++// PR c++/71835
++// { dg-do compile }
++
++typedef void T (int);
++struct A { operator T * (); };	// { dg-message "candidate" }
++struct B { operator T * (); };	// { dg-message "candidate" }
++struct C : A, B {} c;
++
++void
++foo ()
++{
++  c (0);		// { dg-error "is ambiguous" }
++}
 Index: gcc/testsuite/g++.dg/warn/Wplacement-new-size-3.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/warn/Wplacement-new-size-3.C	(.../tags/gcc_6_1_0_release)
@@ -17835,6 +23898,274 @@ Index: gcc/testsuite/g++.dg/warn/Wno-narrowing1.C
 +short offsets[1] = {
 +  ((char*) &(((struct s*)16)->y) - (char *)16),  // { dg-bogus "note" }
 +};
+Index: gcc/testsuite/g++.dg/concepts/req5.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/concepts/req5.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/concepts/req5.C	(.../branches/gcc-6-branch)
+@@ -9,10 +9,10 @@
+ template<typename T> constexpr fool p2() { return {}; }
+ 
+ template<typename T>
+-  concept bool C() { return p1<T>() && p2<T>(); } // { dg-error "does not have type" }
++  concept bool C() { return p1<T>() && p2<T>(); }
+ 
+ template<C T> void f(T x) { }
+ 
+ int main() {
+-  f(0); // { dg-error "cannot call" }
++  f(0); // { dg-error "cannot call|uses overloaded operator" }
+ }
+Index: gcc/testsuite/g++.dg/concepts/expression2.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/concepts/expression2.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/concepts/expression2.C	(.../branches/gcc-6-branch)
+@@ -31,7 +31,7 @@
+ int main()
+ {
+   f1(s); // { dg-error "cannot call" }
+-  f2(s); // { dg-error "cannot call" }
++  f2(s); // { dg-error "" }
+ 
+   // When used in non-SFINAE contexts, make sure that we fail
+   // the constraint check before emitting the access check
+@@ -38,5 +38,5 @@
+   // failures. The context is being presented constistently
+   // in both cases.
+   static_assert(C1<S>(), ""); // { dg-error "failed" }
+-  static_assert(C2<S>(), ""); // { dg-error "failed" }
++  static_assert(C2<S>(), ""); // { dg-error "" }
+ }
+Index: gcc/testsuite/g++.dg/concepts/req6.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/concepts/req6.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/concepts/req6.C	(.../branches/gcc-6-branch)
+@@ -7,7 +7,12 @@
+   concept bool C1() { return X(); }
+ 
+ template<C1 T>
+-  void h(T) { } // { dg-error "not|bool" }
++  void h(T) { } // OK until used.
+ 
++void f()
++{
++  h(0); // { dg-error "does not have|cannot call" }
++}
++
+ template<typename T>
+   concept bool C2() { return X() == X(); } // OK
+Index: gcc/testsuite/g++.dg/concepts/variadic2.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/concepts/variadic2.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/concepts/variadic2.C	(.../branches/gcc-6-branch)
+@@ -4,10 +4,13 @@
+ template <class T> concept bool Constructable = requires { T(); };
+ template <class T> concept bool Both = Copyable<T> && Constructable<T>;
+ 
+-template <Copyable... Ts> void f(Ts...) { }
+-template <Both... Ts> void f(Ts...) { }
++template <Copyable... Ts>
++constexpr int f(Ts...) { return 0; } // #1
+ 
++template <Both... Ts>
++constexpr int f(Ts...) { return 1; }     // #2
++
+ int main()
+ {
+-  f(42);
++  static_assert(f(42) == 1);
+ }
+Index: gcc/testsuite/g++.dg/concepts/dr1430.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/concepts/dr1430.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/concepts/dr1430.C	(.../branches/gcc-6-branch)
+@@ -24,11 +24,19 @@
+     return decltype(check<T, U, Args...>())::value;
+   }
+ 
++template <typename T, typename U, typename... Args>
++  concept bool Similar = true;
++
+ template <typename... Args>
+-requires Same<Args...>()	// { dg-error "concept" }
++requires Same<Args...>() // { dg-error "invalid reference" }
+   void foo( Args... args ) {}
+ 
++template <typename... Args>
++requires Similar<Args...> // { dg-error "invalid reference" }
++  void bar( Args... args ) {}
++
+ int main()
+ {
+-  foo(1, 2, 3);			// { dg-error "" }
++  foo(1, 2, 3); // { dg-error "cannot call" }
++  bar(1, 2, 3); // { dg-error "cannot call" }
+ }
+Index: gcc/testsuite/g++.dg/concepts/req19.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/concepts/req19.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/concepts/req19.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,13 @@
++// { dg-options "-std=c++1z -fconcepts" }
++
++struct B
++{
++  template <class T> void f(T t)
++    requires requires (T tt) { tt; }
++  { }
++};
++
++int main()
++{
++  B().f(42);
++}
+Index: gcc/testsuite/g++.dg/concepts/req20.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/concepts/req20.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/concepts/req20.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,19 @@
++// { dg-options "-std=c++1z -fconcepts" }
++
++template <class T> concept bool C = true;
++
++template <class T>
++requires C<typename T::foo>
++void f(T t) { }
++
++void f(...);
++
++template <class T>
++requires C<T>
++void g(T t) { }
++
++int main()
++{
++  f(42);
++  g(42);
++}
+Index: gcc/testsuite/g++.dg/concepts/diagnostic1.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/concepts/diagnostic1.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/concepts/diagnostic1.C	(.../branches/gcc-6-branch)
+@@ -1,16 +1,30 @@
+ // PR c++/67159
+ // { dg-options "-std=c++1z -fconcepts" }
+ 
++template <class T, class U>
++concept bool SameAs = __is_same_as(T, U);
++
+ template <class T>
+-concept bool R = requires (T& t) {
++concept bool R1 = requires (T& t) {
+   { t.begin() } -> T
++  { t.end() } -> SameAs<T*>;
+ };
+ 
++template <class T>
++concept bool R2 = requires (T& t) {
++  { t.end() } -> SameAs<T*>;
++};
++
+ struct foo {
+   int* begin();
++  int* end();
+ };
+ 
+-R{T}
++R1{T}
+ constexpr bool f() { return true; }
+ 
++R2{T}
++constexpr bool g() { return true; }
++
+ static_assert(f<foo>());	// { dg-error "" }
++static_assert(g<foo>());	// { dg-error "" }
+Index: gcc/testsuite/g++.dg/concepts/req4.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/concepts/req4.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/concepts/req4.C	(.../branches/gcc-6-branch)
+@@ -9,10 +9,10 @@
+ template<typename T> constexpr fool p2() { return {}; }
+ 
+ template<typename T>
+-  concept bool C() { return p1<T>() && p2<T>(); } // { dg-error "does not have type" }
++  concept bool C() { return p1<T>() && p2<T>(); }
+ 
+ template<C T> void f(T x) { }
+ 
+ int main() {
+-  f(0); // { dg-error "cannot call" }
++  f(0); // { dg-error "cannot call|uses overloaded operator" }
+ }
+Index: gcc/testsuite/g++.dg/concepts/var-templ1.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/concepts/var-templ1.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/concepts/var-templ1.C	(.../branches/gcc-6-branch)
+@@ -13,4 +13,4 @@
+ constexpr bool f() { return false; }
+ 
+ static_assert(f<void>());
+-static_assert(v<void>);		// { dg-error "constraints" }
++static_assert(v<void>);		// { dg-error "invalid" }
+Index: gcc/testsuite/g++.dg/template/friend63.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/template/friend63.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/template/friend63.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,29 @@
++// PR c++/71738
++
++template < class > struct S
++{
++  template < class > struct A
++  { 
++    template < class > struct B
++    {
++      template <class Z>
++      void operator=(Z) { S::i = 0; }
++    };
++  };
++
++  // Note that this friend declaration is useless, since nested classes are
++  // already friends of their enclosing class.
++  template < class X >
++  template < class Y >
++  template < class Z >
++  friend void A < X >::B < Y >::operator= (Z);
++
++private:
++  static int i;
++};
++
++int main()
++{
++  S<int>::A<int>::B<int> b;
++  b = 0;
++}
+Index: gcc/testsuite/g++.dg/template/defarg21.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/template/defarg21.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/template/defarg21.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,21 @@
++// PR c++/71822
++// { dg-do compile }
++
++int bar (int);
++
++template <typename T>
++struct A
++{
++  explicit A (int x = bar (sizeof (T)));
++};
++
++struct B
++{
++  A <int> b[2];
++};
++
++void
++baz ()
++{
++  B b;
++}
 Index: gcc/testsuite/g++.dg/template/pr70466-2.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/template/pr70466-2.C	(.../tags/gcc_6_1_0_release)
@@ -17865,6 +24196,32 @@ Index: gcc/testsuite/g++.dg/template/pr70466-2.C
 +  foo (&B::bar);
 +  return 0;
 +}
+Index: gcc/testsuite/g++.dg/template/ttp29.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/template/ttp29.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/template/ttp29.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,21 @@
++// PR c++/70778
++
++template <class KeyType>
++struct Stuff
++{
++  template <KeyType, class>
++  struct AddToFront;
++
++  template <KeyType ToAdd, template<KeyType> class Holder, KeyType Indexs>
++  struct AddToFront<ToAdd, Holder<Indexs> >
++  {
++  };
++};
++
++template <unsigned>
++struct Holder {};
++
++int main()
++{
++  Stuff<unsigned>::AddToFront<0, Holder<24> > t;
++}
 Index: gcc/testsuite/g++.dg/template/friend62.C
 ===================================================================
 --- a/src/gcc/testsuite/g++.dg/template/friend62.C	(.../tags/gcc_6_1_0_release)
@@ -17918,6 +24275,34 @@ Index: gcc/testsuite/g++.dg/template/pr70466-1.C
 +  foo (&B::bar);
 +  return 0;
 +}
+Index: gcc/testsuite/g++.dg/template/dtor10.C
+===================================================================
+--- a/src/gcc/testsuite/g++.dg/template/dtor10.C	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/g++.dg/template/dtor10.C	(.../branches/gcc-6-branch)
+@@ -0,0 +1,23 @@
++// PR c++/71748
++
++struct A
++{
++  virtual ~A () {}
++};
++
++struct B : public A
++{
++  virtual ~B () {}
++};
++
++template < int > void foo ()
++{
++  B *b = new B;
++  b->~A ();
++}
++
++int main ()
++{
++  foo < 0 > ();
++  return 0;
++}
 Index: gcc/testsuite/c-c++-common/ubsan/bounds-13.c
 ===================================================================
 --- a/src/gcc/testsuite/c-c++-common/ubsan/bounds-13.c	(.../tags/gcc_6_1_0_release)
@@ -18057,6 +24442,21 @@ Index: gcc/testsuite/c-c++-common/gomp/pr71371.c
 +      baz (&i);
 +  }
 +}
+Index: gcc/testsuite/c-c++-common/gomp/pr71758.c
+===================================================================
+--- a/src/gcc/testsuite/c-c++-common/gomp/pr71758.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/testsuite/c-c++-common/gomp/pr71758.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,10 @@
++/* PR middle-end/71758 */
++
++void
++foo (int *p)
++{
++  long long i = 0;
++  #pragma omp target device (i)
++  ;
++  #pragma omp target update device (i) to (p[0])
++}
 Index: gcc/testsuite/c-c++-common/gomp/clauses-1.c
 ===================================================================
 --- a/src/gcc/testsuite/c-c++-common/gomp/clauses-1.c	(.../tags/gcc_6_1_0_release)
@@ -18360,11 +24760,57 @@ Index: gcc/cp/typeck.c
      {
        tree t = complete_type (TREE_TYPE (type));
        unsigned int needs_constructing, has_nontrivial_dtor;
+@@ -6270,8 +6270,7 @@
+     }
+ 
+   expr = build_conditional_expr (loc, ifexp, op1, op2, complain);
+-  if (processing_template_decl && expr != error_mark_node
+-      && TREE_CODE (expr) != VEC_COND_EXPR)
++  if (processing_template_decl && expr != error_mark_node)
+     {
+       tree min = build_min_non_dep (COND_EXPR, expr,
+ 				    orig_ifexp, orig_op1, orig_op2);
 Index: gcc/cp/init.c
 ===================================================================
 --- a/src/gcc/cp/init.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/cp/init.c	(.../branches/gcc-6-branch)
-@@ -2375,7 +2375,8 @@
+@@ -1816,6 +1816,19 @@
+       return;
+     }
+ 
++  /* List-initialization from {} becomes value-initialization for non-aggregate
++     classes with default constructors.  Handle this here so protected access
++     works.  */
++  if (init && TREE_CODE (init) == TREE_LIST)
++    {
++      tree elt = TREE_VALUE (init);
++      if (DIRECT_LIST_INIT_P (elt)
++	  && CONSTRUCTOR_ELTS (elt) == 0
++	  && CLASSTYPE_NON_AGGREGATE (type)
++	  && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
++	init = void_type_node;
++    }
++
+   /* If an explicit -- but empty -- initializer list was present,
+      that's value-initialization.  */
+   if (init == void_type_node)
+@@ -2072,8 +2085,13 @@
+ 	  && TREE_CODE (init) == TREE_LIST
+ 	  && TREE_CHAIN (init) == NULL_TREE)
+ 	init = TREE_VALUE (init);
+-      /* Instantiate a non-dependent initializer.  */
+-      init = instantiate_non_dependent_or_null (init);
++      /* Instantiate a non-dependent initializer for user variables.  We
++	 mustn't do this for the temporary for an array compound literal;
++	 trying to instatiate the initializer will keep creating new
++	 temporaries until we crash.  Probably it's not useful to do it for
++	 other artificial variables, either.  */
++      if (!DECL_ARTIFICIAL (decl))
++	init = instantiate_non_dependent_or_null (init);
+       if (!init
+ 	  || !TREE_TYPE (init)
+ 	  || !TREE_CONSTANT (init)
+@@ -2375,7 +2393,8 @@
  
    STRIP_NOPS (oper);
  
@@ -18374,7 +24820,7 @@ Index: gcc/cp/init.c
      {
        /* Similar to the offset computed above, see if the array index
  	 is a compile-time constant.  If so, and unless the offset was
-@@ -2404,8 +2405,8 @@
+@@ -2404,8 +2423,8 @@
    bool compref = TREE_CODE (oper) == COMPONENT_REF;
  
    /* Descend into a struct or union to find the member whose address
@@ -18385,6 +24831,20 @@ Index: gcc/cp/init.c
      {
        tree op0 = oper;
        while (TREE_CODE (op0 = TREE_OPERAND (op0, 0)) == COMPONENT_REF);
+Index: gcc/cp/class.c
+===================================================================
+--- a/src/gcc/cp/class.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/class.c	(.../branches/gcc-6-branch)
+@@ -4172,7 +4172,8 @@
+       /* Avoid recursing into objects that are not interesting.  */
+       if (!CLASS_TYPE_P (element_type)
+ 	  || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type)
+-	  || !domain)
++	  || !domain
++	  || integer_minus_onep (TYPE_MAX_VALUE (domain)))
+ 	return 0;
+ 
+       /* Step through each of the elements in the array.  */
 Index: gcc/cp/decl.c
 ===================================================================
 --- a/src/gcc/cp/decl.c	(.../tags/gcc_6_1_0_release)
@@ -18416,7 +24876,20 @@ Index: gcc/cp/decl.c
      layout_decl (decl, 0);
  
    if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE)
-@@ -6633,6 +6638,13 @@
+@@ -5892,8 +5897,10 @@
+ 	    }
+ 	}
+ 
+-      warning (OPT_Wmissing_braces, "missing braces around initializer for %qT",
+-	       type);
++      if (complain & tf_warning)
++	warning (OPT_Wmissing_braces,
++		 "missing braces around initializer for %qT",
++		 type);
+     }
+ 
+   /* Dispatch to specialized routines.  */
+@@ -6633,6 +6640,13 @@
                                                     adc_variable_type);
        if (type == error_mark_node)
  	return;
@@ -18430,7 +24903,16 @@ Index: gcc/cp/decl.c
        cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
      }
  
-@@ -11186,8 +11198,7 @@
+@@ -7905,7 +7919,7 @@
+ 
+       /* Adjust the required expression into a constraint. */
+       if (decl_reqs)
+-        decl_reqs = make_predicate_constraint (decl_reqs);
++        decl_reqs = normalize_expression (decl_reqs);
+ 
+       tree ci = build_constraints (tmpl_reqs, decl_reqs);
+       set_constraints (decl, ci);
+@@ -11186,8 +11200,7 @@
  	  }
  	else if (!staticp && !dependent_type_p (type)
  		 && !COMPLETE_TYPE_P (complete_type (type))
@@ -18440,7 +24922,7 @@ Index: gcc/cp/decl.c
  		     || initialized == 0))
  	  {
  	    if (TREE_CODE (type) != ARRAY_TYPE
-@@ -13382,6 +13393,19 @@
+@@ -13382,6 +13395,19 @@
        use_short_enum = flag_short_enums
          || lookup_attribute ("packed", TYPE_ATTRIBUTES (enumtype));
  
@@ -18460,7 +24942,7 @@ Index: gcc/cp/decl.c
        for (itk = (use_short_enum ? itk_char : itk_int);
             itk != itk_none;
             itk++)
-@@ -14999,8 +15023,9 @@
+@@ -14999,8 +15025,9 @@
  	  tree var = iv->decl;
  	  tree type = TREE_TYPE (var);
  
@@ -18472,6 +24954,18 @@ Index: gcc/cp/decl.c
  	    {
  	      /* Complete the type of the variable.  The VAR_DECL itself
  		 will be laid out in expand_expr.  */
+Index: gcc/cp/ptree.c
+===================================================================
+--- a/src/gcc/cp/ptree.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/ptree.c	(.../branches/gcc-6-branch)
+@@ -260,7 +260,6 @@
+ 		      indent+4);
+         print_node (file, "associated_constr",
+                           cinfo->associated_constr, indent+4);
+-        print_node_brief (file, "assumptions", cinfo->assumptions, indent+4);
+         break;
+       }
+     case ARGUMENT_PACK_SELECT:
 Index: gcc/cp/method.c
 ===================================================================
 --- a/src/gcc/cp/method.c	(.../tags/gcc_6_1_0_release)
@@ -18509,11 +25003,1517 @@ Index: gcc/cp/constexpr.c
  		error_at (loc, "%qD called in a constant expression before its "
  			  "definition is complete", fun);
  	      else if (DECL_INITIAL (fun))
+@@ -1444,9 +1450,19 @@
+     }
+   else
+     {
+-      if (!result || result == error_mark_node)
++      if (result && result != error_mark_node)
++	/* OK */;
++      else if (!DECL_SAVED_TREE (fun))
+ 	{
+-	  gcc_assert (DECL_SAVED_TREE (fun));
++	  /* When at_eof >= 2, cgraph has started throwing away
++	     DECL_SAVED_TREE, so fail quietly.  FIXME we get here because of
++	     late code generation for VEC_INIT_EXPR, which needs to be
++	     completely reconsidered.  */
++	  gcc_assert (at_eof >= 2 && ctx->quiet);
++	  *non_constant_p = true;
++	}
++      else
++	{
+ 	  tree body, parms, res;
+ 
+ 	  /* Reuse or create a new unshared copy of this function's body.  */
+@@ -1750,6 +1766,10 @@
+ 	       && (null_member_pointer_value_p (lhs)
+ 		   || null_member_pointer_value_p (rhs)))
+ 	r = constant_boolean_node (!is_code_eq, type);
++      else if (TREE_CODE (lhs) == PTRMEM_CST)
++	lhs = cplus_expand_constant (lhs);
++      else if (TREE_CODE (rhs) == PTRMEM_CST)
++	rhs = cplus_expand_constant (rhs);
+     }
+ 
+   if (r == NULL_TREE)
+@@ -3714,6 +3734,19 @@
+ 
+     case REALPART_EXPR:
+     case IMAGPART_EXPR:
++      if (lval)
++	{
++	  r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
++					    non_constant_p, overflow_p);
++	  if (r == error_mark_node)
++	    ;
++	  else if (r == TREE_OPERAND (t, 0))
++	    r = t;
++	  else
++	    r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), r);
++	  break;
++	}
++      /* FALLTHRU */
+     case CONJ_EXPR:
+     case FIX_TRUNC_EXPR:
+     case FLOAT_EXPR:
+@@ -5140,10 +5173,12 @@
+     case GOTO_EXPR:
+       {
+ 	tree *target = &TREE_OPERAND (t, 0);
+-	/* Gotos representing break and continue are OK; we should have
+-	   rejected other gotos in parsing.  */
+-	gcc_assert (breaks (target) || continues (target));
+-	return true;
++	/* Gotos representing break and continue are OK.  */
++	if (breaks (target) || continues (target))
++	  return true;
++	if (flags & tf_error)
++	  error ("%<goto%> is not a constant-expression");
++	return false;
+       }
+ 
+     default:
+@@ -5151,7 +5186,7 @@
+ 	return false;
+ 
+       sorry ("unexpected AST of kind %s", get_tree_code_name (TREE_CODE (t)));
+-      gcc_unreachable();
++      gcc_unreachable ();
+       return false;
+     }
+ #undef RECUR
+Index: gcc/cp/error.c
+===================================================================
+--- a/src/gcc/cp/error.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/error.c	(.../branches/gcc-6-branch)
+@@ -961,7 +961,12 @@
+     {
+       if (VAR_P (t)
+ 	  && DECL_DECLARED_CONSTEXPR_P (t))
+-	pp_cxx_ws_string (pp, "constexpr");
++            {
++              if (DECL_DECLARED_CONCEPT_P (t))
++                pp_cxx_ws_string (pp, "concept");
++              else
++		pp_cxx_ws_string (pp, "constexpr");
++            }
+       dump_type_prefix (pp, type, flags & ~TFF_UNQUALIFIED_NAME);
+       pp_maybe_space (pp);
+     }
+@@ -1334,16 +1339,19 @@
+ 	  if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+ 	    pp_cxx_ws_string (pp, "...");
+ 	}
++
++      /* Only print the requirements if we're also printing
++         the template header.  */
++      if (flag_concepts)
++	if (tree ci = get_constraints (t))
++	  if (check_constraint_info (ci))
++	    if (tree reqs = CI_TEMPLATE_REQS (ci))
++	      {
++		pp_cxx_requires_clause (pp, reqs);
++		pp_cxx_whitespace (pp);
++	      }
+     }
+ 
+-  if (flag_concepts)
+-    if (tree ci = get_constraints (t))
+-      if (check_constraint_info (ci))
+-        if (tree reqs = CI_TEMPLATE_REQS (ci))
+-	  {
+-	    pp_cxx_requires_clause (pp, reqs);
+-	    pp_cxx_whitespace (pp);
+-	  }
+ 
+   if (DECL_CLASS_TEMPLATE_P (t))
+     dump_type (pp, TREE_TYPE (t),
+@@ -1530,7 +1538,12 @@
+ 	pp_cxx_ws_string (pp, "virtual");
+ 
+       if (DECL_DECLARED_CONSTEXPR_P (t))
+-	pp_cxx_ws_string (pp, "constexpr");
++        {
++          if (DECL_DECLARED_CONCEPT_P (t))
++            pp_cxx_ws_string (pp, "concept");
++          else
++	    pp_cxx_ws_string (pp, "constexpr");
++	}
+     }
+ 
+   /* Print the return type?  */
+@@ -2661,6 +2674,10 @@
+       break;
+ 
+     case EXPR_PACK_EXPANSION:
++    case UNARY_LEFT_FOLD_EXPR:
++    case UNARY_RIGHT_FOLD_EXPR:
++    case BINARY_LEFT_FOLD_EXPR:
++    case BINARY_RIGHT_FOLD_EXPR:
+     case TYPEID_EXPR:
+     case MEMBER_REF:
+     case DOTSTAR_EXPR:
+@@ -2733,6 +2750,7 @@
+       break;
+ 
+     case PRED_CONSTR:
++    case CHECK_CONSTR:
+     case EXPR_CONSTR:
+     case TYPE_CONSTR:
+     case ICONV_CONSTR:
+Index: gcc/cp/operators.def
+===================================================================
+--- a/src/gcc/cp/operators.def	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/operators.def	(.../branches/gcc-6-branch)
+@@ -155,3 +155,7 @@
+ 
+ /* Variadic templates extension. */
+ DEF_SIMPLE_OPERATOR ("...", EXPR_PACK_EXPANSION, "sp", 1)
++DEF_SIMPLE_OPERATOR ("... +", UNARY_LEFT_FOLD_EXPR, "fl", 2)
++DEF_SIMPLE_OPERATOR ("+ ...", UNARY_RIGHT_FOLD_EXPR, "fr", 2)
++DEF_SIMPLE_OPERATOR ("+ ... +", BINARY_LEFT_FOLD_EXPR, "fL", 3)
++DEF_SIMPLE_OPERATOR ("+ ... +", BINARY_RIGHT_FOLD_EXPR, "fR", 3)
+Index: gcc/cp/tree.c
+===================================================================
+--- a/src/gcc/cp/tree.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/tree.c	(.../branches/gcc-6-branch)
+@@ -3139,6 +3139,11 @@
+       return cp_tree_equal (CI_ASSOCIATED_CONSTRAINTS (t1),
+                             CI_ASSOCIATED_CONSTRAINTS (t2));
+ 
++    case CHECK_CONSTR:
++      return (CHECK_CONSTR_CONCEPT (t1) == CHECK_CONSTR_CONCEPT (t2)
++              && comp_template_args (CHECK_CONSTR_ARGS (t1),
++				     CHECK_CONSTR_ARGS (t2)));
++
+     case TREE_VEC:
+       {
+ 	unsigned ix;
+Index: gcc/cp/logic.cc
+===================================================================
+--- a/src/gcc/cp/logic.cc	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/logic.cc	(.../branches/gcc-6-branch)
+@@ -23,6 +23,7 @@
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
++#include "timevar.h"
+ #include "hash-set.h"
+ #include "machmode.h"
+ #include "vec.h"
+@@ -50,19 +51,52 @@
+ 
+ // Helper algorithms
+ 
+-// Increment iter distance(first, last) times.
+-template<typename I1, typename I2, typename I3>
+-  I1 next_by_distance (I1 iter, I2 first, I3 last)
+-  {
+-    for ( ; first != last; ++first, ++iter)
+-      ;
+-    return iter;
+-  }
++template<typename I>
++inline I
++next (I iter)
++{
++  return ++iter;
++}
+ 
++template<typename I, typename P>
++inline bool
++any_p (I first, I last, P pred)
++{
++  while (first != last)
++    {
++      if (pred(*first))
++        return true;
++      ++first;
++    }
++  return false;
++}
++
++bool prove_implication (tree, tree);
++
+ /*---------------------------------------------------------------------------
+                            Proof state
+ ---------------------------------------------------------------------------*/
+ 
++struct term_entry
++{
++  tree t;
++};
++
++/* Hashing function and equality for constraint entries.  */
++
++struct term_hasher : ggc_ptr_hash<term_entry>
++{
++  static hashval_t hash (term_entry *e)
++  {
++    return iterative_hash_template_arg (e->t, 0);
++  }
++
++  static bool equal (term_entry *e1, term_entry *e2)
++  {
++    return cp_tree_equal (e1->t, e2->t);
++  }
++};
++
+ /* A term list is a list of atomic constraints. It is used
+    to maintain the lists of assumptions and conclusions in a
+    proof goal.
+@@ -70,109 +104,122 @@
+    Each term list maintains an iterator that refers to the current
+    term. This can be used by various tactics to support iteration
+    and stateful manipulation of the list. */
+-struct term_list : std::list<tree>
++struct term_list
+ {
++  typedef std::list<tree>::iterator iterator;
++
+   term_list ();
+-  term_list (const term_list &x);
+-  term_list& operator= (const term_list &x);
++  term_list (tree);
+ 
+-  tree       current_term ()       { return *current; }
+-  const_tree current_term () const { return *current; }
++  bool includes (tree);
++  iterator insert (iterator, tree);
++  iterator push_back (tree);
++  iterator erase (iterator);
++  iterator replace (iterator, tree);
++  iterator replace (iterator, tree, tree);
+ 
++  iterator begin() { return seq.begin(); }
++  iterator end() { return seq.end(); }
+ 
+-  void insert (tree t);
+-  tree erase ();
+-
+-  void start ();
+-  void next ();
+-  bool done() const;
+-
+-  iterator current;
++  std::list<tree>         seq;
++  hash_table<term_hasher> tab;
+ };
+ 
+ inline
+ term_list::term_list ()
+-  : std::list<tree> (), current (end ())
+-{ }
++  : seq(), tab (11)
++{
++}
+ 
++/* Initialize a term list with an initial term. */
++
+ inline
+-term_list::term_list (const term_list &x)
+-  : std::list<tree> (x)
+-  , current (next_by_distance (begin (), x.begin (), x.current))
+-{ }
+-
+-inline term_list&
+-term_list::operator= (const term_list &x)
++term_list::term_list (tree t)
++  : seq (), tab (11)
+ {
+-  std::list<tree>::operator=(x);
+-  current = next_by_distance (begin (), x.begin (), x.current);
+-  return *this;
++  push_back (t);
+ }
+ 
+-/* Try saving the term T into the list of terms. If
+-   T is already in the list of terms, then no action is
+-   performed. Otherwise, insert T before the current
+-   position, making this term current.
++/* Returns true if T is the in the tree. */
+ 
+-   Note that not inserting terms is an optimization
+-   that corresponds to the structural rule of
+-   contraction.
++inline bool
++term_list::includes (tree t)
++{
++  term_entry ent = {t};
++  return tab.find (&ent);
++}
+ 
+-   NOTE: With the contraction rule, this data structure
+-   would be more efficiently represented as an ordered set
+-   or hash set.  */
+-void
+-term_list::insert (tree t)
++/* Append a term to the list. */
++inline term_list::iterator
++term_list::push_back (tree t)
+ {
+-  /* Search the current term list. If there is already
+-     a matching term, do not add the new one.  */
+-  for (iterator i = begin(); i != end(); ++i)
+-    if (cp_tree_equal (*i, t))
+-      return;
+-
+-  current = std::list<tree>::insert (current, t);
++  return insert (end(), t);
+ }
+ 
+-/* Remove the current term from the list, repositioning to
+-   the term following the removed term. Note that the new
+-   position could be past the end of the list.
++/* Insert a new (unseen) term T into the list before the proposition
++   indicated by ITER. Returns the iterator to the newly inserted
++   element.  */
+ 
+-   The removed term is returned. */
+-inline tree
+-term_list::erase ()
++term_list::iterator
++term_list::insert (iterator iter, tree t)
+ {
+-  tree t = *current;
+-  current = std::list<tree>::erase (current);
+-  return t;
++  gcc_assert (!includes (t));
++  iter = seq.insert (iter, t);
++  term_entry ent = {t};
++  term_entry** slot = tab.find_slot (&ent, INSERT);
++  term_entry* ptr = ggc_alloc<term_entry> ();
++  *ptr = ent;
++  *slot = ptr;
++  return iter;
+ }
+ 
+-/* Initialize the current term to the first in the list. */
+-inline void
+-term_list::start ()
++/* Remove an existing term from the list. Returns an iterator referring
++   to the element after the removed term.  This may be end().  */
++
++term_list::iterator
++term_list::erase (iterator iter)
+ {
+-  current = begin ();
++  gcc_assert (includes (*iter));
++  term_entry ent = {*iter};
++  tab.remove_elt (&ent);
++  iter = seq.erase (iter);
++  return iter;
+ }
+ 
+-/* Advance to the next term in the list. */
+-inline void
+-term_list::next ()
++/* Replace the given term with that specified. If the term has
++   been previously seen, do not insert the term. Returns the
++   first iterator past the current term.  */
++
++term_list::iterator
++term_list::replace (iterator iter, tree t)
+ {
+-  ++current;
++  iter = erase (iter);
++  if (!includes (t))
++    insert (iter, t);
++  return iter;
+ }
+ 
+-/* Returns true when the current position is past the end. */
+-inline bool
+-term_list::done () const
++
++/* Replace the term at the given position by the supplied T1
++   followed by t2. This is used in certain logical operators to
++   load a list of assumptions or conclusions.  */
++
++term_list::iterator
++term_list::replace (iterator iter, tree t1, tree t2)
+ {
+-  return current == end ();
++  iter = erase (iter);
++  if (!includes (t1))
++    insert (iter, t1);
++  if (!includes (t2))
++    insert (iter, t2);
++  return iter;
+ }
+ 
+-
+ /* A goal (or subgoal) models a sequent of the form
+    'A |- C' where A and C are lists of assumptions and
+    conclusions written as propositions in the constraint
+-   language (i.e., lists of trees).
+-*/
++   language (i.e., lists of trees). */
++
+ struct proof_goal
+ {
+   term_list assumptions;
+@@ -182,18 +229,18 @@
+ /* A proof state owns a list of goals and tracks the
+    current sub-goal. The class also provides facilities
+    for managing subgoals and constructing term lists. */
++
+ struct proof_state : std::list<proof_goal>
+ {
+   proof_state ();
+ 
+   iterator branch (iterator i);
++  iterator discharge (iterator i);
+ };
+ 
+-/* An alias for proof state iterators. */
+-typedef proof_state::iterator goal_iterator;
++/* Initialize the state with a single empty goal, and set that goal
++   as the current subgoal.  */
+ 
+-/* Initialize the state with a single empty goal,
+-   and set that goal as the current subgoal. */
+ inline
+ proof_state::proof_state ()
+   : std::list<proof_goal> (1)
+@@ -200,9 +247,9 @@
+ { }
+ 
+ 
+-/* Branch the current goal by creating a new subgoal,
+-   returning a reference to // the new object. This does
+-   not update the current goal. */
++/* Branch the current goal by creating a new subgoal, returning a
++   reference to the new object. This does not update the current goal. */
++
+ inline proof_state::iterator
+ proof_state::branch (iterator i)
+ {
+@@ -211,258 +258,519 @@
+   return insert (++i, g);
+ }
+ 
++/* Discharge the current goal, setting it equal to the
++   next non-satisfied goal. */
++
++inline proof_state::iterator
++proof_state::discharge (iterator i)
++{
++  gcc_assert (i != end());
++  return erase (i);
++}
++
++
+ /*---------------------------------------------------------------------------
+-                           Logical rules
++                        Debugging
+ ---------------------------------------------------------------------------*/
+ 
+-/*These functions modify the current state and goal by decomposing
+-  logical expressions using the logical rules of sequent calculus for
+-  first order logic.
++// void
++// debug (term_list& ts)
++// {
++//   for (term_list::iterator i = ts.begin(); i != ts.end(); ++i)
++//     verbatim ("  # %E", *i);
++// }
++//
++// void
++// debug (proof_goal& g)
++// {
++//   debug (g.assumptions);
++//   verbatim ("       |-");
++//   debug (g.conclusions);
++// }
+ 
+-  Note that in each decomposition rule, the term T has been erased
+-  from term list before the specific rule is applied. */
++/*---------------------------------------------------------------------------
++                        Atomicity of constraints
++---------------------------------------------------------------------------*/
+ 
+-/* The left logical rule for conjunction adds both operands
+-   to the current set of constraints. */
+-void
+-left_conjunction (proof_state &, goal_iterator i, tree t)
++/* Returns true if T is not an atomic constraint.  */
++
++bool
++non_atomic_constraint_p (tree t)
+ {
+-  gcc_assert (TREE_CODE (t) == CONJ_CONSTR);
++  switch (TREE_CODE (t))
++    {
++    case PRED_CONSTR:
++    case EXPR_CONSTR:
++    case TYPE_CONSTR:
++    case ICONV_CONSTR:
++    case DEDUCT_CONSTR:
++    case EXCEPT_CONSTR:
++      return false;
++    case CHECK_CONSTR:
++    case PARM_CONSTR:
++    case CONJ_CONSTR:
++    case DISJ_CONSTR:
++      return true;
++    default:
++      gcc_unreachable ();
++    }
++}
+ 
+-  /* Insert the operands into the current branch. Note that the
+-     final order of insertion is left-to-right. */
+-  term_list &l = i->assumptions;
+-  l.insert (TREE_OPERAND (t, 1));
+-  l.insert (TREE_OPERAND (t, 0));
++/* Returns true if any constraints in T are not atomic.  */
++
++bool
++any_non_atomic_constraints_p (term_list& t)
++{
++  return any_p (t.begin(), t.end(), non_atomic_constraint_p);
+ }
+ 
+-/* The left logical rule for disjunction creates a new goal,
+-   adding the first operand to the original set of
+-   constraints and the second operand to the new set
+-   of constraints. */
+-void
+-left_disjunction (proof_state &s, goal_iterator i, tree t)
++/*---------------------------------------------------------------------------
++                           Proof validations
++---------------------------------------------------------------------------*/
++
++enum proof_result
+ {
+-  gcc_assert (TREE_CODE (t) == DISJ_CONSTR);
++  invalid,
++  valid,
++  undecided
++};
+ 
+-  /* Branch the current subgoal. */
+-  goal_iterator j = s.branch (i);
+-  term_list &l1 = i->assumptions;
+-  term_list &l2 = j->assumptions;
++proof_result check_term (term_list&, tree);
+ 
+-  /* Insert operands into the different branches. */
+-  l1.insert (TREE_OPERAND (t, 0));
+-  l2.insert (TREE_OPERAND (t, 1));
++
++proof_result
++analyze_atom (term_list& ts, tree t)
++{
++  /* FIXME: Hook into special cases, if any. */
++  /*
++  term_list::iterator iter = ts.begin();
++  term_list::iterator end = ts.end();
++  while (iter != end)
++    {
++      ++iter;
++    }
++  */
++
++  if (non_atomic_constraint_p (t))
++    return undecided;
++  if (any_non_atomic_constraints_p (ts))
++    return undecided;
++  return invalid;
+ }
+ 
+-/* The left logical rules for parameterized constraints
+-   adds its operand to the current goal. The list of
+-   parameters are effectively discarded. */
+-void
+-left_parameterized_constraint (proof_state &, goal_iterator i, tree t)
++/* Search for a pack expansion in the list of assumptions that would
++   make this expansion valid.  */
++
++proof_result
++analyze_pack (term_list& ts, tree t)
+ {
+-  gcc_assert (TREE_CODE (t) == PARM_CONSTR);
+-  term_list &l = i->assumptions;
+-  l.insert (PARM_CONSTR_OPERAND (t));
++  tree c1 = normalize_expression (PACK_EXPANSION_PATTERN (t));
++  term_list::iterator iter = ts.begin();
++  term_list::iterator end = ts.end();
++  while (iter != end)
++    {
++      if (TREE_CODE (*iter) == TREE_CODE (t))
++        {
++          tree c2 = normalize_expression (PACK_EXPANSION_PATTERN (*iter));
++          if (prove_implication (c2, c1))
++            return valid;
++          else
++            return invalid;
++        }
++      ++iter;
++    }
++  return invalid;
+ }
+ 
+-/*---------------------------------------------------------------------------
+-                           Decomposition
+----------------------------------------------------------------------------*/
++/* Search for concept checks in TS that we know subsume T. */
+ 
+-/* The following algorithms decompose expressions into sets of
+-   atomic propositions. In terms of the sequent calculus, these
+-   functions exercise the logical rules only.
++proof_result
++search_known_subsumptions (term_list& ts, tree t)
++{
++  for (term_list::iterator i = ts.begin(); i != ts.end(); ++i)
++    if (TREE_CODE (*i) == CHECK_CONSTR)
++      {
++        if (bool* b = lookup_subsumption_result (*i, t))
++          return *b ? valid : invalid;
++      }
++  return undecided;
++}
+ 
+-   This is equivalent, for the purpose of determining subsumption,
+-   to rewriting a constraint in disjunctive normal form. It also
+-   allows the resulting assumptions to be used as declarations
+-   for the purpose of separate checking. */
++/* Determine if the terms in TS provide sufficient support for proving
++   the proposition T. If any term in TS is a concept check that is known
++   to subsume T, then the proof is valid. Otherwise, we have to expand T
++   and continue searching for support.  */
+ 
+-/* Apply the left logical rules to the proof state. */
+-void
+-decompose_left_term (proof_state &s, goal_iterator i)
++proof_result
++analyze_check (term_list& ts, tree t)
+ {
+-  term_list &l = i->assumptions;
+-  tree t = l.current_term ();
++  proof_result r = search_known_subsumptions (ts, t);
++  if (r != undecided)
++    return r;
++
++  tree tmpl = CHECK_CONSTR_CONCEPT (t);
++  tree args = CHECK_CONSTR_ARGS (t);
++  tree c = expand_concept (tmpl, args);
++  return check_term (ts, c);
++}
++
++/* Recursively check constraints of the parameterized constraint. */
++
++proof_result
++analyze_parameterized (term_list& ts, tree t)
++{
++  return check_term (ts, PARM_CONSTR_OPERAND (t));
++}
++
++proof_result
++analyze_conjunction (term_list& ts, tree t)
++{
++  proof_result r = check_term (ts, TREE_OPERAND (t, 0));
++  if (r == invalid || r == undecided)
++    return r;
++  return check_term (ts, TREE_OPERAND (t, 1));
++}
++
++proof_result
++analyze_disjunction (term_list& ts, tree t)
++{
++  proof_result r = check_term (ts, TREE_OPERAND (t, 0));
++  if (r == valid)
++    return r;
++  return check_term (ts, TREE_OPERAND (t, 1));
++}
++
++proof_result
++analyze_term (term_list& ts, tree t)
++{
+   switch (TREE_CODE (t))
+     {
++    case CHECK_CONSTR:
++      return analyze_check (ts, t);
++
++    case PARM_CONSTR:
++      return analyze_parameterized (ts, t);
++
+     case CONJ_CONSTR:
+-      left_conjunction (s, i, l.erase ());
+-      break;
++      return analyze_conjunction (ts, t);
+     case DISJ_CONSTR:
+-      left_disjunction (s, i, l.erase ());
+-      break;
+-    case PARM_CONSTR:
+-      left_parameterized_constraint (s, i, l.erase ());
+-      break;
++      return analyze_disjunction (ts, t);
++
++    case PRED_CONSTR:
++    case EXPR_CONSTR:
++    case TYPE_CONSTR:
++    case ICONV_CONSTR:
++    case DEDUCT_CONSTR:
++    case EXCEPT_CONSTR:
++      return analyze_atom (ts, t);
++
++    case EXPR_PACK_EXPANSION:
++      return analyze_pack (ts, t);
++
++    case ERROR_MARK:
++      /* Encountering an error anywhere in a constraint invalidates
++         the proof, since the constraint is ill-formed.  */
++      return invalid;
+     default:
+-      l.next ();
+-      break;
++      gcc_unreachable ();
+     }
+ }
+ 
+-/* Apply the left logical rules of the sequent calculus
+-   until the current goal is fully decomposed into atomic
+-   constraints. */
+-void
+-decompose_left_goal (proof_state &s, goal_iterator i)
++/* Check if a single term can be proven from a set of assumptions.
++   If the proof is not valid, then it is incomplete when either
++   the given term is non-atomic or any term in the list of assumptions
++   is not-atomic.  */
++
++proof_result
++check_term (term_list& ts, tree t)
+ {
+-  term_list& l = i->assumptions;
+-  l.start ();
+-  while (!l.done ())
+-    decompose_left_term (s, i);
++  /* Try the easy way; search for an equivalent term.  */
++  if (ts.includes (t))
++    return valid;
++
++  /* The hard way; actually consider what the term means.  */
++  return analyze_term (ts, t);
+ }
+ 
+-/* Apply the left logical rules of the sequent calculus
+-   until the antecedents are fully decomposed into atomic
+-   constraints. */
+-void
+-decompose_left (proof_state& s)
++/* Check to see if any term is proven by the assumptions in the
++   proof goal. The proof is valid if the proof of any term is valid.
++   If validity cannot be determined, but any particular
++   check was undecided, then this goal is undecided.  */
++
++proof_result
++check_goal (proof_goal& g)
+ {
+-  goal_iterator iter = s.begin ();
+-  goal_iterator end = s.end ();
+-  for ( ; iter != end; ++iter)
+-    decompose_left_goal (s, iter);
++  term_list::iterator iter = g.conclusions.begin ();
++  term_list::iterator end = g.conclusions.end ();
++  bool incomplete = false;
++  while (iter != end)
++    {
++      proof_result r = check_term (g.assumptions, *iter);
++      if (r == valid)
++        return r;
++      if (r == undecided)
++        incomplete = true;
++      ++iter;
++    }
++
++    /* Was the proof complete? */
++    if (incomplete)
++      return undecided;
++    else
++      return invalid;
+ }
+ 
+-/* Returns a vector of terms from the term list L. */
+-tree
+-extract_terms (term_list& l)
++/* Check if the the proof is valid. This is the case when all
++   goals can be discharged. If any goal is invalid, then the
++   entire proof is invalid. Otherwise, the proof is undecided.  */
++
++proof_result
++check_proof (proof_state& p)
+ {
+-  tree result = make_tree_vec (l.size());
+-  term_list::iterator iter = l.begin();
+-  term_list::iterator end = l.end();
+-  for (int n = 0; iter != end; ++iter, ++n)
+-    TREE_VEC_ELT (result, n) = *iter;
+-  return result;
++  proof_state::iterator iter = p.begin();
++  proof_state::iterator end = p.end();
++  while (iter != end)
++    {
++      proof_result r = check_goal (*iter);
++      if (r == invalid)
++        return r;
++      if (r == valid)
++        iter = p.discharge (iter);
++      else
++        ++iter;
++    }
++
++  /* If all goals are discharged, then the proof is valid.  */
++  if (p.empty())
++    return valid;
++  else
++    return undecided;
+ }
+ 
+-/* Extract the assumptions from the proof state S
+-   as a vector of vectors of atomic constraints. */
+-inline tree
+-extract_assumptions (proof_state& s)
++/*---------------------------------------------------------------------------
++                           Left logical rules
++---------------------------------------------------------------------------*/
++
++term_list::iterator
++load_check_assumption (term_list& ts, term_list::iterator i)
+ {
+-  tree result = make_tree_vec (s.size ());
+-  goal_iterator iter = s.begin ();
+-  goal_iterator end = s.end ();
+-  for (int n = 0; iter != end; ++iter, ++n)
+-    TREE_VEC_ELT (result, n) = extract_terms (iter->assumptions);
+-  return result;
++  tree decl = CHECK_CONSTR_CONCEPT (*i);
++  tree tmpl = DECL_TI_TEMPLATE (decl);
++  tree args = CHECK_CONSTR_ARGS (*i);
++  return ts.replace(i, expand_concept (tmpl, args));
+ }
+ 
+-} // namespace
++term_list::iterator
++load_parameterized_assumption (term_list& ts, term_list::iterator i)
++{
++  return ts.replace(i, PARM_CONSTR_OPERAND(*i));
++}
+ 
+-/* Decompose the required expression T into a constraint set: a
+-   vector of vectors containing only atomic propositions. If T is
+-   invalid, return an error. */
+-tree
+-decompose_assumptions (tree t)
++term_list::iterator
++load_conjunction_assumption (term_list& ts, term_list::iterator i)
+ {
+-  if (!t || t == error_mark_node)
+-    return t;
++  tree t1 = TREE_OPERAND (*i, 0);
++  tree t2 = TREE_OPERAND (*i, 1);
++  return ts.replace(i, t1, t2);
++}
+ 
+-  /* Create a proof state, and insert T as the sole assumption. */
+-  proof_state s;
+-  term_list &l = s.begin ()->assumptions;
+-  l.insert (t);
++/* Examine the terms in the list, and apply left-logical rules to move
++   terms into the set of assumptions. */
+ 
+-  /* Decompose the expression into a constraint set, and then
+-     extract the terms for the AST. */
+-  decompose_left (s);
+-  return extract_assumptions (s);
++void
++load_assumptions (proof_goal& g)
++{
++  term_list::iterator iter = g.assumptions.begin();
++  term_list::iterator end = g.assumptions.end();
++  while (iter != end)
++    {
++      switch (TREE_CODE (*iter))
++        {
++        case CHECK_CONSTR:
++          iter = load_check_assumption (g.assumptions, iter);
++          break;
++        case PARM_CONSTR:
++          iter = load_parameterized_assumption (g.assumptions, iter);
++          break;
++        case CONJ_CONSTR:
++          iter = load_conjunction_assumption (g.assumptions, iter);
++          break;
++        default:
++          ++iter;
++          break;
++        }
++    }
+ }
+ 
++/* In each subgoal, load constraints into the assumption set.  */
+ 
+-/*---------------------------------------------------------------------------
+-                           Subsumption Rules
+----------------------------------------------------------------------------*/
++void
++load_assumptions(proof_state& p)
++{
++  proof_state::iterator iter = p.begin();
++  while (iter != p.end())
++    {
++      load_assumptions (*iter);
++      ++iter;
++    }
++}
+ 
+-namespace {
++void
++explode_disjunction (proof_state& p, proof_state::iterator gi, term_list::iterator ti1)
++{
++  tree t1 = TREE_OPERAND (*ti1, 0);
++  tree t2 = TREE_OPERAND (*ti1, 1);
+ 
+-bool subsumes_constraint (tree, tree);
+-bool subsumes_conjunction (tree, tree);
+-bool subsumes_disjunction (tree, tree);
+-bool subsumes_parameterized_constraint (tree, tree);
+-bool subsumes_atomic_constraint (tree, tree);
++  /* Erase the current term from the goal. */
++  proof_goal& g1 = *gi;
++  proof_goal& g2 = *p.branch (gi);
+ 
+-/* Returns true if the assumption A matches the conclusion C. This
+-   is generally the case when A and C have the same syntax.
++  /* Get an iterator to the equivalent position in th enew goal. */
++  int n = std::distance (g1.assumptions.begin (), ti1);
++  term_list::iterator ti2 = g2.assumptions.begin ();
++  std::advance (ti2, n);
+ 
+-   NOTE: There will be specialized matching rules to accommodate
+-   type equivalence, conversion, inheritance, etc. But this is not
+-   in the current concepts draft. */
+-inline bool
+-match_terms (tree a, tree c)
+-{
+-  return cp_tree_equal (a, c);
++  /* Replace the disjunction in both branches. */
++  g1.assumptions.replace (ti1, t1);
++  g2.assumptions.replace (ti2, t2);
+ }
+ 
+-/* Returns true if the list of assumptions AS subsumes the atomic
+-   proposition C. This is the case when we can find a proposition
+-  in AS that entails the conclusion C. */
++
++/* Search the assumptions of the goal for the first disjunction. */
++
+ bool
+-subsumes_atomic_constraint (tree as, tree c)
++explode_goal (proof_state& p, proof_state::iterator gi)
+ {
+-  for (int i = 0; i < TREE_VEC_LENGTH (as); ++i)
+-    if (match_terms (TREE_VEC_ELT (as, i), c))
+-      return true;
++  term_list& ts = gi->assumptions;
++  term_list::iterator ti = ts.begin();
++  term_list::iterator end = ts.end();
++  while (ti != end)
++    {
++      if (TREE_CODE (*ti) == DISJ_CONSTR)
++        {
++          explode_disjunction (p, gi, ti);
++          return true;
++        }
++      else ++ti;
++    }
+   return false;
+ }
+ 
+-/* Returns true when both operands of C are subsumed by the
+-   assumptions AS. */
+-inline bool
+-subsumes_conjunction (tree as, tree c)
++/* Search for the first goal with a disjunction, and then branch
++   creating a clone of that subgoal. */
++
++void
++explode_assumptions (proof_state& p)
+ {
+-  tree l = TREE_OPERAND (c, 0);
+-  tree r = TREE_OPERAND (c, 1);
+-  return subsumes_constraint (as, l) && subsumes_constraint (as, r);
++  proof_state::iterator iter = p.begin();
++  proof_state::iterator end = p.end();
++  while (iter != end)
++    {
++      if (explode_goal (p, iter))
++        return;
++      ++iter;
++    }
+ }
+ 
+-/* Returns true when either operand of C is subsumed by the
+-   assumptions AS. */
+-inline bool
+-subsumes_disjunction (tree as, tree c)
++
++/*---------------------------------------------------------------------------
++                           Right logical rules
++---------------------------------------------------------------------------*/
++
++term_list::iterator
++load_disjunction_conclusion (term_list& g, term_list::iterator i)
+ {
+-  tree l = TREE_OPERAND (c, 0);
+-  tree r = TREE_OPERAND (c, 1);
+-  return subsumes_constraint (as, l) || subsumes_constraint (as, r);
++  tree t1 = TREE_OPERAND (*i, 0);
++  tree t2 = TREE_OPERAND (*i, 1);
++  return g.replace(i, t1, t2);
+ }
+ 
+-/* Returns true when the operand of C is subsumed by the
+-   assumptions in AS. The parameters are not considered in
+-   the subsumption rules. */
+-bool
+-subsumes_parameterized_constraint (tree as, tree c)
++/* Apply logical rules to the right hand side. This will load the
++   conclusion set with all tpp-level disjunctions.  */
++
++void
++load_conclusions (proof_goal& g)
+ {
+-  tree t = PARM_CONSTR_OPERAND (c);
+-  return subsumes_constraint (as, t);
++  term_list::iterator iter = g.conclusions.begin();
++  term_list::iterator end = g.conclusions.end();
++  while (iter != end)
++    {
++      if (TREE_CODE (*iter) == DISJ_CONSTR)
++        iter = load_disjunction_conclusion (g.conclusions, iter);
++      else
++        ++iter;
++    }
+ }
+ 
++void
++load_conclusions (proof_state& p)
++{
++  proof_state::iterator iter = p.begin();
++  while (iter != p.end())
++    {
++      load_conclusions (*iter);
++      ++iter;
++    }
++}
+ 
+-/* Returns true when the list of assumptions AS subsumes the
+-   concluded proposition C. This is a simple recursive descent
+-   on C, matching against propositions in the assumption list AS. */
++
++/*---------------------------------------------------------------------------
++                          High-level proof tactics
++---------------------------------------------------------------------------*/
++
++/* Given two constraints A and C, try to derive a proof that
++   A implies C.  */
++
+ bool
+-subsumes_constraint (tree as, tree c)
++prove_implication (tree a, tree c)
+ {
+-  switch (TREE_CODE (c))
++  /* Quick accept. */
++  if (cp_tree_equal (a, c))
++    return true;
++
++  /* Build the initial proof state. */
++  proof_state proof;
++  proof_goal& goal = proof.front();
++  goal.assumptions.push_back(a);
++  goal.conclusions.push_back(c);
++
++  /* Perform an initial right-expansion in the off-chance that the right
++     hand side contains disjunctions. */
++  load_conclusions (proof);
++
++  int step_max = 1 << 10;
++  int step_count = 0;              /* FIXME: We shouldn't have this. */
++  std::size_t branch_limit = 1024; /* FIXME: This needs to be configurable. */
++  while (step_count < step_max && proof.size() < branch_limit)
+     {
+-    case CONJ_CONSTR:
+-      return subsumes_conjunction (as, c);
+-    case DISJ_CONSTR:
+-      return subsumes_disjunction (as, c);
+-    case PARM_CONSTR:
+-      return subsumes_parameterized_constraint (as, c);
+-    default:
+-      return subsumes_atomic_constraint (as, c);
++      /* Determine if we can prove that the assumptions entail the
++         conclusions. If so, we're done. */
++      load_assumptions (proof);
++
++      /* Can we solve the proof based on this? */
++      proof_result r = check_proof (proof);
++      if (r != undecided)
++        return r == valid;
++
++      /* If not, then we need to dig into disjunctions.  */
++      explode_assumptions (proof);
++
++      ++step_count;
+     }
++
++  if (step_count == step_max)
++    error ("subsumption failed to resolve");
++
++  if (proof.size() == branch_limit)
++    error ("exceeded maximum number of branches");
++
++  return false;
+ }
+ 
+-/* Returns true if the LEFT constraints subsume the RIGHT constraints.
+-   This is done by checking that the RIGHT requirements follow from
+-   each of the LEFT subgoals. */
++/* Returns true if the LEFT constraint subsume the RIGHT constraints.
++   This is done by deriving a proof of the conclusions on the RIGHT
++   from the assumptions on the LEFT assumptions.  */
++
+ bool
+ subsumes_constraints_nonnull (tree left, tree right)
+ {
+@@ -469,20 +777,17 @@
+   gcc_assert (check_constraint_info (left));
+   gcc_assert (check_constraint_info (right));
+ 
+-  /* Check that the required expression in RIGHT is subsumed by each
+-     subgoal in the assumptions of LEFT. */
+-  tree as = CI_ASSUMPTIONS (left);
+-  tree c = CI_NORMALIZED_CONSTRAINTS (right);
+-  for (int i = 0; i < TREE_VEC_LENGTH (as); ++i)
+-    if (!subsumes_constraint (TREE_VEC_ELT (as, i), c))
+-      return false;
+-  return true;
++  auto_timevar time (TV_CONSTRAINT_SUB);
++  tree a = CI_ASSOCIATED_CONSTRAINTS (left);
++  tree c = CI_ASSOCIATED_CONSTRAINTS (right);
++  return prove_implication (a, c);
+ }
+ 
+ } /* namespace */
+ 
+ /* Returns true if the LEFT constraints subsume the RIGHT
+-   constraints. */
++   constraints.  */
++
+ bool
+ subsumes (tree left, tree right)
+ {
 Index: gcc/cp/ChangeLog
 ===================================================================
 --- a/src/gcc/cp/ChangeLog	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/cp/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,201 @@
+@@ -1,3 +1,497 @@
++2016-07-23  Jason Merrill  <jason at redhat.com>
++
++	PR c++/55922
++	PR c++/63151
++	* init.c (expand_aggr_init_1): Handle list-initialization from {}.
++
++	PR c++/70709
++	* class.c (walk_subobject_offsets): Handle 0-length array.
++
++	PR c++/70778
++	* pt.c (tsubst): Also substitute into the template of a
++	BOUND_TEMPLATE_TEMPLATE_PARM.
++
++	PR c++/71738
++	* pt.c (lookup_template_class_1): Handle getting template from tsubst.
++
++	PR c++/71350
++	* decl.c (reshape_init_r): Check complain for missing braces warning.
++
++2016-07-22  Jason Merrill  <jason at redhat.com>
++
++	PR c++/71748
++	PR c++/52746
++	* pt.c (tsubst_baselink): Call
++	adjust_result_of_qualified_name_lookup for unqualified
++	destructors.
++
++2016-07-21  Jason Merrill  <jason at redhat.com>
++
++	PR c++/69223
++	* semantics.c (apply_deduced_return_type): Call
++	complete_type_or_else before building the new RESULT_DECL.
++
++	PR c++/71630
++	* pt.c (instantiate_decl): Fix pattern_defined for namespace scope
++	variable templates.
++
++	PR c++/71913
++	* call.c (unsafe_copy_elision_p): It's OK to elide when
++	initializing an unknown object.
++
++2016-07-21  Jakub Jelinek  <jakub at redhat.com>
++
++	PR c++/71728
++	* constexpr.c (potential_constant_expression_1) <case GOTO_EXPR>:
++	Replace assert with test, return false if the goto isn't break
++	or continue.  Formatting fix.
++
++2016-07-21  Jakub Jelinek  <jakub at redhat.com>
++
++	PR c++/71941
++	* cp-gimplify.c (cp_genericize): For nested cp_genericize calls
++	save/restore bc_label array.
++
++2016-07-21  Patrick Palka  <ppalka at gcc.gnu.org>
++
++	PR c++/70822
++	PR c++/70106
++	* cp-tree.h (REF_PARENTHESIZED_P): Make this flag apply to
++	SCOPE_REFs too.
++	* pt.c (tsubst_qualified_id): If REF_PARENTHESIZED_P is set
++	on the qualified_id then propagate it to the resulting
++	expression.
++	(do_auto_deduction): Check REF_PARENTHESIZED_P on SCOPE_REFs
++	too.
++	* semantics.c (force_paren_expr): If given a SCOPE_REF, just set
++	its REF_PARENTHESIZED_P flag.
++
++2016-07-21  Andrew Sutton  <andrew.n.sutton at gmail.com>
++	    Jason Merrill  <jason at redhat.com>
++
++	Improving concepts performance and diagnostics.
++	PR c++/67565
++	PR c++/67579
++	PR c++/71843
++	* cp-tree.def (CHECK_CONSTR): New.
++	* cp-tree.h (CHECK_CONSTR_CONCEPT): New.
++	(CHECK_CONSTR_ARGS): New.
++	* constraint.cc (make_predicate_constraint): Remove in favor of
++	normalize_expression.
++	(resolve_constraint_check): Actually return error_mark_node when
++	resolution fails.
++	(resolve_variable_concept_check): Perform coercion as if processing
++	a template. Also return errors on resolution failure.
++	(lift_*): Remove all of these functions. Don't unnecessarily inline
++	concepts.
++	(learn_*): Add facilities to memoize implications for subsumption
++	during normalization.
++	(expanding_concept): New.
++	(expand_concept): New. Return the inlined and normalized definition
++	of a concept when needed.
++	(transform_*, xform_*): Rename to normalize_* to better reflect the
++	responsibility of those functions.
++	(normalize_template_id_expression): Check for non-boolean operands
++	when possible. Generate check constraints instead of normal variable
++	references.
++	(normalize_call_expression): Report errors when resolution fails.
++	(check_for_logical_overloads): Rewrite this check to more accurately
++	report the error.
++	(normalize_atom): Check for overloaded calls and invalid types before
++	determining if the expression refers to a concept.
++	(build_constraints): Don't cache normalized constraints or decomposed
++	assumptions.
++	(finish_shorthand_constraint): Return a normalized expression instead
++	of a predicate constraint.
++	(finish_template_introduction): Same.
++	(placeholder_extract_concept_and_args): Rewrite this since we only
++	ever get check constraints here.
++	(equivalent_placeholder_constraints): Rewrite in terms of check
++	constraints, and handle error_mark_nodes correctly.
++	(tsubst_check_constraint, tsubst_expr_constr, tsubst_type_constr)
++	(tsubst_implicit_conversion_constr)
++	(tsubst_argument_deduction_constr, tsubst_exception_constr)
++	(tsubst_parameterized_constraint, tsubst_constraint): New.
++	(tsbust_conjunection): Replace with tsubst_logical_operator and
++	actually generate the right kind of constraint.
++	(tsubst_requirement_body): Reverse the order of substituted arguments
++	so that they appear in the order written (helps diagnostics).
++	(satisfy_check_constraint): New.
++	(satisfy_conjunction): Simplify.
++	(satisfy_disjunction): Same.
++	(satisfy_constraint_1): Handle check constraints.
++	(eval_constr): New (private) global state.
++	(evaluating_constraints_sentinel): New. Manages eval_constr.
++	(satisfy_constraint): Add timing variables.
++	(satisfy_associated_constraints): Add hooks for memoization.
++	(evaluate_function_concept): Build a check constraint instead of
++	normalizing its definition.
++	(evaluate_variable_concept): Same.
++	(evaluate_constraint_expression): Normalize, but in the current
++	declaration processing context.
++	(evaluating_constraints_p): New.
++	(elide_constraint_failure_p): Actually emit constraint_thresh errors.
++	(diagnose_*): Remove artificial indentation. Add a new parameter to
++	each that tracks the current (complete) constraint prior to any
++	substitutions.
++	(diagnose_expression): Removed.
++	(diagnose_call_expression): Same.
++	(diagnose_template_id): Same.
++	(diagnose_template_id): New.
++	(diagnose_logical_constraint): New.
++	(diagnose_expression_constraint): Show the original expression.
++	(diagnose_type_constraint): Show the original type.
++	(diagnose_implicit_conversion_constraint): Be specific about
++	failures, don't re-diagnose a known-to-be-failed substitutions,
++	and manage elisions properly.
++	(diagnose_argument_deduction_constraint): Same.
++	(diagnose_exception_constraint): Same.
++	(diagnose_parameterized_constraint): Same.
++	(constraint_p): Allow EXPR_PACK_EXPANSION.
++	* logic.cc (next_by_distance): Removed. No longer used.
++	(any_p): Renamed from any_of.
++	(term_entry, term_hasher): New.
++	(term_list): Rewrite to include a hash table for quick lookup.
++	Also, make less stateful.
++	(proof_state): Extend to allow goals to be discharged once
++	satisfied.
++	(non_atomic_constraint_p): New.
++	(any_non_atomic_constraints_p): New.
++	(...rest...): Previous implementation completely replaced with an
++	iterative algorithm that opportunistically prunes the search space
++	before committing to using more memory.
++	* parser.c: (cp_parser_type_parameter): Normalize constraints.
++	(cp_parser_explicit_template_declaration): Same.
++	* pt.c: (finish_template_variable): Be less redundant with this error
++	message.
++	(template_args_equal): No longer static.
++	(tsubst_decl): Don't try to find specializations of variables that
++	have already been instantiated.
++	(build_non_dependent_expr): Avoid infinite recursion during concept
++	expansion.
++	(make_constrained_auto): Normalize constraints.
++	(do_auto_deduction): When doing auto deduction from a
++	partial-concept-id, be sure to include the explicit args checking
++	the constraints.
++	(constraint_sat_*): New. Memoize satisfied constraints.
++	(concept_spec_*): New. Memoize expressions associated with a concept
++	specialization.
++	(constraint_memos, concept_memos): New.
++	(lookup_constraint_satisfaction, memoize_constraint_satisfaction): New.
++	(lookup_concept_satisfaction, memoize_concept_satisfaction): New.
++	(get_concept_expansion, save_concept_expansion): New.
++	(hash_subsumption_args): New.
++	(comp_subsumption_args): New.
++	(subsumption_*): New. Memoize parts of the subsumption relation.
++	(lookup_subsumption_result, save_subsumption_result): New.
++	(init_constraint_processing): Initialize memo tables.
++	(get_constraints): Shortcut if !flag_concepts.
++	* decl.c (grokfndecl): Normalize constraints.
++	* error.c (dump_simple_decl): Print "concept" when appropriate.
++	(dump_function_decl): Same.
++	(dump_template_decl): Don't write requirements when we're not
++	printing the header.
++	(dump_expr): Handle fold expressions.
++	* cxx-pretty-print.c (cxx_pretty_printer::expression): Handle
++	fold expressions.
++	(get_fold_operator): New.
++	(pp_cxx_unary_left_fold_expression): New.
++	(pp_cxx_unary_right_fold_expression): New.
++	(pp_cxx_binary_fold_expression): New.
++	(pp_cxx_check_constraint): New.
++	(pp_cxx_*_constraint): Rewrite the grammar of internal constraints
++	to make them easier to read when debugging.
++	* search.c (accessible_p): Don't shortcut when evaluating constraints.
++	* tree.c (cp_tree_equal): Handle CHECK_CONSTR.
++
++2016-07-21  Jason Merrill  <jason at redhat.com>
++
++	PR c++/70781
++	* parser.c (cp_parser_lambda_expression): Unset OK if there was an
++	error parsing the lambda-declarator.
++
++	PR c++/71896
++	* constexpr.c (cxx_eval_binary_expression): Handle comparison
++	between lowered and unlowered PTRMEM_CST.
++
++	PR c++/71092
++	* constexpr.c (cxx_eval_call_expression): Fail quietly when cgraph
++	threw away DECL_SAVED_TREE.
++
++	PR c++/71117
++	Core 2189
++	* call.c (add_template_conv_candidate): Disable if there are
++	viable candidates.
++
++	PR c++/71495
++	* call.c (convert_like_real): Mask complain.
++
++	PR c++/71511
++	* typeck2.c (cxx_incomplete_type_diagnostic): Handle DECLTYPE_TYPE.
++
++	PR c++/71513
++	* pt.c (tsubst_attributes): Fix loop logic.
++
++	PR c++/71604
++	PR c++/54430
++	* parser.c (cp_parser_range_for): Modify IDENTIFIER_BINDING directly.
++	(cp_parser_simple_declaration): Diagnose type definition in
++	for-range-declaration.
++
++	PR c++/71711
++	* operators.def: Add *_FOLD_EXPR.
++	* cp-tree.h (FOLD_EXPR_P): Parenthesize.
++	* mangle.c (write_expression): Handle fold-expressions.
++	* pt.c (tsubst_unary_left_fold, tsubst_binary_left_fold)
++	(tsubst_unary_right_fold, tsubst_binary_right_fold): Handle
++	partial instantiation.
++
++	PR c++/71814
++	* mangle.c (write_expression): Handle sizeof... an argument pack.
++
++	PR c++/71718
++	* pt.c (push_tinst_level_loc): Set at_eof before fatal_error.
++
++	PR c++/70824
++	* init.c (constant_value_1): Don't instantiated DECL_INITIAL of
++	artificial variables.
++
++	* lambda.c (maybe_add_lambda_conv_op): Fix null object argument.
++
++2016-07-20  Jakub Jelinek  <jakub at redhat.com>
++
++	PR c++/71909
++	* parser.c (cp_parser_save_member_function_body): Consume
++	__transaction_relaxed or __transaction_atomic with optional
++	attribute.  Only skip catch with block if try keyword is seen.
++
++2016-07-19  Jakub Jelinek  <jakub at redhat.com>
++
++	Backported from mainline
++	2016-07-18  Jakub Jelinek  <jakub at redhat.com>
++
++	PR c++/71835
++	* call.c (build_op_call_1): Use convert_like_with_context only
++	if cand->fn is a decl.
++
++	PR c++/71828
++	* constexpr.c (cxx_eval_constant_expression) <case REALPART_EXPR>:
++	For lval don't use cxx_eval_unary_expression and instead recurse
++	and if needed rebuild the reference.
++
++	PR c++/71822
++	* cp-gimplify.c (cp_gimplify_expr) <case VEC_INIT_EXPR>: Recursively
++	fold *expr_p before genericizing it.
++
++	PR c++/71871
++	* typeck.c (build_x_conditional_expr): Revert the 2012-10-25 change.
++
++	2016-07-07  Jakub Jelinek  <jakub at redhat.com>
++		    Kai Tietz  <ktietz70 at googlemail.com>
++
++	PR c++/70869
++	PR c++/71054
++	* cp-gimplify.c (cp_genericize_r): For DECL_EXPR for non-static
++	artificial vars, genericize their initializers.
++
 +2016-06-21  Jakub Jelinek  <jakub at redhat.com>
 +
 +	Backported from mainline
@@ -18719,7 +26719,16 @@ Index: gcc/cp/cp-gimplify.c
 ===================================================================
 --- a/src/gcc/cp/cp-gimplify.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/cp/cp-gimplify.c	(.../branches/gcc-6-branch)
-@@ -939,6 +939,17 @@
+@@ -592,6 +592,8 @@
+ 				  init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
+ 				  from_array,
+ 				  tf_warning_or_error);
++	hash_set<tree> pset;
++	cp_walk_tree (expr_p, cp_fold_r, &pset, NULL);
+ 	cp_genericize_tree (expr_p);
+ 	ret = GS_OK;
+ 	input_location = loc;
+@@ -939,6 +941,17 @@
  
    *stmt_p = stmt = cp_fold (*stmt_p);
  
@@ -18737,7 +26746,7 @@ Index: gcc/cp/cp-gimplify.c
    code = TREE_CODE (stmt);
    if (code == OMP_FOR || code == OMP_SIMD || code == OMP_DISTRIBUTE
        || code == OMP_TASKLOOP || code == CILK_FOR || code == CILK_SIMD
-@@ -996,7 +1007,8 @@
+@@ -996,7 +1009,8 @@
  void
  cp_fold_function (tree fndecl)
  {
@@ -18747,7 +26756,47 @@ Index: gcc/cp/cp-gimplify.c
  }
  
  /* Perform any pre-gimplification lowering of C++ front end trees to
-@@ -1877,13 +1889,21 @@
+@@ -1266,7 +1280,15 @@
+     {
+       tree d = DECL_EXPR_DECL (stmt);
+       if (TREE_CODE (d) == VAR_DECL)
+-	gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
++	{
++	  gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
++	  /* User var initializers should be genericized during containing
++	     BIND_EXPR genericization when walk_tree walks DECL_INITIAL
++	     of BIND_EXPR_VARS.  Artificial temporaries might not be
++	     mentioned there though, so walk them now.  */
++	  if (DECL_ARTIFICIAL (d) && !TREE_STATIC (d) && DECL_INITIAL (d))
++	    cp_walk_tree (&DECL_INITIAL (d), cp_genericize_r, data, NULL);
++	}
+     }
+   else if (TREE_CODE (stmt) == OMP_PARALLEL
+ 	   || TREE_CODE (stmt) == OMP_TASK
+@@ -1547,6 +1569,13 @@
+   if (DECL_CLONED_FUNCTION_P (fndecl))
+     return;
+ 
++  /* Allow cp_genericize calls to be nested.  */
++  tree save_bc_label[2];
++  save_bc_label[bc_break] = bc_label[bc_break];
++  save_bc_label[bc_continue] = bc_label[bc_continue];
++  bc_label[bc_break] = NULL_TREE;
++  bc_label[bc_continue] = NULL_TREE;
++
+   /* Expand all the array notations here.  */
+   if (flag_cilkplus 
+       && contains_array_notation_expr (DECL_SAVED_TREE (fndecl)))
+@@ -1566,6 +1595,8 @@
+ 
+   gcc_assert (bc_label[bc_break] == NULL);
+   gcc_assert (bc_label[bc_continue] == NULL);
++  bc_label[bc_break] = save_bc_label[bc_break];
++  bc_label[bc_continue] = save_bc_label[bc_continue];
+ }
+ 

+ /* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
+@@ -1877,13 +1908,21 @@
  static tree
  cp_fold_maybe_rvalue (tree x, bool rval)
  {
@@ -18774,7 +26823,7 @@ Index: gcc/cp/cp-gimplify.c
  }
  
  /* Fold expression X which is used as an rvalue.  */
-@@ -1995,6 +2015,15 @@
+@@ -1995,6 +2034,15 @@
  
        break;
  
@@ -18790,7 +26839,7 @@ Index: gcc/cp/cp-gimplify.c
      case ADDR_EXPR:
      case REALPART_EXPR:
      case IMAGPART_EXPR:
-@@ -2007,7 +2036,7 @@
+@@ -2007,7 +2055,7 @@
      case BIT_NOT_EXPR:
      case TRUTH_NOT_EXPR:
      case FIXED_CONVERT_EXPR:
@@ -18799,7 +26848,7 @@ Index: gcc/cp/cp-gimplify.c
  
        loc = EXPR_LOCATION (x);
        op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
-@@ -2017,7 +2046,16 @@
+@@ -2017,7 +2065,16 @@
  	  if (op0 == error_mark_node)
  	    x = error_mark_node;
  	  else
@@ -18817,7 +26866,7 @@ Index: gcc/cp/cp-gimplify.c
  	}
        else
  	x = fold (x);
-@@ -2294,7 +2332,12 @@
+@@ -2294,7 +2351,12 @@
  	      || op3 == error_mark_node)
  	    x = error_mark_node;
  	  else
@@ -18831,11 +26880,327 @@ Index: gcc/cp/cp-gimplify.c
  	}
  
        x = fold (x);
+Index: gcc/cp/cxx-pretty-print.c
+===================================================================
+--- a/src/gcc/cp/cxx-pretty-print.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/cxx-pretty-print.c	(.../branches/gcc-6-branch)
+@@ -35,6 +35,9 @@
+ static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
+ static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
+ static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
++static void pp_cxx_unary_left_fold_expression (cxx_pretty_printer *, tree);
++static void pp_cxx_unary_right_fold_expression (cxx_pretty_printer *, tree);
++static void pp_cxx_binary_fold_expression (cxx_pretty_printer *, tree);
+ 

+ 
+ static inline void
+@@ -1140,6 +1143,19 @@
+       pp_cxx_ws_string (this, "...");
+       break;
+ 
++    case UNARY_LEFT_FOLD_EXPR:
++      pp_cxx_unary_left_fold_expression (this, t);
++      break;
++
++    case UNARY_RIGHT_FOLD_EXPR:
++      pp_cxx_unary_right_fold_expression (this, t);
++    break;
++
++    case BINARY_LEFT_FOLD_EXPR:
++    case BINARY_RIGHT_FOLD_EXPR:
++      pp_cxx_binary_fold_expression (this, t);
++      break;
++
+     case TEMPLATE_ID_EXPR:
+       pp_cxx_template_id (this, t);
+       break;
+@@ -1166,6 +1182,7 @@
+       break;
+ 
+     case PRED_CONSTR:
++    case CHECK_CONSTR:
+     case EXPR_CONSTR:
+     case TYPE_CONSTR:
+     case ICONV_CONSTR:
+@@ -2199,6 +2216,11 @@
+ pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
+ {
+   tree t, a;
++  if (c == error_mark_node)
++    {
++      pp_cxx_ws_string(pp, "<unsatisfied-constrained-placeholder>");
++      return;
++    }
+   placeholder_extract_concept_and_args (c, t, a);
+   pp->id_expression (t);
+   if (TREE_VEC_LENGTH (a) > 1)
+@@ -2408,7 +2430,103 @@
+   pp_cxx_right_paren (pp);
+ }
+ 
++static char const*
++get_fold_operator (tree t)
++{
++  int op = int_cst_value (FOLD_EXPR_OP (t));
++  if (FOLD_EXPR_MODIFY_P (t))
++    {
++      switch (op)
++        {
++        case NOP_EXPR: return "=";
++        case PLUS_EXPR: return "+=";
++        case MINUS_EXPR: return "-=";
++        case MULT_EXPR: return "*=";
++        case TRUNC_DIV_EXPR: return "/=";
++        case TRUNC_MOD_EXPR: return "%=";
++        case BIT_XOR_EXPR: return "^=";
++        case BIT_AND_EXPR: return "&=";
++        case BIT_IOR_EXPR: return "|=";
++        case LSHIFT_EXPR: return "<<=";
++        case RSHIFT_EXPR: return ">>=";
++        default: gcc_unreachable ();
++        }
++    }
++  else
++    {
++      switch (op)
++        {
++        case PLUS_EXPR: return "+";
++        case MINUS_EXPR: return "-";
++        case MULT_EXPR: return "*";
++        case TRUNC_DIV_EXPR: return "/";
++        case TRUNC_MOD_EXPR: return "%";
++        case BIT_XOR_EXPR: return "^";
++        case BIT_AND_EXPR: return "&";
++        case BIT_IOR_EXPR: return "|";
++        case LSHIFT_EXPR: return "<<";
++        case RSHIFT_EXPR: return ">>";
++        case EQ_EXPR: return "==";
++        case NE_EXPR: return "!=";
++        case LT_EXPR: return "<";
++        case GT_EXPR: return ">";
++        case LE_EXPR: return "<=";
++        case GE_EXPR: return ">=";
++        case TRUTH_ANDIF_EXPR: return "&&";
++        case TRUTH_ORIF_EXPR: return "||";
++        case MEMBER_REF: return "->*";
++        case DOTSTAR_EXPR: return ".*";
++        case OFFSET_REF: return ".*";
++        default: return ","; /* FIXME: Not the right default.  */
++        }
++    }
++}
++
+ void
++pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
++{
++  char const* op = get_fold_operator (t);
++  tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
++  pp_cxx_left_paren (pp);
++  pp_cxx_ws_string (pp, "...");
++  pp_cxx_ws_string (pp, op);
++  pp->expression (expr);
++  pp_cxx_right_paren (pp);
++}
++
++void
++pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
++{
++  char const* op = get_fold_operator (t);
++  tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
++  pp_cxx_left_paren (pp);
++  pp->expression (expr);
++  pp_space (pp);
++  pp_cxx_ws_string (pp, op);
++  pp_cxx_ws_string (pp, "...");
++  pp_cxx_right_paren (pp);
++}
++
++void
++pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
++{
++  char const* op = get_fold_operator (t);
++  tree t1 = TREE_OPERAND (t, 1);
++  tree t2 = TREE_OPERAND (t, 2);
++  if (t1 == FOLD_EXPR_PACK (t))
++    t1 = PACK_EXPANSION_PATTERN (t1);
++  else
++    t2 = PACK_EXPANSION_PATTERN (t2);
++  pp_cxx_left_paren (pp);
++  pp->expression (t1);
++  pp_cxx_ws_string (pp, op);
++  pp_cxx_ws_string (pp, "...");
++  pp_cxx_ws_string (pp, op);
++  pp->expression (t2);
++  pp_cxx_right_paren (pp);
++}
++
++void
+ pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
+ {
+   cp_trait_kind kind = TRAIT_EXPR_KIND (t);
+@@ -2618,6 +2736,7 @@
+       pp_cxx_ws_string (pp, "->");
+       pp->type_id (type);
+     }
++  pp_cxx_semicolon (pp);
+ }
+ 
+ /* nested requirement:
+@@ -2633,50 +2752,70 @@
+ void
+ pp_cxx_predicate_constraint (cxx_pretty_printer *pp, tree t)
+ {
+-  pp_string (pp, "predicate");
+-  pp_left_paren (pp);
+   pp->expression (TREE_OPERAND (t, 0));
+-  pp_right_paren (pp);
+ }
+ 
+ void
++pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
++{
++  tree decl = CHECK_CONSTR_CONCEPT (t);
++  tree tmpl = DECL_TI_TEMPLATE (decl);
++  tree args = CHECK_CONSTR_ARGS (t);
++  tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
++
++  if (TREE_CODE (decl) == VAR_DECL)
++    pp->expression (id);
++  else if (TREE_CODE (decl) == FUNCTION_DECL)
++    {
++      tree call = build_vl_exp (CALL_EXPR, 2);
++      TREE_OPERAND (call, 0) = integer_two_node;
++      TREE_OPERAND (call, 1) = id;
++      pp->expression (call);
++    }
++  else
++    gcc_unreachable ();
++}
++
++void
+ pp_cxx_expression_constraint (cxx_pretty_printer *pp, tree t)
+ {
+-  pp_string (pp, "valid_expr");
+-  pp_left_paren (pp);
++  pp_string (pp, "<valid-expression ");
++  pp_cxx_left_paren (pp);
+   pp->expression (TREE_OPERAND (t, 0));
+-  pp_right_paren (pp);
++  pp_cxx_right_paren (pp);
++  pp_string (pp, ">");
+ }
+ 
+ void
+ pp_cxx_type_constraint (cxx_pretty_printer *pp, tree t)
+ {
+-  pp_string (pp, "valid_type");
+-  pp_left_paren (pp);
++  pp_string (pp, "<valid-type ");
+   pp->type_id (TREE_OPERAND (t, 0));
+-  pp_right_paren (pp);
++  pp_string (pp, ">");
+ }
+ 
+ void
+ pp_cxx_implicit_conversion_constraint (cxx_pretty_printer *pp, tree t)
+ {
+-  pp_string (pp, "convertible");
+-  pp_left_paren (pp);
++  pp_string (pp, "<implicitly-conversion ");
++  pp_cxx_left_paren (pp);
+   pp->expression (ICONV_CONSTR_EXPR (t));
+-  pp_cxx_separate_with (pp, ',');
+-  pp->expression (ICONV_CONSTR_TYPE (t));
+-  pp_right_paren (pp);
++  pp_cxx_right_paren (pp);
++  pp_cxx_ws_string (pp, "to");
++  pp->type_id (ICONV_CONSTR_TYPE (t));
++  pp_string (pp, ">");
+ }
+ 
+ void
+ pp_cxx_argument_deduction_constraint (cxx_pretty_printer *pp, tree t)
+ {
+-  pp_string (pp, "deducible");
+-  pp_left_paren (pp);
++  pp_string (pp, "<argument-deduction ");
++  pp_cxx_left_paren (pp);
+   pp->expression (DEDUCT_CONSTR_EXPR (t));
+-  pp_cxx_separate_with (pp, ',');
++  pp_cxx_right_paren (pp);
++  pp_cxx_ws_string (pp, "as");
+   pp->expression (DEDUCT_CONSTR_PATTERN (t));
+-  pp_right_paren (pp);
++  pp_string (pp, ">");
+ }
+ 
+ void
+@@ -2683,9 +2822,10 @@
+ pp_cxx_exception_constraint (cxx_pretty_printer *pp, tree t)
+ {
+   pp_cxx_ws_string (pp, "noexcept");
+-  pp_left_paren (pp);
++  pp_cxx_whitespace (pp);
++  pp_cxx_left_paren (pp);
+   pp->expression (TREE_OPERAND (t, 0));
+-  pp_right_paren (pp);
++  pp_cxx_right_paren (pp);
+ }
+ 
+ void
+@@ -2692,15 +2832,14 @@
+ pp_cxx_parameterized_constraint (cxx_pretty_printer *pp, tree t)
+ {
+   pp_left_paren (pp);
+-  pp_string (pp, "forall");
++  pp_string (pp, "<requires ");
+   if (tree parms = PARM_CONSTR_PARMS (t))
+     {
+-      if (parms)
+ 	pp_cxx_parameter_declaration_clause (pp, parms);
+       pp_cxx_whitespace (pp);
+     }
+   pp_cxx_constraint (pp, PARM_CONSTR_OPERAND (t));
+-  pp_right_paren (pp);
++  pp_string (pp, ">");
+ }
+ 
+ void
+@@ -2731,6 +2870,10 @@
+       pp_cxx_predicate_constraint (pp, t);
+       break;
+ 
++    case CHECK_CONSTR:
++      pp_cxx_check_constraint (pp, t);
++      break;
++
+     case EXPR_CONSTR:
+       pp_cxx_expression_constraint (pp, t);
+       break;
+@@ -2763,6 +2906,10 @@
+       pp_cxx_disjunction (pp, t);
+       break;
+ 
++    case EXPR_PACK_EXPANSION:
++      pp->expression (TREE_OPERAND (t, 0));
++      break;
++
+     default:
+       gcc_unreachable ();
+     }
 Index: gcc/cp/typeck2.c
 ===================================================================
 --- a/src/gcc/cp/typeck2.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/cp/typeck2.c	(.../branches/gcc-6-branch)
-@@ -951,10 +951,12 @@
+@@ -539,6 +539,7 @@
+       break;
+ 
+     case TYPENAME_TYPE:
++    case DECLTYPE_TYPE:
+       emit_diagnostic (diag_kind, loc, 0,
+ 		       "invalid use of dependent type %qT", type);
+       break;
+@@ -951,10 +952,12 @@
  	{
  	  if (complain & tf_warning_or_error)
  	    {
@@ -18864,7 +27229,15 @@ Index: gcc/cp/pt.c
  static tree most_specialized_partial_spec (tree, tsubst_flags_t);
  static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
  static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree);
-@@ -2808,6 +2807,13 @@
+@@ -196,7 +195,6 @@
+ static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
+ 					   tree, tree);
+ static bool template_template_parm_bindings_ok_p (tree, tree);
+-static int template_args_equal (tree, tree);
+ static void tsubst_default_arguments (tree, tsubst_flags_t);
+ static tree for_each_template_parm_r (tree *, int *, void *);
+ static tree copy_default_args_to_explicit_spec_1 (tree, tree);
+@@ -2808,6 +2806,13 @@
  		 context.  */
  	      fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname,
  					   false, true);
@@ -18878,7 +27251,7 @@ Index: gcc/cp/pt.c
  	      if (fns == error_mark_node || !is_overloaded_fn (fns))
  		{
  		  error ("%qD is not a template function", dname);
-@@ -2953,6 +2959,15 @@
+@@ -2953,6 +2958,15 @@
  					   CP_DECL_CONTEXT (tmpl)))
  	    error ("%qD is not declared in %qD",
  		   tmpl, current_namespace);
@@ -18894,7 +27267,45 @@ Index: gcc/cp/pt.c
  
  	  tree gen_tmpl = most_general_template (tmpl);
  
-@@ -9554,7 +9569,7 @@
+@@ -7823,7 +7837,7 @@
+ 
+ /* Returns 1 if template args OT and NT are equivalent.  */
+ 
+-static int
++int
+ template_args_equal (tree ot, tree nt)
+ {
+   if (nt == ot)
+@@ -8580,7 +8594,9 @@
+ 	     for parameters in the TYPE_DECL of the alias template
+ 	     done earlier.  So be careful while getting the template
+ 	     of FOUND.  */
+-	  found = TREE_CODE (found) == TYPE_DECL
++	  found = TREE_CODE (found) == TEMPLATE_DECL
++	    ? found
++	    : TREE_CODE (found) == TYPE_DECL
+ 	    ? TYPE_TI_TEMPLATE (TREE_TYPE (found))
+ 	    : CLASSTYPE_TI_TEMPLATE (found);
+ 	}
+@@ -8680,7 +8696,7 @@
+     {
+       if (complain & tf_error)
+ 	{
+-	  error ("constraints for %qD not satisfied", templ);
++	  error ("use of invalid variable template %qE", var);
+ 	  diagnose_constraints (location_of (var), templ, arglist);
+ 	}
+       return error_mark_node;
+@@ -9071,6 +9087,8 @@
+ 
+   if (tinst_depth >= max_tinst_depth)
+     {
++      /* Tell error.c not to try to instantiate any templates.  */
++      at_eof = 2;
+       fatal_error (input_location,
+ 		   "template instantiation depth exceeds maximum of %d"
+                    " (use -ftemplate-depth= to increase the maximum)",
+@@ -9554,7 +9572,7 @@
      return 0;
    else if (COMPLETE_TYPE_P (type))
      return 1;
@@ -18903,7 +27314,39 @@ Index: gcc/cp/pt.c
      return can_complete_type_without_circularity (TREE_TYPE (type));
    else if (CLASS_TYPE_P (type)
  	   && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type)))
-@@ -10118,17 +10133,12 @@
+@@ -9649,20 +9667,23 @@
+       }
+ 
+   if (last_dep)
+-    for (tree *p = &attributes; *p; p = &TREE_CHAIN (*p))
++    for (tree *p = &attributes; *p; )
+       {
+ 	tree t = *p;
+ 	if (ATTR_IS_DEPENDENT (t))
+ 	  {
+ 	    tree subst = tsubst_attribute (t, NULL, args, complain, in_decl);
+-	    if (subst == t)
+-	      continue;
+-	    *p = subst;
+-	    do
+-	      p = &TREE_CHAIN (*p);
+-	    while (*p);
+-	    *p = TREE_CHAIN (t);
++	    if (subst != t)
++	      {
++		*p = subst;
++		do
++		  p = &TREE_CHAIN (*p);
++		while (*p);
++		*p = TREE_CHAIN (t);
++		continue;
++	      }
+ 	  }
++	p = &TREE_CHAIN (*p);
+       }
+ 
+   return attributes;
+@@ -10118,17 +10139,12 @@
  			  if (can_complete_type_without_circularity (rtype))
  			    complete_type (rtype);
  
@@ -18926,7 +27369,63 @@ Index: gcc/cp/pt.c
  			      cxx_incomplete_type_error (r, rtype);
  			      TREE_TYPE (r) = error_mark_node;
  			    }
-@@ -12285,6 +12295,14 @@
+@@ -10732,6 +10748,12 @@
+   tree pack = tsubst_fold_expr_pack (t, args, complain, in_decl);
+   if (pack == error_mark_node)
+     return error_mark_node;
++  if (PACK_EXPANSION_P (pack))
++    {
++      tree r = copy_node (t);
++      FOLD_EXPR_PACK (r) = pack;
++      return r;
++    }
+   if (TREE_VEC_LENGTH (pack) == 0)
+     return expand_empty_fold (t, complain);
+   else
+@@ -10754,6 +10776,14 @@
+   if (init == error_mark_node)
+     return error_mark_node;
+ 
++  if (PACK_EXPANSION_P (pack))
++    {
++      tree r = copy_node (t);
++      FOLD_EXPR_PACK (r) = pack;
++      FOLD_EXPR_INIT (r) = init;
++      return r;
++    }
++
+   tree vec = make_tree_vec (TREE_VEC_LENGTH (pack) + 1);
+   TREE_VEC_ELT (vec, 0) = init;
+   for (int i = 0; i < TREE_VEC_LENGTH (pack); ++i)
+@@ -10795,6 +10825,12 @@
+   tree pack = tsubst_fold_expr_pack (t, args, complain, in_decl);
+   if (pack == error_mark_node)
+     return error_mark_node;
++  if (PACK_EXPANSION_P (pack))
++    {
++      tree r = copy_node (t);
++      FOLD_EXPR_PACK (r) = pack;
++      return r;
++    }
+   if (TREE_VEC_LENGTH (pack) == 0)
+     return expand_empty_fold (t, complain);
+   else
+@@ -10817,6 +10853,14 @@
+   if (init == error_mark_node)
+     return error_mark_node;
+ 
++  if (PACK_EXPANSION_P (pack))
++    {
++      tree r = copy_node (t);
++      FOLD_EXPR_PACK (r) = pack;
++      FOLD_EXPR_INIT (r) = init;
++      return r;
++    }
++
+   int n = TREE_VEC_LENGTH (pack);
+   tree vec = make_tree_vec (n + 1);
+   for (int i = 0; i < n; ++i)
+@@ -12285,6 +12329,14 @@
  	    local_p = true;
  	    /* Subsequent calls to pushdecl will fill this in.  */
  	    ctx = NULL_TREE;
@@ -18941,7 +27440,75 @@ Index: gcc/cp/pt.c
  	    spec = retrieve_local_specialization (t);
  	  }
  	/* If we already have the specialization we need, there is
-@@ -13996,7 +14014,8 @@
+@@ -13151,13 +13203,20 @@
+ 
+ 		if (code == BOUND_TEMPLATE_TEMPLATE_PARM)
+ 		  {
+-		    tree argvec = tsubst (TYPE_TI_ARGS (t), args,
++		    tree tinfo = TYPE_TEMPLATE_INFO (t);
++		    /* We might need to substitute into the types of non-type
++		       template parameters.  */
++		    tree tmpl = tsubst (TI_TEMPLATE (tinfo), args,
++					complain, in_decl);
++		    if (tmpl == error_mark_node)
++		      return error_mark_node;
++		    tree argvec = tsubst (TI_ARGS (tinfo), args,
+ 					  complain, in_decl);
+ 		    if (argvec == error_mark_node)
+ 		      return error_mark_node;
+ 
+ 		    TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
+-		      = build_template_info (TYPE_TI_TEMPLATE (t), argvec);
++		      = build_template_info (tmpl, argvec);
+ 		  }
+ 	      }
+ 	    break;
+@@ -13678,10 +13737,17 @@
+     if (!object_type)
+       object_type = current_class_type;
+ 
+-    if (qualified)
+-      baselink = adjust_result_of_qualified_name_lookup (baselink,
+-							 qualifying_scope,
+-							 object_type);
++    if (qualified || name == complete_dtor_identifier)
++      {
++	baselink = adjust_result_of_qualified_name_lookup (baselink,
++							   qualifying_scope,
++							   object_type);
++	if (!qualified)
++	  /* We need to call adjust_result_of_qualified_name_lookup in case the
++	     destructor names a base class, but we unset BASELINK_QUALIFIED_P
++	     so that we still get virtual function binding.  */
++	  BASELINK_QUALIFIED_P (baselink) = false;
++      }
+     return baselink;
+ }
+ 
+@@ -13740,8 +13806,10 @@
+     {
+       if (is_template)
+ 	expr = build_min_nt_loc (loc, TEMPLATE_ID_EXPR, expr, template_args);
+-      return build_qualified_name (NULL_TREE, scope, expr,
+-				   QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
++      tree r = build_qualified_name (NULL_TREE, scope, expr,
++				     QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
++      REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (qualified_id);
++      return r;
+     }
+ 
+   if (!BASELINK_P (name) && !DECL_P (expr))
+@@ -13821,6 +13889,9 @@
+       && TREE_CODE (expr) != OFFSET_REF)
+     expr = convert_from_reference (expr);
+ 
++  if (REF_PARENTHESIZED_P (qualified_id))
++    expr = force_paren_expr (expr);
++
+   return expr;
+ }
+ 
+@@ -13996,7 +14067,8 @@
      case FUNCTION_DECL:
        if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
  	r = tsubst (t, args, complain, in_decl);
@@ -18951,7 +27518,7 @@ Index: gcc/cp/pt.c
  	{
  	  r = retrieve_local_specialization (t);
  	  if (r == NULL_TREE)
-@@ -14040,14 +14059,9 @@
+@@ -14040,14 +14112,9 @@
  		  gcc_assert (cp_unevaluated_operand || TREE_STATIC (r)
  			      || decl_constant_var_p (r)
  			      || errorcount || sorrycount);
@@ -18969,7 +27536,7 @@ Index: gcc/cp/pt.c
  		}
  	      /* Remember this for subsequent uses.  */
  	      if (local_specializations)
-@@ -14145,7 +14159,8 @@
+@@ -14145,7 +14212,8 @@
  	      len = TREE_VEC_LENGTH (expanded);
  	      /* Set TREE_USED for the benefit of -Wunused.  */
  	      for (int i = 0; i < len; i++)
@@ -18979,7 +27546,7 @@ Index: gcc/cp/pt.c
  	    }
  
  	  if (expanded == error_mark_node)
-@@ -17376,6 +17391,7 @@
+@@ -17376,6 +17444,7 @@
  
    tree pattern = DECL_TEMPLATE_RESULT (gen_tmpl);
  
@@ -18987,7 +27554,7 @@ Index: gcc/cp/pt.c
    if (VAR_P (pattern))
      {
        /* We need to determine if we're using a partial or explicit
-@@ -17387,14 +17403,16 @@
+@@ -17387,14 +17456,16 @@
  	pattern = error_mark_node;
        else if (elt)
  	{
@@ -19008,7 +27575,7 @@ Index: gcc/cp/pt.c
    if (DECL_CLASS_SCOPE_P (gen_tmpl))
      pop_nested_class ();
    pop_from_top_level ();
-@@ -20848,36 +20866,6 @@
+@@ -20848,36 +20919,6 @@
    return decl;
  }
  
@@ -19045,7 +27612,7 @@ Index: gcc/cp/pt.c
  /* Return the most specialized of the template partial specializations
     which can produce TARGET, a specialization of some class or variable
     template.  The value returned is actually a TREE_LIST; the TREE_VALUE is
-@@ -21379,14 +21367,12 @@
+@@ -21379,14 +21420,12 @@
     to instantiate the DECL, we regenerate it.  */
  
  static void
@@ -19061,7 +27628,7 @@ Index: gcc/cp/pt.c
    code_pattern = DECL_TEMPLATE_RESULT (tmpl);
  
    /* Make sure that we can see identifiers, and compute access
-@@ -21702,7 +21688,7 @@
+@@ -21702,7 +21741,7 @@
      return d;
  
    gen_tmpl = most_general_template (tmpl);
@@ -19070,7 +27637,7 @@ Index: gcc/cp/pt.c
  
    if (tmpl != gen_tmpl)
      /* We should already have the extra args.  */
-@@ -21721,6 +21707,20 @@
+@@ -21721,6 +21760,20 @@
    /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
       for the instantiation.  */
    td = template_for_substitution (d);
@@ -19091,7 +27658,7 @@ Index: gcc/cp/pt.c
    code_pattern = DECL_TEMPLATE_RESULT (td);
  
    /* We should never be trying to instantiate a member of a class
-@@ -21733,9 +21733,7 @@
+@@ -21733,9 +21786,7 @@
         outside the class, we may have too many arguments.  Drop the
         ones we don't need.  The same is true for specializations.  */
      args = get_innermost_template_args
@@ -19102,7 +27669,19 @@ Index: gcc/cp/pt.c
  
    if (TREE_CODE (d) == FUNCTION_DECL)
      {
-@@ -21901,7 +21899,7 @@
+@@ -21748,7 +21799,10 @@
+   else
+     {
+       deleted_p = false;
+-      pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
++      if (DECL_CLASS_SCOPE_P (code_pattern))
++	pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
++      else
++	pattern_defined = ! DECL_EXTERNAL (code_pattern);
+     }
+ 
+   /* We may be in the middle of deferred access check.  Disable it now.  */
+@@ -21901,7 +21955,7 @@
  
    /* Regenerate the declaration in case the template has been modified
       by a subsequent redeclaration.  */
@@ -19111,11 +27690,385 @@ Index: gcc/cp/pt.c
  
    /* We already set the file and line above.  Reset them now in case
       they changed as a result of calling regenerate_decl_from_template.  */
+@@ -23628,7 +23682,10 @@
+   if (0 && flag_checking && cxx_dialect >= cxx11
+       /* Don't do this during nsdmi parsing as it can lead to
+ 	 unexpected recursive instantiations.  */
+-      && !parsing_nsdmi ())
++      && !parsing_nsdmi ()
++      /* Don't do this during concept expansion either and for
++         the same reason.  */
++      && !expanding_concept ())
+     fold_non_dependent_expr (expr);
+ 
+   /* Preserve OVERLOADs; the functions must be available to resolve
+@@ -23766,7 +23823,7 @@
+   else
+     expr = build_concept_check (build_overload (tmpl, NULL_TREE), type, args);
+ 
+-  tree constr = make_predicate_constraint (expr);
++  tree constr = normalize_expression (expr);
+   PLACEHOLDER_TYPE_CONSTRAINTS (type) = constr;
+ 
+   /* Our canonical type depends on the constraint.  */
+@@ -23918,8 +23975,11 @@
+ /* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
+    from INIT.  AUTO_NODE is the TEMPLATE_TYPE_PARM used for 'auto' in TYPE.
+    The CONTEXT determines the context in which auto deduction is performed
+-   and is used to control error diagnostics.  */
++   and is used to control error diagnostics.
+ 
++   For partial-concept-ids, extra args may be appended to the list of deduced
++   template arguments prior to determining constraint satisfaction.  */
++
+ tree
+ do_auto_deduction (tree type, tree init, tree auto_node,
+                    tsubst_flags_t complain, auto_deduction_context context)
+@@ -23965,8 +24025,10 @@
+ 
+   if (AUTO_IS_DECLTYPE (auto_node))
+     {
+-      bool id = (DECL_P (init) || (TREE_CODE (init) == COMPONENT_REF
+-				   && !REF_PARENTHESIZED_P (init)));
++      bool id = (DECL_P (init)
++		 || ((TREE_CODE (init) == COMPONENT_REF
++		      || TREE_CODE (init) == SCOPE_REF)
++		     && !REF_PARENTHESIZED_P (init)));
+       targs = make_tree_vec (1);
+       TREE_VEC_ELT (targs, 0)
+ 	= finish_decltype_type (init, id, tf_warning_or_error);
+@@ -24023,9 +24085,20 @@
+   if (flag_concepts && !processing_template_decl)
+     if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (auto_node))
+       {
+-        /* Use the deduced type to check the associated constraints. */
+-        if (!constraints_satisfied_p (constr, targs))
++        /* Use the deduced type to check the associated constraints. If we
++           have a partial-concept-id, rebuild the argument list so that
++           we check using the extra arguments. */
++        gcc_assert (TREE_CODE (constr) == CHECK_CONSTR);
++        tree cargs = CHECK_CONSTR_ARGS (constr);
++        if (TREE_VEC_LENGTH (cargs) > 1)
+           {
++            cargs = copy_node (cargs);
++            TREE_VEC_ELT (cargs, 0) = TREE_VEC_ELT (targs, 0);
++          }
++        else
++          cargs = targs;
++        if (!constraints_satisfied_p (constr, cargs))
++          {
+             if (complain & tf_warning_or_error)
+               {
+                 switch (context)
+@@ -24344,18 +24417,6 @@
+ 
+ static GTY (()) hash_table<constr_hasher> *decl_constraints;
+ 
+-/* Returns true iff cinfo contains a valid set of constraints.
+-   This is the case when the associated requirements have been
+-   successfully decomposed into lists of atomic constraints.
+-   That is, when the saved assumptions are not error_mark_node.  */
+-
+-bool
+-valid_constraints_p (tree cinfo)
+-{
+-  gcc_assert (cinfo);
+-  return CI_ASSUMPTIONS (cinfo) != error_mark_node;
+-}
+-
+ /* Returns the template constraints of declaration T. If T is not
+    constrained, return NULL_TREE. Note that T must be non-null. */
+ 
+@@ -24362,6 +24423,9 @@
+ tree
+ get_constraints (tree t)
+ {
++  if (!flag_concepts)
++    return NULL_TREE;
++
+   gcc_assert (DECL_P (t));
+   if (TREE_CODE (t) == TEMPLATE_DECL)
+     t = DECL_TEMPLATE_RESULT (t);
+@@ -24383,7 +24447,7 @@
+ {
+   if (!ci)
+     return;
+-  gcc_assert (t);
++  gcc_assert (t && flag_concepts);
+   if (TREE_CODE (t) == TEMPLATE_DECL)
+     t = DECL_TEMPLATE_RESULT (t);
+   gcc_assert (!get_constraints (t));
+@@ -24409,12 +24473,244 @@
+     decl_constraints->clear_slot (slot);
+ }
+ 
++/* Memoized satisfaction results for declarations. This
++   maps the pair (constraint_info, arguments) to the result computed
++   by constraints_satisfied_p.  */
++
++struct GTY((for_user)) constraint_sat_entry
++{
++  tree ci;
++  tree args;
++  tree result;
++};
++
++/* Hashing function and equality for constraint entries. */
++
++struct constraint_sat_hasher : ggc_ptr_hash<constraint_sat_entry>
++{
++  static hashval_t hash (constraint_sat_entry *e)
++  {
++    hashval_t val = iterative_hash_object(e->ci, 0);
++    return iterative_hash_template_arg (e->args, val);
++  }
++
++  static bool equal (constraint_sat_entry *e1, constraint_sat_entry *e2)
++  {
++    return e1->ci == e2->ci && comp_template_args (e1->args, e2->args);
++  }
++};
++
++/* Memoized satisfaction results for concept checks. */
++
++struct GTY((for_user)) concept_spec_entry
++{
++  tree tmpl;
++  tree args;
++  tree result;
++};
++
++/* Hashing function and equality for constraint entries.  */
++
++struct concept_spec_hasher : ggc_ptr_hash<concept_spec_entry>
++{
++  static hashval_t hash (concept_spec_entry *e)
++  {
++    return hash_tmpl_and_args (e->tmpl, e->args);
++  }
++
++  static bool equal (concept_spec_entry *e1, concept_spec_entry *e2)
++  {
++    ++comparing_specializations;
++    bool eq = e1->tmpl == e2->tmpl && comp_template_args (e1->args, e2->args);
++    --comparing_specializations;
++    return eq;
++  }
++};
++
++static GTY (()) hash_table<constraint_sat_hasher> *constraint_memos;
++static GTY (()) hash_table<concept_spec_hasher> *concept_memos;
++
++/* Search for a memoized satisfaction result. Returns one of the
++   truth value nodes if previously memoized, or NULL_TREE otherwise.   */
++
++tree
++lookup_constraint_satisfaction (tree ci, tree args)
++{
++  constraint_sat_entry elt = { ci, args, NULL_TREE };
++  constraint_sat_entry* found = constraint_memos->find (&elt);
++  if (found)
++    return found->result;
++  else
++    return NULL_TREE;
++}
++
++/* Memoize the result of a satisfication test. Returns the saved result.  */
++
++tree
++memoize_constraint_satisfaction (tree ci, tree args, tree result)
++{
++  constraint_sat_entry elt = {ci, args, result};
++  constraint_sat_entry** slot = constraint_memos->find_slot (&elt, INSERT);
++  constraint_sat_entry* entry = ggc_alloc<constraint_sat_entry> ();
++  *entry = elt;
++  *slot = entry;
++  return result;
++}
++
++/* Search for a memoized satisfaction result for a concept. */
++
++tree
++lookup_concept_satisfaction (tree tmpl, tree args)
++{
++  concept_spec_entry elt = { tmpl, args, NULL_TREE };
++  concept_spec_entry* found = concept_memos->find (&elt);
++  if (found)
++    return found->result;
++  else
++    return NULL_TREE;
++}
++
++/* Memoize the result of a concept check. Returns the saved result.  */
++
++tree
++memoize_concept_satisfaction (tree tmpl, tree args, tree result)
++{
++  concept_spec_entry elt = {tmpl, args, result};
++  concept_spec_entry** slot = concept_memos->find_slot (&elt, INSERT);
++  concept_spec_entry* entry = ggc_alloc<concept_spec_entry> ();
++  *entry = elt;
++  *slot = entry;
++  return result;
++}
++
++static GTY (()) hash_table<concept_spec_hasher> *concept_expansions;
++
++/* Returns a prior concept specialization. This returns the substituted
++   and normalized constraints defined by the concept.  */
++
++tree
++get_concept_expansion (tree tmpl, tree args)
++{
++  concept_spec_entry elt = { tmpl, args, NULL_TREE };
++  concept_spec_entry* found = concept_expansions->find (&elt);
++  if (found)
++    return found->result;
++  else
++    return NULL_TREE;
++}
++
++/* Save a concept expansion for later.  */
++
++tree
++save_concept_expansion (tree tmpl, tree args, tree def)
++{
++  concept_spec_entry elt = {tmpl, args, def};
++  concept_spec_entry** slot = concept_expansions->find_slot (&elt, INSERT);
++  concept_spec_entry* entry = ggc_alloc<concept_spec_entry> ();
++  *entry = elt;
++  *slot = entry;
++  return def;
++}
++
++static hashval_t
++hash_subsumption_args (tree t1, tree t2)
++{
++  gcc_assert (TREE_CODE (t1) == CHECK_CONSTR);
++  gcc_assert (TREE_CODE (t2) == CHECK_CONSTR);
++  int val = 0;
++  val = iterative_hash_object (CHECK_CONSTR_CONCEPT (t1), val);
++  val = iterative_hash_template_arg (CHECK_CONSTR_ARGS (t1), val);
++  val = iterative_hash_object (CHECK_CONSTR_CONCEPT (t2), val);
++  val = iterative_hash_template_arg (CHECK_CONSTR_ARGS (t2), val);
++  return val;
++}
++
++/* Compare the constraints of two subsumption entries.  The LEFT1 and
++   LEFT2 arguments comprise the first subsumption pair and the RIGHT1
++   and RIGHT2 arguments comprise the second. These are all CHECK_CONSTRs. */
++
++static bool
++comp_subsumption_args (tree left1, tree left2, tree right1, tree right2)
++{
++  if (CHECK_CONSTR_CONCEPT (left1) == CHECK_CONSTR_CONCEPT (right1))
++    if (CHECK_CONSTR_CONCEPT (left2) == CHECK_CONSTR_CONCEPT (right2))
++      if (comp_template_args (CHECK_CONSTR_ARGS (left1),
++                             CHECK_CONSTR_ARGS (right1)))
++        return comp_template_args (CHECK_CONSTR_ARGS (left2),
++                                  CHECK_CONSTR_ARGS (right2));
++  return false;
++}
++
++/* Key/value pair for learning and memoizing subsumption results. This
++   associates a pair of check constraints (including arguments) with
++   a boolean value indicating the result.  */
++
++struct GTY((for_user)) subsumption_entry
++{
++  tree t1;
++  tree t2;
++  bool result;
++};
++
++/* Hashing function and equality for constraint entries.  */
++
++struct subsumption_hasher : ggc_ptr_hash<subsumption_entry>
++{
++  static hashval_t hash (subsumption_entry *e)
++  {
++    return hash_subsumption_args (e->t1, e->t2);
++  }
++
++  static bool equal (subsumption_entry *e1, subsumption_entry *e2)
++  {
++    ++comparing_specializations;
++    bool eq = comp_subsumption_args(e1->t1, e1->t2, e2->t1, e2->t2);
++    --comparing_specializations;
++    return eq;
++  }
++};
++
++static GTY (()) hash_table<subsumption_hasher> *subsumption_table;
++
++/* Search for a previously cached subsumption result. */
++
++bool*
++lookup_subsumption_result (tree t1, tree t2)
++{
++  subsumption_entry elt = { t1, t2, false };
++  subsumption_entry* found = subsumption_table->find (&elt);
++  if (found)
++    return &found->result;
++  else
++    return 0;
++}
++
++/* Save a subsumption result. */
++
++bool
++save_subsumption_result (tree t1, tree t2, bool result)
++{
++  subsumption_entry elt = {t1, t2, result};
++  subsumption_entry** slot = subsumption_table->find_slot (&elt, INSERT);
++  subsumption_entry* entry = ggc_alloc<subsumption_entry> ();
++  *entry = elt;
++  *slot = entry;
++  return result;
++}
++
+ /* Set up the hash table for constraint association. */
+ 
+ void
+ init_constraint_processing (void)
+ {
++  if (!flag_concepts)
++    return;
++
+   decl_constraints = hash_table<constr_hasher>::create_ggc(37);
++  constraint_memos = hash_table<constraint_sat_hasher>::create_ggc(37);
++  concept_memos = hash_table<concept_spec_hasher>::create_ggc(37);
++  concept_expansions = hash_table<concept_spec_hasher>::create_ggc(37);
++  subsumption_table = hash_table<subsumption_hasher>::create_ggc(37);
+ }
+ 
+ /* Set up the hash tables for template instantiations.  */
 Index: gcc/cp/semantics.c
 ===================================================================
 --- a/src/gcc/cp/semantics.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/cp/semantics.c	(.../branches/gcc-6-branch)
-@@ -3276,7 +3276,7 @@
+@@ -1647,17 +1647,10 @@
+       && TREE_CODE (expr) != SCOPE_REF)
+     return expr;
+ 
+-  if (TREE_CODE (expr) == COMPONENT_REF)
++  if (TREE_CODE (expr) == COMPONENT_REF
++      || TREE_CODE (expr) == SCOPE_REF)
+     REF_PARENTHESIZED_P (expr) = true;
+-  else if (type_dependent_expression_p (expr)
+-	   /* When processing_template_decl, a SCOPE_REF may actually be
+-	      referring to a non-static data member of the current class, in
+-	      which case its TREE_TYPE may not be properly cv-qualified (the
+-	      cv-qualifiers of the implicit *this object haven't yet been taken
+-	      into account) so we have to delay building a static_cast until
+-	      instantiation.  */
+-	   || (processing_template_decl
+-	       && TREE_CODE (expr) == SCOPE_REF))
++  else if (type_dependent_expression_p (expr))
+     expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr);
+   else if (VAR_P (expr) && DECL_HARD_REGISTER (expr))
+     /* We can't bind a hard register variable to a reference.  */;
+@@ -3276,7 +3269,7 @@
    tree initializer = convert_from_reference (decl);
  
    /* Mark it as used now even if the use is ill-formed.  */
@@ -19124,7 +28077,7 @@ Index: gcc/cp/semantics.c
      return error_mark_node;
  
    bool saw_generic_lambda = false;
-@@ -4507,7 +4507,8 @@
+@@ -4507,7 +4500,8 @@
  	      || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM)
  	  && !type_dependent_expression_p (t))
  	{
@@ -19134,7 +28087,7 @@ Index: gcc/cp/semantics.c
  	    {
  	      error_at (OMP_CLAUSE_LOCATION (c),
  			"bit-field %qE in %qs clause",
-@@ -4516,7 +4517,8 @@
+@@ -4516,7 +4510,8 @@
  	    }
  	  while (TREE_CODE (t) == COMPONENT_REF)
  	    {
@@ -19144,7 +28097,7 @@ Index: gcc/cp/semantics.c
  		{
  		  error_at (OMP_CLAUSE_LOCATION (c),
  			    "%qE is a member of a union", t);
-@@ -4524,6 +4526,8 @@
+@@ -4524,6 +4519,8 @@
  		}
  	      t = TREE_OPERAND (t, 0);
  	    }
@@ -19153,7 +28106,7 @@ Index: gcc/cp/semantics.c
  	}
        if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
  	{
-@@ -5884,7 +5888,8 @@
+@@ -5884,7 +5881,8 @@
  		}
  	      if (TREE_CODE (type) == REFERENCE_TYPE)
  		type = TREE_TYPE (type);
@@ -19163,7 +28116,7 @@ Index: gcc/cp/semantics.c
  		  && TREE_CODE (type) != POINTER_TYPE)
  		{
  		  error ("linear clause applied to non-integral non-pointer "
-@@ -6583,6 +6588,8 @@
+@@ -6583,6 +6581,8 @@
  		    {
  		      while (TREE_CODE (t) == COMPONENT_REF)
  			t = TREE_OPERAND (t, 0);
@@ -19172,7 +28125,7 @@ Index: gcc/cp/semantics.c
  		      if (bitmap_bit_p (&map_field_head, DECL_UID (t)))
  			break;
  		      if (bitmap_bit_p (&map_head, DECL_UID (t)))
-@@ -6621,7 +6628,8 @@
+@@ -6621,7 +6621,8 @@
  	    {
  	      if (type_dependent_expression_p (t))
  		break;
@@ -19182,7 +28135,7 @@ Index: gcc/cp/semantics.c
  		{
  		  error_at (OMP_CLAUSE_LOCATION (c),
  			    "bit-field %qE in %qs clause",
-@@ -6637,8 +6645,9 @@
+@@ -6637,8 +6638,9 @@
  		}
  	      while (TREE_CODE (t) == COMPONENT_REF)
  		{
@@ -19194,7 +28147,7 @@ Index: gcc/cp/semantics.c
  		    {
  		      error_at (OMP_CLAUSE_LOCATION (c),
  				"%qE is a member of a union", t);
-@@ -6649,6 +6658,8 @@
+@@ -6649,6 +6651,8 @@
  		}
  	      if (remove)
  		break;
@@ -19203,6 +28156,2258 @@ Index: gcc/cp/semantics.c
  	      if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
  		{
  		  if (bitmap_bit_p (&map_field_head, DECL_UID (t)))
+@@ -9213,6 +9217,10 @@
+   if (TREE_TYPE (result) == return_type)
+     return;
+ 
++  if (!processing_template_decl && !VOID_TYPE_P (return_type)
++      && !complete_type_or_else (return_type, NULL_TREE))
++    return;
++
+   /* We already have a DECL_RESULT from start_preparsed_function.
+      Now we need to redo the work it and allocate_struct_function
+      did to reflect the new type.  */
+@@ -9228,8 +9236,6 @@
+ 
+   if (!processing_template_decl)
+     {
+-      if (!VOID_TYPE_P (TREE_TYPE (result)))
+-	complete_type_or_else (TREE_TYPE (result), NULL_TREE);
+       bool aggr = aggregate_value_p (result, fco);
+ #ifdef PCC_STATIC_STRUCT_RETURN
+       cfun->returns_pcc_struct = aggr;
+Index: gcc/cp/constraint.cc
+===================================================================
+--- a/src/gcc/cp/constraint.cc	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/constraint.cc	(.../branches/gcc-6-branch)
+@@ -22,6 +22,7 @@
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
++#include "timevar.h"
+ #include "hash-set.h"
+ #include "machmode.h"
+ #include "vec.h"
+@@ -55,7 +56,9 @@
+ static inline bool
+ constraint_p (tree_code c)
+ {
+-  return (PRED_CONSTR <= c && c <= DISJ_CONSTR) || c == ERROR_MARK;
++  return ((PRED_CONSTR <= c && c <= DISJ_CONSTR)
++          || c == EXPR_PACK_EXPANSION
++          || c == ERROR_MARK);
+ }
+ 
+ /* Returns true if T is a constraint. Note that error_mark_node
+@@ -67,14 +70,6 @@
+   return constraint_p (TREE_CODE (t));
+ }
+ 
+-/* Make a predicate constraint from the given expression. */
+-
+-tree
+-make_predicate_constraint (tree expr)
+-{
+-  return build_nt (PRED_CONSTR, expr);
+-}
+-
+ /* Returns the conjunction of two constraints A and B. Note that
+    conjoining a non-null constraint with NULL_TREE is an identity
+    operation. That is, for non-null A,
+@@ -132,6 +127,53 @@
+   return false;
+ }
+ 
++/* Returns true if any of the arguments in the template
++   argument list is a wildcard or wildcard pack.  */
++
++bool
++contains_wildcard_p (tree args)
++{
++  for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
++    {
++      tree arg = TREE_VEC_ELT (args, i);
++      if (TREE_CODE (arg) == WILDCARD_DECL)
++	return true;
++    }
++  return false;
++}
++
++/* Build a new call expression, but don't actually generate a
++   new function call. We just want the tree, not the semantics.  */
++
++inline tree
++build_call_check (tree id)
++{
++  ++processing_template_decl;
++  vec<tree, va_gc> *fargs = make_tree_vector();
++  tree call = finish_call_expr (id, &fargs, false, false, tf_none);
++  release_tree_vector (fargs);
++  --processing_template_decl;
++  return call;
++}
++
++/* Build an expression that will check a variable concept. If any
++   argument contains a wildcard, don't try to finish the variable
++   template because we can't substitute into a non-existent
++   declaration.  */
++
++tree
++build_variable_check (tree id)
++{
++  gcc_assert (TREE_CODE (id) == TEMPLATE_ID_EXPR);
++  if (contains_wildcard_p (TREE_OPERAND (id, 1)))
++    return id;
++
++  ++processing_template_decl;
++  tree var = finish_template_variable (id);
++  --processing_template_decl;
++  return var;
++}
++
+ /*---------------------------------------------------------------------------
+                     Resolution of qualified concept names
+ ---------------------------------------------------------------------------*/
+@@ -160,6 +202,7 @@
+ static tree
+ resolve_constraint_check (tree ovl, tree args)
+ {
++  int nerrs = 0;
+   tree cands = NULL_TREE;
+   for (tree p = ovl; p != NULL_TREE; p = OVL_NEXT (p))
+     {
+@@ -185,15 +228,21 @@
+       ++processing_template_decl;
+       tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
+       if (tree subst = coerce_template_parms (parms, args, tmpl))
+-        if (subst != error_mark_node)
+-          cands = tree_cons (subst, fn, cands);
++        {
++          if (subst == error_mark_node)
++            ++nerrs;
++          else
++	    cands = tree_cons (subst, fn, cands);
++        }
+       --processing_template_decl;
+     }
+ 
+-  // If we didn't find a unique candidate, then this is
+-  // not a constraint check.
+-  if (!cands || TREE_CHAIN (cands))
+-    return NULL_TREE;
++  if (!cands)
++    /* We either had no candidates or failed deductions.  */
++    return nerrs ? error_mark_node : NULL_TREE;
++  else if (TREE_CHAIN (cands))
++    /* There are multiple candidates.  */
++    return error_mark_node;
+ 
+   return cands;
+ }
+@@ -250,7 +299,9 @@
+      assuming that it works.  Note that failing to deduce
+      will result in diagnostics.  */
+   tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
++  ++processing_template_decl;
+   tree result = coerce_template_parms (parms, args, tmpl);
++  --processing_template_decl;
+   if (result != error_mark_node)
+     {
+       tree decl = DECL_TEMPLATE_RESULT (tmpl);
+@@ -257,7 +308,7 @@
+       return build_tree_list (result, decl);
+     }
+   else
+-    return NULL_TREE;
++    return error_mark_node;
+ }
+ 
+ 
+@@ -315,45 +366,119 @@
+ namespace {
+ 
+ /*---------------------------------------------------------------------------
+-                       Lifting of concept definitions
++                       Constraint implication learning
+ ---------------------------------------------------------------------------*/
+ 
+-/* Part of constraint normalization.  Whenever we find a reference to
+-   a variable concept or a call to a function concept, we lift or
+-   inline that concept's definition into the constraint.  This ensures
+-   that constraints are always checked in the immediate instantiation
+-   context. */
++/* The implication context determines how we memoize concept checks.
++   Given two checks C1 and C2, the direction of implication depends
++   on whether we are learning implications of a conjunction or disjunction.
++   For example:
+ 
+-tree lift_expression (tree);
++      template<typename T> concept bool C = ...;
++      template<typenaem T> concept bool D = C<T> && true;
+ 
+-/* If the tree T has operands, then lift any concepts out of them.  */
+-tree
+-lift_operands (tree t)
++   From this, we can learn that D<T> implies C<T>. We cannot learn,
++   without further testing, that C<T> does not imply D<T>. If, for
++   example, C<T> were defined as true, then these constraints would
++   be logically equivalent.
++
++   In rare cases, we may start with a logical equivalence. For example:
++
++      template<typename T> concept bool C = ...;
++      template<typename T> concept bool D = C<T>;
++
++   Here, we learn that C<T> implies D<T> and vice versa.   */
++
++enum implication_context
+ {
+-  if (int n = tree_operand_length (t))
++  conjunction_cxt, /* C1 implies C2. */
++  disjunction_cxt, /* C2 implies C1. */
++  equivalence_cxt  /* C1 implies C2, C2 implies C1. */
++};
++
++void learn_implications(tree, tree, implication_context);
++
++void
++learn_implication (tree parent, tree child, implication_context cxt)
++{
++  switch (cxt)
+     {
+-      t = copy_node (t);
+-      for (int i = 0; i < n; ++i)
+-        TREE_OPERAND (t, i) = lift_expression (TREE_OPERAND (t, i));
++      case conjunction_cxt:
++        save_subsumption_result (parent, child, true);
++        break;
++      case disjunction_cxt:
++        save_subsumption_result (child, parent, true);
++        break;
++      case equivalence_cxt:
++        save_subsumption_result (parent, child, true);
++        save_subsumption_result (child, parent, true);
++        break;
+     }
+-  return t;
+ }
+ 
+-/* Recursively lift all operands of the function call. Also, check
+-   that the call target is not accidentally a variable concept
+-   since that's ill-formed.  */
+-tree
+-lift_function_call (tree t)
++void
++learn_logical_operation (tree parent, tree constr, implication_context cxt)
+ {
+-  gcc_assert (TREE_CODE (t) == CALL_EXPR);
+-  gcc_assert (!VAR_P (CALL_EXPR_FN (t)));
+-  return lift_operands (t);
++  learn_implications (parent, TREE_OPERAND (constr, 0), cxt);
++  learn_implications (parent, TREE_OPERAND (constr, 1), cxt);
+ }
+ 
+-/* Inline a function (concept) definition by substituting
+-   ARGS into its body. */
++void
++learn_implications (tree parent, tree constr, implication_context cxt)
++{
++  switch (TREE_CODE (constr))
++    {
++      case CHECK_CONSTR:
++        return learn_implication (parent, constr, cxt);
++
++      case CONJ_CONSTR:
++        if (cxt == disjunction_cxt)
++          return;
++        return learn_logical_operation (parent, constr, cxt);
++
++      case DISJ_CONSTR:
++        if (cxt == conjunction_cxt)
++          return;
++        return learn_logical_operation (parent, constr, cxt);
++
++      default:
++        break;
++    }
++}
++
++/* Quickly scan the top-level constraints of CONSTR to learn and
++   cache logical relations between concepts.  The search does not
++   include conjunctions of disjunctions or vice versa.  */
++
++void
++learn_implications (tree tmpl, tree args, tree constr)
++{
++  /* Don't memoize relations between non-dependent arguemnts. It's not
++     helpful. */
++  if (!uses_template_parms (args))
++    return;
++
++  /* Build a check constraint for the purpose of caching. */
++  tree parent = build_nt (CHECK_CONSTR, tmpl, args);
++
++  /* Start learning based on the kind of the top-level contraint. */
++  if (TREE_CODE (constr) == CONJ_CONSTR)
++    return learn_logical_operation (parent, constr, conjunction_cxt);
++  else if (TREE_CODE (constr) == DISJ_CONSTR)
++    return learn_logical_operation (parent, constr, disjunction_cxt);
++  else if (TREE_CODE (constr) == CHECK_CONSTR)
++    /* This is the rare concept alias case. */
++    return learn_implication (parent, constr, equivalence_cxt);
++}
++
++/*---------------------------------------------------------------------------
++                       Expansion of concept definitions
++---------------------------------------------------------------------------*/
++
++/* Returns the expression of a function concept. */
++
+ tree
+-lift_function_definition (tree fn, tree args)
++get_returned_expression (tree fn)
+ {
+   /* Extract the body of the function minus the return expression.  */
+   tree body = DECL_SAVED_TREE (fn);
+@@ -364,202 +489,107 @@
+   if (TREE_CODE (body) != RETURN_EXPR)
+     return error_mark_node;
+ 
+-  body = TREE_OPERAND (body, 0);
+-
+-  /* Substitute template arguments to produce our inline expression.  */
+-  tree result = tsubst_expr (body, args, tf_none, NULL_TREE, false);
+-  if (result == error_mark_node)
+-    return error_mark_node;
+-
+-  return lift_expression (result);
++  return TREE_OPERAND (body, 0);
+ }
+ 
+-/* Inline a reference to a function concept.  */
+-tree
+-lift_call_expression (tree t)
+-{
+-  /* Try to resolve this function call as a concept.  If not, then
+-     it can be returned as-is.  */
+-  tree check = resolve_constraint_check (t);
+-  if (!check)
+-    return lift_function_call (t);
+-  if (check == error_mark_node)
+-    return error_mark_node;
++/* Returns the initializer of a variable concept. */
+ 
+-  tree fn = TREE_VALUE (check);
+-  tree args = TREE_PURPOSE (check);
+-  return lift_function_definition (fn, args);
+-}
+-
+ tree
+-lift_variable_initializer (tree var, tree args)
++get_variable_initializer (tree var)
+ {
+-  /* Extract the body from the variable initializer.  */
+   tree init = DECL_INITIAL (var);
+   if (!init)
+     return error_mark_node;
++  return init;
++}
+ 
+-  /* Substitute the arguments to form our new inline expression.  */
+-  tree result = tsubst_expr (init, args, tf_none, NULL_TREE, false);
+-  if (result == error_mark_node)
+-    return error_mark_node;
++/* Returns the definition of a variable or function concept.  */
+ 
+-  return lift_expression (result);
++tree
++get_concept_definition (tree decl)
++{
++  if (TREE_CODE (decl) == VAR_DECL)
++    return get_variable_initializer (decl);
++  else if (TREE_CODE (decl) == FUNCTION_DECL)
++    return get_returned_expression (decl);
++  gcc_unreachable ();
+ }
+ 
+-/* Determine if a template-id is a variable concept and inline.  */
++int expansion_level = 0;
+ 
+-tree
+-lift_template_id (tree t)
++struct expanding_concept_sentinel
+ {
+-  if (tree info = resolve_variable_concept_check (t))
+-    {
+-      tree decl = TREE_VALUE (info);
+-      tree args = TREE_PURPOSE (info);
+-      return lift_variable_initializer (decl, args);
+-    }
++  expanding_concept_sentinel ()
++  {
++    ++expansion_level;
++  }
+ 
+-  /* Check that we didn't refer to a function concept like
+-      a variable.
++  ~expanding_concept_sentinel()
++  {
++    --expansion_level;
++  }
++};
+ 
+-     TODO: Add a note on how to fix this.  */
+-  tree tmpl = TREE_OPERAND (t, 0);
+-  if (TREE_CODE (tmpl) == OVERLOAD)
+-    {
+-      tree fn = OVL_FUNCTION (tmpl);
+-      if (TREE_CODE (fn) == TEMPLATE_DECL
+-          && DECL_DECLARED_CONCEPT_P (DECL_TEMPLATE_RESULT (fn)))
+-        {
+-          error_at (location_of (t),
+-		    "invalid reference to function concept %qD", fn);
+-          return error_mark_node;
+-        }
+-    }
+ 
+-  return t;
+-}
++} /* namespace */
+ 
+-/* Lift any constraints appearing in a nested requirement of
+-   a requires-expression. */
+-tree
+-lift_requires_expression (tree t)
++/* Returns true when a concept is being expanded.  */
++
++bool
++expanding_concept()
+ {
+-  tree parms = TREE_OPERAND (t, 0);
+-  tree reqs = TREE_OPERAND (t, 1);
+-  tree result = NULL_TREE;
+-  for (; reqs != NULL_TREE; reqs = TREE_CHAIN (reqs))
+-    {
+-      tree req = TREE_VALUE (reqs);
+-      if (TREE_CODE (req) == NESTED_REQ)
+-        {
+-          tree expr = lift_expression (TREE_OPERAND (req, 0));
+-          req = finish_nested_requirement (expr);
+-        }
+-      result = tree_cons (NULL_TREE, req, result);
+-    }
+-  return finish_requires_expr (parms, result);
++  return expansion_level > 0;
+ }
+ 
+-/* Inline references to specializations of concepts.  */
++/* Expand a concept declaration (not a template) and its arguments to
++   a constraint defined by the concept's initializer or definition.  */
++
+ tree
+-lift_expression (tree t)
++expand_concept (tree decl, tree args)
+ {
+-  if (t == NULL_TREE)
+-    return NULL_TREE;
++  expanding_concept_sentinel sentinel;
+ 
+-  if (t == error_mark_node)
+-    return error_mark_node;
++  if (TREE_CODE (decl) == TEMPLATE_DECL)
++    decl = DECL_TEMPLATE_RESULT (decl);
++  tree tmpl = DECL_TI_TEMPLATE (decl);
+ 
+-  /* Concepts can be referred to by call or variable. All other
+-     nodes are preserved.  */
+-  switch (TREE_CODE (t))
+-    {
+-    case CALL_EXPR:
+-      return lift_call_expression (t);
++  /* Check for a previous specialization. */
++  if (tree spec = get_concept_expansion (tmpl, args))
++    return spec;
+ 
+-    case TEMPLATE_ID_EXPR:
+-      return lift_template_id (t);
++  /* Substitute the arguments to form a new definition expression.  */
++  tree def = get_concept_definition (decl);
+ 
+-    case REQUIRES_EXPR:
+-      return lift_requires_expression (t);
++  ++processing_template_decl;
++  tree result = tsubst_expr (def, args, tf_none, NULL_TREE, true);
++  --processing_template_decl;
++  if (result == error_mark_node)
++    return error_mark_node;
+ 
+-    case EXPR_PACK_EXPANSION:
+-      /* Use copy_node rather than make_pack_expansion so that
+-	 PACK_EXPANSION_PARAMETER_PACKS stays the same.  */
+-      t = copy_node (t);
+-      SET_PACK_EXPANSION_PATTERN
+-	(t, lift_expression (PACK_EXPANSION_PATTERN (t)));
+-      return t;
++  /* And lastly, normalize it, check for implications, and save
++     the specialization for later.  */
++  tree norm = normalize_expression (result);
++  learn_implications (tmpl, args, norm);
++  return save_concept_expansion (tmpl, args, norm);
++}
+ 
+-    case TREE_LIST:
+-      {
+-        t = copy_node (t);
+-        TREE_VALUE (t) = lift_expression (TREE_VALUE (t));
+-        TREE_CHAIN (t) = lift_expression (TREE_CHAIN (t));
+-        return t;
+-      }
+ 
+-    default:
+-      return lift_operands (t);
+-    }
+-}
++/*---------------------------------------------------------------------------
++                Stepwise normalization of expressions
+ 
+-/*---------------------------------------------------------------------------
+-                Transformation of expressions into constraints
++This set of functions will transform an expression into a constraint
++in a sequence of steps. Normalization does not not look into concept
++definitions.
+ ---------------------------------------------------------------------------*/
+ 
+-/* Part of constraint normalization. The following functions rewrite
+-   expressions as constraints.  */
+-
+-tree transform_expression (tree);
+-
+-/* Check that the logical-or or logical-and expression does
+-   not result in a call to a user-defined user-defined operator
+-   (temp.constr.op). Returns true if the logical operator is
+-   admissible and false otherwise. */
+-
+-bool
+-check_logical_expr (tree t)
+-{
+-  /* We can't do much for type dependent expressions. */
+-  if (type_dependent_expression_p (t))
+-    return true;
+-
+-  /* Resolve the logical operator. Note that template processing is
+-     disabled so we get the actual call or target expression back.
+-     not_processing_template_sentinel sentinel.
+-
+-     TODO: This check is actually subsumed by the requirement that
+-     constraint operands have type bool. I'm not sure we need it
+-     unless we allow conversions.  */
+-  tree arg1 = TREE_OPERAND (t, 0);
+-  tree arg2 = TREE_OPERAND (t, 1);
+-  tree ovl = NULL_TREE;
+-  tree expr = build_x_binary_op (EXPR_LOC_OR_LOC (arg2, input_location),
+-                                 TREE_CODE (t),
+-                                 arg1, TREE_CODE (arg1),
+-                                 arg2, TREE_CODE (arg2),
+-                                 &ovl,
+-                                 tf_none);
+-  if (TREE_CODE (expr) != TREE_CODE (t))
+-    {
+-      error ("user-defined operator %qs in constraint %q+E",
+-	     operator_name_info[TREE_CODE (t)].name, t);
+-      return false;
+-    }
+-  return true;
+-}
+-
+ /* Transform a logical-or or logical-and expression into either
+    a conjunction or disjunction. */
+ 
+ tree
+-xform_logical (tree t, tree_code c)
++normalize_logical_operation (tree t, tree_code c)
+ {
+-  if (!check_logical_expr (t))
+-    return error_mark_node;
+-  tree t0 = transform_expression (TREE_OPERAND (t, 0));
+-  tree t1 = transform_expression (TREE_OPERAND (t, 1));
++  tree t0 = normalize_expression (TREE_OPERAND (t, 0));
++  tree t1 = normalize_expression (TREE_OPERAND (t, 1));
+   return build_nt (c, t0, t1);
+ }
+ 
+@@ -567,7 +597,7 @@
+    for its expression. */
+ 
+ inline tree
+-xform_simple_requirement (tree t)
++normalize_simple_requirement (tree t)
+ {
+   return build_nt (EXPR_CONSTR, TREE_OPERAND (t, 0));
+ }
+@@ -575,7 +605,7 @@
+ /* A type requirement T introduce a type constraint for its type.  */
+ 
+ inline tree
+-xform_type_requirement (tree t)
++normalize_type_requirement (tree t)
+ {
+   return build_nt (TYPE_CONSTR, TREE_OPERAND (t, 0));
+ }
+@@ -589,7 +619,7 @@
+    includes an exception constraint.  */
+ 
+ tree
+-xform_compound_requirement (tree t)
++normalize_compound_requirement (tree t)
+ {
+   tree expr = TREE_OPERAND (t, 0);
+   tree constr = build_nt (EXPR_CONSTR, TREE_OPERAND (t, 0));
+@@ -627,29 +657,29 @@
+    will guarantee that the constraint is never satisfied.  */
+ 
+ inline tree
+-xform_nested_requirement (tree t)
++normalize_nested_requirement (tree t)
+ {
+-  return transform_expression (TREE_OPERAND (t, 0));
++  return normalize_expression (TREE_OPERAND (t, 0));
+ }
+ 
+ /* Transform a requirement T into one or more constraints.  */
+ 
+ tree
+-xform_requirement (tree t)
++normalize_requirement (tree t)
+ {
+   switch (TREE_CODE (t))
+     {
+     case SIMPLE_REQ:
+-      return xform_simple_requirement (t);
++      return normalize_simple_requirement (t);
+ 
+     case TYPE_REQ:
+-      return xform_type_requirement (t);
++      return normalize_type_requirement (t);
+ 
+     case COMPOUND_REQ:
+-      return xform_compound_requirement (t);
++      return normalize_compound_requirement (t);
+ 
+     case NESTED_REQ:
+-      return xform_nested_requirement (t);
++      return normalize_nested_requirement (t);
+ 
+     default:
+       gcc_unreachable ();
+@@ -661,23 +691,25 @@
+    constraints. */
+ 
+ tree
+-xform_requirements (tree t)
++normalize_requirements (tree t)
+ {
+   tree result = NULL_TREE;
+   for (; t; t = TREE_CHAIN (t))
+     {
+-      tree constr = xform_requirement (TREE_VALUE (t));
++      tree constr = normalize_requirement (TREE_VALUE (t));
+       result = conjoin_constraints (result, constr);
+     }
+   return result;
+ }
+ 
+-/* Transform a requires-expression into a parameterized constraint.  */
++/* The normal form of a requires-expression is a parameterized
++   constraint having the same parameters and a conjunction of
++   constraints representing the normal form of requirements.  */
+ 
+ tree
+-xform_requires_expr (tree t)
++normalize_requires_expression (tree t)
+ {
+-  tree operand = xform_requirements (TREE_OPERAND (t, 1));
++  tree operand = normalize_requirements (TREE_OPERAND (t, 1));
+   if (tree parms = TREE_OPERAND (t, 0))
+     return build_nt (PARM_CONSTR, parms, operand);
+   else
+@@ -684,23 +716,140 @@
+     return operand;
+ }
+ 
+-/* Transform an expression into an atomic predicate constraint.
+-   After substitution, the expression of a predicate constraint
+-   shall have type bool (temp.constr.pred).  For non-type-dependent
+-   expressions, we can check that now.  */
++/* For a template-id referring to a variable concept, returns
++   a check constraint. Otherwise, returns a predicate constraint. */
+ 
+ tree
+-xform_atomic (tree t)
++normalize_template_id_expression (tree t)
+ {
+-  if (TREE_TYPE (t) && !type_dependent_expression_p (t))
+-  {
+-    tree type = cv_unqualified (TREE_TYPE (t));
+-    if (!same_type_p (type, boolean_type_node))
+-      {
+-        error ("predicate constraint %q+E does not have type %<bool%>", t);
++  if (tree info = resolve_variable_concept_check (t))
++    {
++      if (info == error_mark_node)
++        {
++          /* We get this when the template arguments don't match
++             the variable concept. */
++          error ("invalid reference to concept %qE", t);
++          return error_mark_node;
++        }
++
++      tree decl = TREE_VALUE (info);
++      tree args = TREE_PURPOSE (info);
++      return build_nt (CHECK_CONSTR, decl, args);
++    }
++
++  /* Check that we didn't refer to a function concept like a variable.  */
++  tree tmpl = TREE_OPERAND (t, 0);
++  if (TREE_CODE (tmpl) == OVERLOAD)
++    {
++      tree fn = OVL_FUNCTION (tmpl);
++      if (TREE_CODE (fn) == TEMPLATE_DECL
++          && DECL_DECLARED_CONCEPT_P (DECL_TEMPLATE_RESULT (fn)))
++        {
++          error_at (location_of (t),
++                    "invalid reference to function concept %qD", fn);
++          return error_mark_node;
++        }
++    }
++
++  return build_nt (PRED_CONSTR, t);
++}
++
++/* For a call expression to a function concept, returns a check
++   constraint. Otherwise, returns a predicate constraint. */
++
++tree
++normalize_call_expression (tree t)
++{
++  /* Try to resolve this function call as a concept.  If not, then
++     it can be returned as a predicate constraint.  */
++  tree check = resolve_constraint_check (t);
++  if (!check)
++    return build_nt (PRED_CONSTR, t);
++  if (check == error_mark_node)
++    {
++      /* TODO: Improve diagnostics. We could report why the reference
++         is invalid. */
++      error ("invalid reference to concept %qE", t);
++      return error_mark_node;
++    }
++
++  tree fn = TREE_VALUE (check);
++  tree args = TREE_PURPOSE (check);
++  return build_nt (CHECK_CONSTR, fn, args);
++}
++
++/* If T is a call to an overloaded && or || operator, diagnose that
++   as a non-SFINAEable error.  Returns true if an error is emitted.
++
++   TODO: It would be better to diagnose this at the point of definition,
++   if possible. Perhaps we should immediately do a first-pass normalization
++   of a concept definition to catch obvious non-dependent errors like
++   this.  */
++
++bool
++check_for_logical_overloads (tree t)
++{
++  if (TREE_CODE (t) != CALL_EXPR)
++    return false;
++
++  tree fn = CALL_EXPR_FN (t);
++
++  /* For member calls, try extracting the function from the
++     component ref.  */
++  if (TREE_CODE (fn) == COMPONENT_REF)
++    {
++      fn = TREE_OPERAND (fn, 1);
++      if (TREE_CODE (fn) == BASELINK)
++        fn = BASELINK_FUNCTIONS (fn);
++    }
++
++  if (TREE_CODE (fn) != FUNCTION_DECL)
++    return false;
++
++  if (DECL_OVERLOADED_OPERATOR_P (fn))
++    {
++      location_t loc = EXPR_LOC_OR_LOC (t, input_location);
++      error_at (loc, "constraint %qE, uses overloaded operator", t);
++      return true;
++    }
++
++  return false;
++}
++
++/* The normal form of an atom depends on the expression. The normal
++   form of a function call to a function concept is a check constraint
++   for that concept. The normal form of a reference to a variable
++   concept is a check constraint for that concept. Otherwise, the
++   constraint is a predicate constraint.  */
++
++tree
++normalize_atom (tree t)
++{
++  /* We can get constraints pushed down through pack expansions, so
++     just return them. */
++  if (constraint_p (t))
++    return t;
++
++  tree type = TREE_TYPE (t);
++  if (!type || type_unknown_p (t) || TREE_CODE (type) == TEMPLATE_TYPE_PARM)
++    ;
++  else if (!dependent_type_p (type))
++    {
++      if (check_for_logical_overloads (t))
+         return error_mark_node;
+-      }
+-  }
++
++      type = cv_unqualified (type);
++      if (!same_type_p (type, boolean_type_node))
++	{
++	  error ("predicate constraint %q+E does not have type %<bool%>", t);
++	  return error_mark_node;
++	}
++    }
++
++  if (TREE_CODE (t) == TEMPLATE_ID_EXPR)
++    return normalize_template_id_expression (t);
++  if (TREE_CODE (t) == CALL_EXPR)
++    return normalize_call_expression (t);
+   return build_nt (PRED_CONSTR, t);
+ }
+ 
+@@ -735,9 +884,9 @@
+    leaves of the constraint so that partial ordering will work.  */
+ 
+ tree
+-xform_pack_expansion (tree t)
++normalize_pack_expansion (tree t)
+ {
+-  tree pat = transform_expression (PACK_EXPANSION_PATTERN (t));
++  tree pat = normalize_expression (PACK_EXPANSION_PATTERN (t));
+   return push_down_pack_expansion (t, pat);
+ }
+ 
+@@ -744,40 +893,39 @@
+ /* Transform an expression into a constraint.  */
+ 
+ tree
+-xform_expr (tree t)
++normalize_any_expression (tree t)
+ {
+   switch (TREE_CODE (t))
+     {
+     case TRUTH_ANDIF_EXPR:
+-      return xform_logical (t, CONJ_CONSTR);
++      return normalize_logical_operation (t, CONJ_CONSTR);
+ 
+     case TRUTH_ORIF_EXPR:
+-      return xform_logical (t, DISJ_CONSTR);
++      return normalize_logical_operation (t, DISJ_CONSTR);
+ 
+     case REQUIRES_EXPR:
+-      return xform_requires_expr (t);
++      return normalize_requires_expression (t);
+ 
+     case BIND_EXPR:
+-      return transform_expression (BIND_EXPR_BODY (t));
++      return normalize_expression (BIND_EXPR_BODY (t));
+ 
+     case EXPR_PACK_EXPANSION:
+-      return xform_pack_expansion (t);
++      return normalize_pack_expansion (t);
+ 
+     default:
+       /* All other constraints are atomic. */
+-      return xform_atomic (t);
++      return normalize_atom (t);
+     }
+ }
+ 
+ /* Transform a statement into an expression.  */
+-
+ tree
+-xform_stmt (tree t)
++normalize_any_statement (tree t)
+ {
+   switch (TREE_CODE (t))
+     {
+     case RETURN_EXPR:
+-      return transform_expression (TREE_OPERAND (t, 0));
++      return normalize_expression (TREE_OPERAND (t, 0));
+     default:
+       gcc_unreachable ();
+     }
+@@ -787,12 +935,12 @@
+ /* Reduction rules for the declaration T.  */
+ 
+ tree
+-xform_decl (tree t)
++normalize_any_declaration (tree t)
+ {
+   switch (TREE_CODE (t))
+     {
+     case VAR_DECL:
+-      return xform_atomic (t);
++      return normalize_atom (t);
+     default:
+       gcc_unreachable ();
+     }
+@@ -799,12 +947,10 @@
+   return error_mark_node;
+ }
+ 
+-/* Transform a lifted expression into a constraint. This either
+-   returns a constraint, or it returns error_mark_node when
+-   a constraint cannot be formed.  */
++/* Returns the normal form of a constraint expression. */
+ 
+ tree
+-transform_expression (tree t)
++normalize_expression (tree t)
+ {
+   if (!t)
+     return NULL_TREE;
+@@ -818,13 +964,13 @@
+     case tcc_binary:
+     case tcc_expression:
+     case tcc_vl_exp:
+-      return xform_expr (t);
++      return normalize_any_expression (t);
+ 
+     case tcc_statement:
+-      return xform_stmt (t);
++      return normalize_any_statement (t);
+ 
+     case tcc_declaration:
+-      return xform_decl (t);
++      return normalize_any_declaration (t);
+ 
+     case tcc_exceptional:
+     case tcc_constant:
+@@ -831,7 +977,7 @@
+     case tcc_reference:
+     case tcc_comparison:
+       /* These are all atomic predicate constraints. */
+-      return xform_atomic (t);
++      return normalize_atom (t);
+ 
+     default:
+       /* Unhandled node kind. */
+@@ -840,6 +986,7 @@
+   return error_mark_node;
+ }
+ 
++
+ /*---------------------------------------------------------------------------
+                         Constraint normalization
+ ---------------------------------------------------------------------------*/
+@@ -879,8 +1026,7 @@
+ {
+   ++processing_template_decl;
+   tree expr = PRED_CONSTR_EXPR (t);
+-  tree lifted = lift_expression (expr);
+-  tree constr = transform_expression (lifted);
++  tree constr = normalize_expression (expr);
+   --processing_template_decl;
+   return constr;
+ }
+@@ -938,7 +1084,6 @@
+   return error_mark_node;
+ }
+ 
+-} /* namespace */
+ 
+ 
+ // -------------------------------------------------------------------------- //
+@@ -1028,61 +1173,11 @@
+   ci->declarator_reqs = decl_reqs;
+   ci->associated_constr = conjoin_constraints (tmpl_reqs, decl_reqs);
+ 
+-  ++processing_template_decl;
+-  ci->normalized_constr = normalize_constraint (ci->associated_constr);
+-  --processing_template_decl;
+-
+-  ci->assumptions = decompose_assumptions (ci->normalized_constr);
+   return (tree)ci;
+ }
+ 
+ namespace {
+ 
+-/* Returns true if any of the arguments in the template
+-   argument list is a wildcard or wildcard pack. */
+-bool
+-contains_wildcard_p (tree args)
+-{
+-  for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
+-    {
+-      tree arg = TREE_VEC_ELT (args, i);
+-      if (TREE_CODE (arg) == WILDCARD_DECL)
+-	return true;
+-    }
+-  return false;
+-}
+-
+-/* Build a new call expression, but don't actually generate
+-   a new function call. We just want the tree, not the
+-   semantics. */
+-inline tree
+-build_call_check (tree id)
+-{
+-  ++processing_template_decl;
+-  vec<tree, va_gc> *fargs = make_tree_vector();
+-  tree call = finish_call_expr (id, &fargs, false, false, tf_none);
+-  release_tree_vector (fargs);
+-  --processing_template_decl;
+-  return call;
+-}
+-
+-/* Build an expression that will check a variable concept. If any
+-   argument contains a wildcard, don't try to finish the variable
+-   template because we can't substitute into a non-existent
+-   declaration.  */
+-tree
+-build_variable_check (tree id)
+-{
+-  gcc_assert (TREE_CODE (id) == TEMPLATE_ID_EXPR);
+-  if (contains_wildcard_p (TREE_OPERAND (id, 1)))
+-    return id;
+-
+-  ++processing_template_decl;
+-  tree var = finish_template_variable (id);
+-  --processing_template_decl;
+-  return var;
+-}
+-
+ /* Construct a sequence of template arguments by prepending
+    ARG to REST. Either ARG or REST may be null. */
+ tree
+@@ -1158,7 +1253,9 @@
+ 
+    Note that the constraints are neither reduced nor decomposed.
+    That is done only after the requires clause has been parsed
+-   (or not). */
++   (or not).
++
++   This will always return a CHECK_CONSTR. */
+ tree
+ finish_shorthand_constraint (tree decl, tree constr)
+ {
+@@ -1207,7 +1304,7 @@
+       TREE_TYPE (check) = boolean_type_node;
+     }
+ 
+-  return make_predicate_constraint (check);
++  return normalize_expression (check);
+ }
+ 
+ /* Returns a conjunction of shorthand requirements for the template
+@@ -1346,7 +1443,7 @@
+ 
+   /* Associate the constraint. */
+   tree check = build_concept_check (tmpl_decl, NULL_TREE, check_args);
+-  tree constr = make_predicate_constraint (check);
++  tree constr = normalize_expression (check);
+   TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = constr;
+ 
+   return parm_list;
+@@ -1362,41 +1459,28 @@
+ {
+   if (TREE_CODE (t) == TYPE_DECL)
+     {
+-      /* A constrained parameter.  */
+-      tmpl = DECL_TI_TEMPLATE (CONSTRAINED_PARM_CONCEPT (t));
+-      args = CONSTRAINED_PARM_EXTRA_ARGS (t);
++      /* A constrained parameter.  Build a constraint check
++         based on the prototype parameter and then extract the
++         arguments from that.  */
++      tree proto = CONSTRAINED_PARM_PROTOTYPE (t);
++      tree check = finish_shorthand_constraint (proto, t);
++      placeholder_extract_concept_and_args (check, tmpl, args);
+       return;
+     }
+ 
+-  gcc_assert (TREE_CODE (t) == PRED_CONSTR);
+-  t = PRED_CONSTR_EXPR (t);
+-  gcc_assert (TREE_CODE (t) == CALL_EXPR
+-              || TREE_CODE (t) == TEMPLATE_ID_EXPR
+-              || VAR_P (t));
+-
+-  if (TREE_CODE (t) == CALL_EXPR)
+-    t = CALL_EXPR_FN (t);
+-  if (TREE_CODE (t) == TEMPLATE_ID_EXPR)
++  if (TREE_CODE (t) == CHECK_CONSTR)
+     {
+-      tmpl = TREE_OPERAND (t, 0);
+-      if (TREE_CODE (tmpl) == OVERLOAD)
+-	{
+-	  gcc_assert (OVL_CHAIN (tmpl) == NULL_TREE);
+-	  tmpl = OVL_FUNCTION (tmpl);
+-	}
+-      args = TREE_OPERAND (t, 1);
++      tree decl = CHECK_CONSTR_CONCEPT (t);
++      tmpl = DECL_TI_TEMPLATE (decl);
++      args = CHECK_CONSTR_ARGS (t);
++      return;
+     }
+-  else if (DECL_P (t))
+-    {
+-      tmpl = DECL_TI_TEMPLATE (t);
+-      args = DECL_TI_ARGS (t);
+-    }
+-  else
++
+     gcc_unreachable ();
+ }
+ 
+ /* Returns true iff the placeholders C1 and C2 are equivalent.  C1
+-   and C2 can be either PRED_CONSTR_EXPR or TEMPLATE_TYPE_PARM.  */
++   and C2 can be either CHECK_CONSTR or TEMPLATE_TYPE_PARM.  */
+ 
+ bool
+ equivalent_placeholder_constraints (tree c1, tree c2)
+@@ -1411,6 +1495,11 @@
+     return true;
+   if (!c1 || !c2)
+     return false;
++  if (c1 == error_mark_node || c2 == error_mark_node)
++    /* We get here during satisfaction; when a deduction constraint
++       fails, substitution can produce an error_mark_node for the
++       placeholder constraints.  */
++    return false;
+ 
+   tree t1, t2, a1, a2;
+   placeholder_extract_concept_and_args (c1, t1, a1);
+@@ -1419,21 +1508,20 @@
+   if (t1 != t2)
+     return false;
+ 
+-  /* Skip the first argument to avoid infinite recursion on the
+-     placeholder auto itself.  */
+-  bool skip1 = (TREE_CODE (c1) == PRED_CONSTR);
+-  bool skip2 = (TREE_CODE (c2) == PRED_CONSTR);
+-
+-  int len1 = (a1 ? TREE_VEC_LENGTH (a1) : 0) - skip1;
+-  int len2 = (a2 ? TREE_VEC_LENGTH (a2) : 0) - skip2;
+-
++  int len1 = TREE_VEC_LENGTH (a1);
++  int len2 = TREE_VEC_LENGTH (a2);
+   if (len1 != len2)
+     return false;
+ 
+-  for (int i = 0; i < len1; ++i)
+-    if (!cp_tree_equal (TREE_VEC_ELT (a1, i + skip1),
+-			TREE_VEC_ELT (a2, i + skip2)))
++  /* Skip the first argument so we don't infinitely recurse.
++     Also, they may differ in template parameter index.  */
++  for (int i = 1; i < len1; ++i)
++    {
++      tree t1 = TREE_VEC_ELT (a1, i);
++      tree t2 = TREE_VEC_ELT (a2, i);
++      if (!template_args_equal (t1, t2))
+       return false;
++    }
+   return true;
+ }
+ 
+@@ -1492,40 +1580,139 @@
+   return build_nt (PRED_CONSTR, result);
+ }
+ 
++/* Substitute into a check constraint. */
++
++tree
++tsubst_check_constraint (tree t, tree args,
++                         tsubst_flags_t complain, tree in_decl)
++{
++  tree decl = CHECK_CONSTR_CONCEPT (t);
++  tree tmpl = DECL_TI_TEMPLATE (decl);
++  tree targs = CHECK_CONSTR_ARGS (t);
++
++  /* Substitute through by building an template-id expression
++     and then substituting into that. */
++  tree expr = build_nt(TEMPLATE_ID_EXPR, tmpl, targs);
++  ++processing_template_decl;
++  tree result = tsubst_expr (expr, args, complain, in_decl, false);
++  --processing_template_decl;
++
++  if (result == error_mark_node)
++    return error_mark_node;
++
++  /* Extract the results and rebuild the check constraint. */
++  decl = DECL_TEMPLATE_RESULT (TREE_OPERAND (result, 0));
++  args = TREE_OPERAND (result, 1);
++
++  return build_nt (CHECK_CONSTR, decl, args);
++}
++
+ /* Substitute into the conjunction of constraints. Returns
+    error_mark_node if substitution into either operand fails. */
++
+ tree
+-tsubst_conjunction (tree t, tree args,
+-                    tsubst_flags_t complain, tree in_decl)
++tsubst_logical_operator (tree t, tree args,
++			 tsubst_flags_t complain, tree in_decl)
+ {
+   tree t0 = TREE_OPERAND (t, 0);
+   tree r0 = tsubst_constraint (t0, args, complain, in_decl);
++  if (r0 == error_mark_node)
++    return error_mark_node;
+   tree t1 = TREE_OPERAND (t, 1);
+   tree r1 = tsubst_constraint (t1, args, complain, in_decl);
+-  return build_nt (CONJ_CONSTR, r0, r1);
++  if (r1 == error_mark_node)
++    return error_mark_node;
++  return build_nt (TREE_CODE (t), r0, r1);
+ }
+ 
+-/* Substitute ARGS into the constraint T. */
++namespace {
++
++/* Substitute ARGS into the expression constraint T.  */
++
+ tree
+-tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl)
++tsubst_expr_constr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+ {
+-  if (t == NULL_TREE)
+-    return t;
+-  if (TREE_CODE (t) == CONJ_CONSTR)
+-    return tsubst_conjunction (t, args, complain, in_decl);
+-  else if (TREE_CODE (t) == PRED_CONSTR)
+-    return tsubst_predicate_constraint (t, args, complain, in_decl);
+-  else
+-    gcc_unreachable ();
+-  return error_mark_node;
++  cp_unevaluated guard;
++  tree expr = EXPR_CONSTR_EXPR (t);
++  tree ret = tsubst_expr (expr, args, complain, in_decl, false);
++  if (ret == error_mark_node)
++    return error_mark_node;
++  return build_nt (EXPR_CONSTR, ret);
+ }
+ 
+-namespace {
++/* Substitute ARGS into the type constraint T.  */
+ 
++tree
++tsubst_type_constr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
++{
++  tree type = TYPE_CONSTR_TYPE (t);
++  tree ret = tsubst (type, args, complain, in_decl);
++  if (ret == error_mark_node)
++    return error_mark_node;
++  return build_nt (TYPE_CONSTR, ret);
++}
++
++/* Substitute ARGS into the implicit conversion constraint T.  */
++
++tree
++tsubst_implicit_conversion_constr (tree t, tree args, tsubst_flags_t complain,
++                                   tree in_decl)
++{
++  cp_unevaluated guard;
++  tree expr = ICONV_CONSTR_EXPR (t);
++  tree type = ICONV_CONSTR_TYPE (t);
++  tree new_expr = tsubst_expr (expr, args, complain, in_decl, false);
++  if (new_expr == error_mark_node)
++    return error_mark_node;
++  tree new_type = tsubst (type, args, complain, in_decl);
++  if (new_type == error_mark_node)
++    return error_mark_node;
++  return build_nt (ICONV_CONSTR, new_expr, new_type);
++}
++
++/* Substitute ARGS into the argument deduction constraint T.  */
++
++tree
++tsubst_argument_deduction_constr (tree t, tree args, tsubst_flags_t complain,
++                                  tree in_decl)
++{
++  cp_unevaluated guard;
++  tree expr = DEDUCT_CONSTR_EXPR (t);
++  tree pattern = DEDUCT_CONSTR_PATTERN (t);
++  tree autos = DEDUCT_CONSTR_PLACEHOLDER(t);
++  tree new_expr = tsubst_expr (expr, args, complain, in_decl, false);
++  if (new_expr == error_mark_node)
++    return error_mark_node;
++  /* It seems like substituting through the pattern will not affect the
++     placeholders.  We should (?) be able to reuse the existing list
++     without any problems.  If not, then we probably want to create a
++     new list of placeholders and then instantiate the pattern using
++     those.  */
++  tree new_pattern = tsubst (pattern, args, complain, in_decl);
++  if (new_pattern == error_mark_node)
++    return error_mark_node;
++  return build_nt (DEDUCT_CONSTR, new_expr, new_pattern, autos);
++}
++
++/* Substitute ARGS into the exception constraint T.  */
++
++tree
++tsubst_exception_constr (tree t, tree args, tsubst_flags_t complain,
++			 tree in_decl)
++{
++  cp_unevaluated guard;
++  tree expr = EXCEPT_CONSTR_EXPR (t);
++  tree ret = tsubst_expr (expr, args, complain, in_decl, false);
++  if (ret == error_mark_node)
++    return error_mark_node;
++  return build_nt (EXCEPT_CONSTR, ret);
++}
++
+ /* A subroutine of tsubst_constraint_variables. Register local
+    specializations for each of parameter in PARMS and its
+    corresponding substituted constraint variable in VARS.
+    Returns VARS. */
++
+ tree
+ declare_constraint_vars (tree parms, tree vars)
+ {
+@@ -1553,6 +1740,7 @@
+    Note that the caller must establish a local specialization stack
+    prior to calling this function since this substitution will
+    declare the substituted parameters. */
++
+ tree
+ tsubst_constraint_variables (tree t, tree args,
+                              tsubst_flags_t complain, tree in_decl)
+@@ -1568,10 +1756,29 @@
+   return declare_constraint_vars (t, vars);
+ }
+ 
++/* Substitute ARGS into the parameterized constraint T.  */
++
++tree
++tsubst_parameterized_constraint (tree t, tree args,
++				 tsubst_flags_t complain, tree in_decl)
++{
++  local_specialization_stack stack;
++  tree vars = tsubst_constraint_variables (PARM_CONSTR_PARMS (t),
++					   args, complain, in_decl);
++  if (vars == error_mark_node)
++    return error_mark_node;
++  tree expr = tsubst_constraint (PARM_CONSTR_OPERAND (t), args,
++				 complain, in_decl);
++  if (expr == error_mark_node)
++    return error_mark_node;
++  return build_nt (PARM_CONSTR, vars, expr);
++}
++
+ /* Substitute ARGS into the simple requirement T. Note that
+    substitution may result in an ill-formed expression without
+    causing the program to be ill-formed. In such cases, the
+    requirement wraps an error_mark_node. */
++
+ inline tree
+ tsubst_simple_requirement (tree t, tree args,
+                            tsubst_flags_t complain, tree in_decl)
+@@ -1627,6 +1834,8 @@
+   return finish_nested_requirement (expr);
+ }
+ 
++/* Substitute ARGS into the requirement T.  */
++
+ inline tree
+ tsubst_requirement (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+ {
+@@ -1662,7 +1871,8 @@
+       r = tree_cons (NULL_TREE, e, r);
+       t = TREE_CHAIN (t);
+     }
+-  return r;
++  /* Ensure that the order of constraints is the same as the original.  */
++  return nreverse (r);
+ }
+ 
+ } /* namespace */
+@@ -1696,6 +1906,7 @@
+ 
+ /* Substitute ARGS into the constraint information CI, producing a new
+    constraint record. */
++
+ tree
+ tsubst_constraint_info (tree t, tree args,
+                         tsubst_flags_t complain, tree in_decl)
+@@ -1714,7 +1925,40 @@
+   return build_constraints (tmpl_constr, decl_constr);
+ }
+ 
++/* Substitute ARGS into the constraint T. */
+ 
++tree
++tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl)
++{
++  if (t == NULL_TREE)
++    return t;
++  switch (TREE_CODE (t))
++  {
++  case PRED_CONSTR:
++    return tsubst_predicate_constraint (t, args, complain, in_decl);
++  case CHECK_CONSTR:
++    return tsubst_check_constraint (t, args, complain, in_decl);
++  case CONJ_CONSTR:
++  case DISJ_CONSTR:
++    return tsubst_logical_operator (t, args, complain, in_decl);
++  case PARM_CONSTR:
++    return tsubst_parameterized_constraint (t, args, complain, in_decl);
++  case EXPR_CONSTR:
++    return tsubst_expr_constr (t, args, complain, in_decl);
++  case TYPE_CONSTR:
++    return tsubst_type_constr (t, args, complain, in_decl);
++  case ICONV_CONSTR:
++    return tsubst_implicit_conversion_constr (t, args, complain, in_decl);
++  case DEDUCT_CONSTR:
++    return tsubst_argument_deduction_constr (t, args, complain, in_decl);
++  case EXCEPT_CONSTR:
++    return tsubst_exception_constr (t, args, complain, in_decl);
++  default:
++    gcc_unreachable ();
++  }
++  return error_mark_node;
++}
++
+ /*---------------------------------------------------------------------------
+                         Constraint satisfaction
+ ---------------------------------------------------------------------------*/
+@@ -1738,11 +1982,14 @@
+      gen_elem_of_pack_expansion_instantiation will check that each element of
+      the expansion is satisfied.  */
+   tree exprs = tsubst_pack_expansion (t, args, complain, in_decl);
++
+   if (exprs == error_mark_node)
+     return boolean_false_node;
+-  int n = TREE_VEC_LENGTH (exprs);
+ 
+-  for (int i = 0; i < n; ++i)
++  /* TODO: It might be better to normalize each expanded term
++     and evaluate them separately. That would provide better
++     opportunities for diagnostics.  */
++  for (int i = 0; i < TREE_VEC_LENGTH (exprs); ++i)
+     if (TREE_VEC_ELT (exprs, i) != boolean_true_node)
+       return boolean_false_node;
+   return boolean_true_node;
+@@ -1760,12 +2007,14 @@
+ satisfy_predicate_constraint (tree t, tree args,
+                               tsubst_flags_t complain, tree in_decl)
+ {
+-  tree original = TREE_OPERAND (t, 0);
++  tree expr = TREE_OPERAND (t, 0);
+ 
+   /* We should never have a naked pack expansion in a predicate constraint.  */
+-  gcc_assert (TREE_CODE (original) != EXPR_PACK_EXPANSION);
++  gcc_assert (TREE_CODE (expr) != EXPR_PACK_EXPANSION);
+ 
+-  tree expr = tsubst_expr (original, args, complain, in_decl, false);
++  /* If substitution into the expression fails, the constraint
++     is not satisfied.  */
++  expr = tsubst_expr (expr, args, complain, in_decl, false);
+   if (expr == error_mark_node)
+     return boolean_false_node;
+ 
+@@ -1781,10 +2030,39 @@
+       return boolean_false_node;
+     }
+ 
+-  tree value = cxx_constant_value (expr);
+-  return value;
++  return cxx_constant_value (expr);
+ }
+ 
++/* A concept check constraint like C<CARGS> is satisfied if substituting ARGS
++   into CARGS succeeds and C is satisfied for the resulting arguments.  */
++
++tree
++satisfy_check_constraint (tree t, tree args,
++                          tsubst_flags_t complain, tree in_decl)
++{
++  tree decl = CHECK_CONSTR_CONCEPT (t);
++  tree tmpl = DECL_TI_TEMPLATE (decl);
++  tree cargs = CHECK_CONSTR_ARGS (t);
++
++  /* Instantiate the concept check arguments.  */
++  tree targs = tsubst (cargs, args, tf_none, NULL_TREE);
++  if (targs == error_mark_node)
++    return boolean_false_node;
++
++  /* Search for a previous value.  */
++  if (tree prev = lookup_concept_satisfaction (tmpl, targs))
++    return prev;
++
++  /* Expand the concept; failure here implies non-satisfaction.  */
++  tree def = expand_concept (decl, targs);
++  if (def == error_mark_node)
++    return memoize_concept_satisfaction (tmpl, args, boolean_false_node);
++
++  /* Recursively satisfy the constraint.  */
++  tree result = satisfy_constraint_1 (def, targs, complain, in_decl);
++  return memoize_concept_satisfaction (tmpl, targs, result);
++}
++
+ /* Check an expression constraint. The constraint is satisfied if
+    substitution succeeds ([temp.constr.expr]).
+ 
+@@ -1803,7 +2081,6 @@
+     return boolean_false_node;
+   if (!perform_deferred_access_checks (tf_none))
+     return boolean_false_node;
+-
+   return boolean_true_node;
+ }
+ 
+@@ -1822,7 +2099,6 @@
+     return boolean_false_node;
+   if (!perform_deferred_access_checks (complain))
+     return boolean_false_node;
+-
+   return boolean_true_node;
+ }
+ 
+@@ -1932,11 +2208,8 @@
+ {
+   tree t0 = satisfy_constraint_1 (TREE_OPERAND (t, 0), args, complain, in_decl);
+   if (t0 == boolean_false_node)
+-    return t0;
+-  tree t1 = satisfy_constraint_1 (TREE_OPERAND (t, 1), args, complain, in_decl);
+-  if (t1 == boolean_false_node)
+-    return t1;
+-  return boolean_true_node;
++    return boolean_false_node;
++  return satisfy_constraint_1 (TREE_OPERAND (t, 1), args, complain, in_decl);
+ }
+ 
+ /* Check that the disjunction of constraints is satisfied. Note
+@@ -1949,10 +2222,7 @@
+   tree t0 = satisfy_constraint_1 (TREE_OPERAND (t, 0), args, complain, in_decl);
+   if (t0 == boolean_true_node)
+     return boolean_true_node;
+-  tree t1 = satisfy_constraint_1 (TREE_OPERAND (t, 1), args, complain, in_decl);
+-  if (t1 == boolean_true_node)
+-    return boolean_true_node;
+-  return boolean_false_node;
++  return satisfy_constraint_1 (TREE_OPERAND (t, 1), args, complain, in_decl);
+ }
+ 
+ /* Dispatch to an appropriate satisfaction routine depending on the
+@@ -1974,6 +2244,9 @@
+   case PRED_CONSTR:
+     return satisfy_predicate_constraint (t, args, complain, in_decl);
+ 
++  case CHECK_CONSTR:
++    return satisfy_check_constraint (t, args, complain, in_decl);
++
+   case EXPR_CONSTR:
+     return satisfy_expression_constraint (t, args, complain, in_decl);
+ 
+@@ -2014,9 +2287,12 @@
+ tree
+ satisfy_constraint (tree t, tree args)
+ {
++  auto_timevar time (TV_CONSTRAINT_SAT);
++
+   /* Turn off template processing. Constraint satisfaction only applies
+-     to non-dependent terms, so we want full checking here.  */
+-  processing_template_decl_sentinel sentinel (true);
++     to non-dependent terms, so we want to ensure full checking here.  */
++  processing_template_decl_sentinel proc (true);
++
+   /* Avoid early exit in tsubst and tsubst_copy from null args; since earlier
+      substitution was done with processing_template_decl forced on, there will
+      be expressions that still need semantic processing, possibly buried in
+@@ -2023,6 +2299,7 @@
+      decltype or a template argument.  */
+   if (args == NULL_TREE)
+     args = make_tree_vec (1);
++
+   return satisfy_constraint_1 (t, args, tf_none, NULL_TREE);
+ }
+ 
+@@ -2042,11 +2319,13 @@
+   if (args && uses_template_parms (args))
+     return boolean_true_node;
+ 
+-  /* Invalid requirements cannot be satisfied. */
+-  if (!valid_constraints_p (ci))
+-    return boolean_false_node;
++  /* Check if we've seen a previous result. */
++  if (tree prev = lookup_constraint_satisfaction (ci, args))
++    return prev;
+ 
+-  return satisfy_constraint (CI_NORMALIZED_CONSTRAINTS (ci), args);
++  /* Actually test for satisfaction. */
++  tree result = satisfy_constraint (CI_ASSOCIATED_CONSTRAINTS (ci), args);
++  return memoize_constraint_satisfaction (ci, args, result);
+ }
+ 
+ } /* namespace */
+@@ -2059,7 +2338,7 @@
+ evaluate_constraints (tree constr, tree args)
+ {
+   gcc_assert (constraint_p (constr));
+-  return satisfy_constraint (normalize_constraint (constr), args);
++  return satisfy_constraint (constr, args);
+ }
+ 
+ /* Evaluate the function concept FN by substituting its own args
+@@ -2070,14 +2349,7 @@
+ tree
+ evaluate_function_concept (tree fn, tree args)
+ {
+-  ++processing_template_decl;
+-  /* We lift using DECL_TI_ARGS because we want to delay producing
+-     non-dependent expressions until we're doing satisfaction.  We can't just
+-     go without any substitution because we need to lower the level of 'auto's
+-     in type deduction constraints.  */
+-  tree constr = transform_expression (lift_function_definition
+-				      (fn, DECL_TI_ARGS (fn)));
+-  --processing_template_decl;
++  tree constr = build_nt (CHECK_CONSTR, fn, args);
+   return satisfy_constraint (constr, args);
+ }
+ 
+@@ -2087,12 +2359,9 @@
+    boolean_false_node otherwise.  */
+ 
+ tree
+-evaluate_variable_concept (tree decl, tree args)
++evaluate_variable_concept (tree var, tree args)
+ {
+-  ++processing_template_decl;
+-  tree constr = transform_expression (lift_variable_initializer
+-				      (decl, DECL_TI_ARGS (decl)));
+-  --processing_template_decl;
++  tree constr = build_nt (CHECK_CONSTR, var, args);
+   return satisfy_constraint (constr, args);
+ }
+ 
+@@ -2103,9 +2372,7 @@
+ tree
+ evaluate_constraint_expression (tree expr, tree args)
+ {
+-  ++processing_template_decl;
+-  tree constr = transform_expression (lift_expression (expr));
+-  --processing_template_decl;
++  tree constr = normalize_expression (expr);
+   return satisfy_constraint (constr, args);
+ }
+ 
+@@ -2165,7 +2432,6 @@
+ 
+ } /* namespace */
+ 
+-
+ /*---------------------------------------------------------------------------
+                 Semantic analysis of requires-expressions
+ ---------------------------------------------------------------------------*/
+@@ -2309,6 +2575,7 @@
+ ---------------------------------------------------------------------------*/
+ 
+ /* Returns true when the the constraints in A subsume those in B.  */
++
+ bool
+ subsumes_constraints (tree a, tree b)
+ {
+@@ -2332,6 +2599,7 @@
+ 
+    Returns 1 if A is more constrained than B, -1 if B is more constrained
+    than A, and 0 otherwise. */
++
+ int
+ more_constrained (tree d1, tree d2)
+ {
+@@ -2348,6 +2616,7 @@
+ /* Returns true if D1 is at least as constrained as D2. That is, the
+    associated constraints of D1 subsume those of D2, or both declarations
+    are unconstrained. */
++
+ bool
+ at_least_as_constrained (tree d1, tree d2)
+ {
+@@ -2359,49 +2628,71 @@
+ 
+ /*---------------------------------------------------------------------------
+                         Constraint diagnostics
++
++FIXME: Normalize expressions into constraints before evaluating them.
++This should be the general pattern for all such diagnostics.
+ ---------------------------------------------------------------------------*/
+ 
+-/* The diagnosis of constraints performs a combination of
+-   normalization and satisfaction testing. We recursively
+-   walk through the conjunction (or disjunctions) of associated
+-   constraints, testing each sub-expression in turn.
++/* The number of detailed constraint failures.  */
+ 
+-   We currently restrict diagnostics to just the top-level
+-   conjunctions within the associated constraints. A fully
+-   recursive walk is possible, but it can generate a lot
+-   of errors. */
++int constraint_errors = 0;
+ 
++/* Do not generate errors after diagnosing this number of constraint
++   failures.
+ 
+-namespace {
++   FIXME: This is a really arbitrary number. Provide better control of
++   constraint diagnostics with a command line option.  */
+ 
+-void diagnose_expression (location_t, tree, tree);
+-void diagnose_constraint (location_t, tree, tree);
++int constraint_thresh = 20;
+ 
+-/* Diagnose a conjunction of constraints. */
+-void
+-diagnose_logical_operation (location_t loc, tree t, tree args)
++
++/* Returns true if we should elide the diagnostic for a constraint failure.
++   This is the case when the number of errors has exceeded the pre-configured
++   threshold.  */
++
++inline bool
++elide_constraint_failure_p ()
+ {
+-  diagnose_expression (loc, TREE_OPERAND (t, 0), args);
+-  diagnose_expression (loc, TREE_OPERAND (t, 0), args);
++  bool ret = constraint_thresh <= constraint_errors;
++  ++constraint_errors;
++  return ret;
+ }
+ 
+-/* Determine if the trait expression T is satisfied by ARGS.
+-   Emit a precise diagnostic if it is not. */
++/* Returns the number of undiagnosed errors. */
++
++inline int
++undiagnosed_constraint_failures ()
++{
++  return constraint_errors - constraint_thresh;
++}
++
++/* The diagnosis of constraints performs a combination of normalization
++   and satisfaction testing. We recursively walk through the conjunction or
++   disjunction of associated constraints, testing each sub-constraint in
++   turn.  */
++
++namespace {
++
++void diagnose_constraint (location_t, tree, tree, tree);
++
++/* Emit a specific diagnostics for a failed trait.  */
++
+ void
+-diagnose_trait_expression (location_t loc, tree t, tree args)
++diagnose_trait_expression (location_t loc, tree, tree cur, tree args)
+ {
+-  if (constraint_expression_satisfied_p (t, args))
++  if (constraint_expression_satisfied_p (cur, args))
+     return;
++  if (elide_constraint_failure_p())
++    return;
+ 
+-  /* Rebuild the trait expression so we can diagnose the
+-     specific failure. */
++  tree expr = PRED_CONSTR_EXPR (cur);
+   ++processing_template_decl;
+-  tree expr = tsubst_expr (t, args, tf_none, NULL_TREE, false);
++  expr = tsubst_expr (expr, args, tf_none, NULL_TREE, false);
+   --processing_template_decl;
+ 
+   tree t1 = TRAIT_EXPR_TYPE1 (expr);
+   tree t2 = TRAIT_EXPR_TYPE2 (expr);
+-  switch (TRAIT_EXPR_KIND (t))
++  switch (TRAIT_EXPR_KIND (expr))
+     {
+     case CPTK_HAS_NOTHROW_ASSIGN:
+       inform (loc, "  %qT is not nothrow copy assignable", t1);
+@@ -2471,93 +2762,52 @@
+     }
+ }
+ 
+-/* Determine if the call expression T, when normalized as a constraint,
+-   is satisfied by ARGS.
++/* Diagnose the expression of a predicate constraint.  */
+ 
+-   TODO: If T is refers to a concept, We could recursively analyze
+-   its definition to identify the exact failure, but that could
+-   emit a *lot* of error messages (defeating the purpose of
+-   improved diagnostics). Consider adding a flag to control the
+-   depth of diagnostics. */
+ void
+-diagnose_call_expression (location_t loc, tree t, tree args)
++diagnose_other_expression (location_t loc, tree, tree cur, tree args)
+ {
+-  if (constraint_expression_satisfied_p (t, args))
++  if (constraint_expression_satisfied_p (cur, args))
+     return;
++  if (elide_constraint_failure_p())
++    return;
++  inform (loc, "%qE evaluated to false", cur);
++}
+ 
+-  /* Rebuild the expression for the purpose of diagnostics. */
+-  ++processing_template_decl;
+-  tree expr = tsubst_expr (t, args, tf_none, NULL_TREE, false);
+-  --processing_template_decl;
++/* Do our best to infer meaning from predicates.  */
+ 
+-  /* If the function call is known to be a concept check, then
+-     diagnose it differently (i.e., we may recurse). */
+-  if (resolve_constraint_check (t))
+-    inform (loc, "  concept %qE was not satisfied", expr);
+-  else
+-    inform (loc, "  %qE evaluated to false", expr);
+-}
+-
+-/* Determine if the template-id T, when normalized as a constraint
+-   is satisfied by ARGS. */
+-void
+-diagnose_template_id (location_t loc, tree t, tree args)
++inline void
++diagnose_predicate_constraint (location_t loc, tree orig, tree cur, tree args)
+ {
+-  /* Check for invalid template-ids. */
+-  if (!variable_template_p (TREE_OPERAND (t, 0)))
+-    {
+-      inform (loc, "  invalid constraint %qE", t);
+-      return;
+-    }
+-
+-  if (constraint_expression_satisfied_p (t, args))
+-    return;
+-
+-  /* Rebuild the expression for the purpose of diagnostics. */
+-  ++processing_template_decl;
+-  tree expr = tsubst_expr (t, args, tf_none, NULL_TREE, false);
+-  --processing_template_decl;
+-
+-  tree var = DECL_TEMPLATE_RESULT (TREE_OPERAND (t, 0));
+-  if (DECL_DECLARED_CONCEPT_P (var))
+-    inform (loc, "  concept %qE was not satisfied", expr);
++  if (TREE_CODE (PRED_CONSTR_EXPR (cur)) == TRAIT_EXPR)
++    diagnose_trait_expression (loc, orig, cur, args);
+   else
+-    inform (loc, "  %qE evaluated to false", expr);
++    diagnose_other_expression (loc, orig, cur, args);
+ }
+ 
+-/* Determine if the requires-expression, when normalized as a
+-   constraint is satisfied by ARGS.
++/* Diagnose a failed pack expansion, possibly containing constraints.  */
+ 
+-   TODO: Build sets of expressions, types, and constraints
+-   based on the requirements in T and emit specific diagnostics
+-   for those. */
+ void
+-diagnose_requires_expression (location_t loc, tree t, tree args)
++diagnose_pack_expansion (location_t loc, tree, tree cur, tree args)
+ {
+-  if (constraint_expression_satisfied_p (t, args))
++  if (constraint_expression_satisfied_p (cur, args))
+     return;
+-  inform (loc, "requirements not satisfied");
+-}
+-
+-void
+-diagnose_pack_expansion (location_t loc, tree t, tree args)
+-{
+-  if (constraint_expression_satisfied_p (t, args))
++  if (elide_constraint_failure_p())
+     return;
+ 
+   /* Make sure that we don't have naked packs that we don't expect. */
+-  if (!same_type_p (TREE_TYPE (t), boolean_type_node))
++  if (!same_type_p (TREE_TYPE (cur), boolean_type_node))
+     {
+-      inform (loc, "invalid pack expansion in constraint %qE", t);
++      inform (loc, "invalid pack expansion in constraint %qE", cur);
+       return;
+     }
+ 
+-  inform (loc, "  in the expansion of %qE", t);
++  inform (loc, "in the expansion of %qE", cur);
+ 
+   /* Get the vector of expanded arguments. Note that n must not
+      be 0 since this constraint is not satisfied.  */
+   ++processing_template_decl;
+-  tree exprs = tsubst_pack_expansion (t, args, tf_none, NULL_TREE);
++  tree exprs = tsubst_pack_expansion (cur, args, tf_none, NULL_TREE);
+   --processing_template_decl;
+   if (exprs == error_mark_node)
+     {
+@@ -2576,84 +2826,278 @@
+     }
+ }
+ 
+-/* Diagnose an expression that would be characterized as
+-   a predicate constraint. */
++/* Diagnose a potentially unsatisfied concept check constraint DECL<CARGS>.
++   Parameters are as for diagnose_constraint.  */
++
+ void
+-diagnose_other_expression (location_t loc, tree t, tree args)
++diagnose_check_constraint (location_t loc, tree orig, tree cur, tree args)
+ {
+-  if (constraint_expression_satisfied_p (t, args))
++  if (constraints_satisfied_p (cur, args))
+     return;
+-  inform (loc, "  %qE evaluated to false", t);
++
++  tree decl = CHECK_CONSTR_CONCEPT (cur);
++  tree cargs = CHECK_CONSTR_ARGS (cur);
++  tree tmpl = DECL_TI_TEMPLATE (decl);
++  tree check = build_nt (CHECK_CONSTR, decl, cargs);
++
++  /* Instantiate the concept check arguments.  */
++  tree targs = tsubst (cargs, args, tf_none, NULL_TREE);
++  if (targs == error_mark_node)
++    {
++      if (elide_constraint_failure_p ())
++        return;
++      inform (loc, "invalid use of the concept %qE", check);
++      tsubst (cargs, args, tf_warning_or_error, NULL_TREE);
++      return;
++    }
++
++  tree sub = build_tree_list (tmpl, targs);
++  /* Update to the expanded definitions. */
++  cur = expand_concept (decl, targs);
++  if (cur == error_mark_node)
++    {
++      if (elide_constraint_failure_p ())
++        return;
++      inform (loc, "in the expansion of concept %qE %S", check, sub);
++      cur = get_concept_definition (decl);
++      tsubst_expr (cur, targs, tf_warning_or_error, NULL_TREE, false);
++      return;
++    }
++
++  orig = get_concept_definition (CHECK_CONSTR_CONCEPT (orig));
++  orig = normalize_expression (orig);
++
++  location_t dloc = DECL_SOURCE_LOCATION (decl);
++  inform (dloc, "within %qS", sub);
++  diagnose_constraint (dloc, orig, cur, targs);
+ }
+ 
++/* Diagnose a potentially unsatisfied conjunction or disjunction.  Parameters
++   are as for diagnose_constraint.  */
++
+ void
+-diagnose_expression (location_t loc, tree t, tree args)
++diagnose_logical_constraint (location_t loc, tree orig, tree cur, tree args)
+ {
+-  switch (TREE_CODE (t))
+-    {
+-    case TRUTH_ANDIF_EXPR:
+-      diagnose_logical_operation (loc, t, args);
+-      break;
++  tree t0 = TREE_OPERAND (cur, 0);
++  tree t1 = TREE_OPERAND (cur, 1);
++  if (!constraints_satisfied_p (t0, args))
++    diagnose_constraint (loc, TREE_OPERAND (orig, 0), t0, args);
++  else if (TREE_CODE (orig) == TRUTH_ORIF_EXPR)
++    return;
++  if (!constraints_satisfied_p (t1, args))
++    diagnose_constraint (loc, TREE_OPERAND (orig, 1), t1, args);
++}
+ 
+-    case TRUTH_ORIF_EXPR:
+-      diagnose_logical_operation (loc, t, args);
+-      break;
++/* Diagnose a potential expression constraint failure. */
+ 
+-    case CALL_EXPR:
+-      diagnose_call_expression (loc, t, args);
+-      break;
++void
++diagnose_expression_constraint (location_t loc, tree orig, tree cur, tree args)
++{
++  if (constraints_satisfied_p (cur, args))
++    return;
++  if (elide_constraint_failure_p())
++    return;
+ 
+-    case TEMPLATE_ID_EXPR:
+-      diagnose_template_id (loc, t, args);
+-      break;
++  tree expr = EXPR_CONSTR_EXPR (orig);
++  inform (loc, "the required expression %qE would be ill-formed", expr);
+ 
+-    case REQUIRES_EXPR:
+-      diagnose_requires_expression (loc, t, args);
+-      break;
++  // TODO: We should have a flag that controls this substitution.
++  // I'm finding it very useful for resolving concept check errors.
+ 
+-    case TRAIT_EXPR:
+-      diagnose_trait_expression (loc, t, args);
+-      break;
++  // inform (input_location, "==== BEGIN DUMP ====");
++  // tsubst_expr (EXPR_CONSTR_EXPR (orig), args, tf_warning_or_error, NULL_TREE, false);
++  // inform (input_location, "==== END DUMP ====");
++}
+ 
+-    case EXPR_PACK_EXPANSION:
+-      diagnose_pack_expansion (loc, t, args);
+-      break;
++/* Diagnose a potentially failed type constraint. */
+ 
+-    default:
+-      diagnose_other_expression (loc, t, args);
+-      break;
++void
++diagnose_type_constraint (location_t loc, tree orig, tree cur, tree args)
++{
++  if (constraints_satisfied_p (cur, args))
++    return;
++  if (elide_constraint_failure_p())
++    return;
++
++  tree type = TYPE_CONSTR_TYPE (orig);
++  inform (loc, "the required type %qT would be ill-formed", type);
++}
++
++/* Diagnose a potentially unsatisfied conversion constraint. */
++
++void
++diagnose_implicit_conversion_constraint (location_t loc, tree orig, tree cur,
++					 tree args)
++{
++  if (constraints_satisfied_p (cur, args))
++    return;
++
++  /* The expression and type will previously have been substituted into,
++     and therefore may already be an error. Also, we will have already
++     diagnosed substitution failures into an expression since this must be
++     part of a compound requirement.  */
++  tree expr = ICONV_CONSTR_EXPR (cur);
++  if (error_operand_p (expr))
++    return;
++
++  /* Don't elide a previously diagnosed failure.  */
++  if (elide_constraint_failure_p())
++    return;
++
++  tree type = ICONV_CONSTR_TYPE (cur);
++  if (error_operand_p (type))
++    {
++      inform (loc, "substitution into type %qT failed",
++	      ICONV_CONSTR_TYPE (orig));
++      return;
+     }
++
++  inform(loc, "%qE is not implicitly convertible to %qT", expr, type);
+ }
+ 
+-inline void
+-diagnose_predicate_constraint (location_t loc, tree t, tree args)
++/* Diagnose an argument deduction constraint. */
++
++void
++diagnose_argument_deduction_constraint (location_t loc, tree orig, tree cur,
++					tree args)
+ {
+-  diagnose_expression (loc, PRED_CONSTR_EXPR (t), args);
++  if (constraints_satisfied_p (cur, args))
++    return;
++
++  /* The expression and type will previously have been substituted into,
++     and therefore may already be an error. Also, we will have already
++     diagnosed substution failures into an expression since this must be
++     part of a compound requirement.  */
++  tree expr = DEDUCT_CONSTR_EXPR (cur);
++  if (error_operand_p (expr))
++    return;
++
++  /* Don't elide a previously diagnosed failure.  */
++  if (elide_constraint_failure_p ())
++    return;
++
++  tree pattern = DEDUCT_CONSTR_PATTERN (cur);
++  if (error_operand_p (pattern))
++    {
++      inform (loc, "substitution into type %qT failed",
++	      DEDUCT_CONSTR_PATTERN (orig));
++      return;
++    }
++
++  inform (loc, "unable to deduce placeholder type %qT from %qE",
++	  pattern, expr);
+ }
+ 
+-inline void
+-diagnose_conjunction (location_t loc, tree t, tree args)
++/* Diagnose an exception constraint. */
++
++void
++diagnose_exception_constraint (location_t loc, tree orig, tree cur, tree args)
+ {
+-  diagnose_constraint (loc, TREE_OPERAND (t, 0), args);
+-  diagnose_constraint (loc, TREE_OPERAND (t, 1), args);
++  if (constraints_satisfied_p (cur, args))
++    return;
++  if (elide_constraint_failure_p ())
++    return;
++
++  /* Rebuild a noexcept expression. */
++  tree expr = EXCEPT_CONSTR_EXPR (cur);
++  if (error_operand_p (expr))
++    return;
++
++  inform (loc, "%qE evaluated to false", EXCEPT_CONSTR_EXPR (orig));
+ }
+ 
+-/* Diagnose the constraint T for the given ARGS. This is only
+-   ever invoked on the associated constraints, so we can
+-   only have conjunctions of predicate constraints. */
++/* Diagnose a potentially unsatisfied parameterized constraint.  */
++
+ void
+-diagnose_constraint (location_t loc, tree t, tree args)
++diagnose_parameterized_constraint (location_t loc, tree orig, tree cur,
++				   tree args)
+ {
+-  switch (TREE_CODE (t))
++  if (constraints_satisfied_p (cur, args))
++    return;
++
++  local_specialization_stack stack;
++  tree parms = PARM_CONSTR_PARMS (cur);
++  tree vars = tsubst_constraint_variables (parms, args, tf_warning_or_error,
++					   NULL_TREE);
++  if (vars == error_mark_node)
+     {
++      if (elide_constraint_failure_p ())
++        return;
++
++      /* TODO: Check which variable failed and use orig to diagnose
++         that substitution error.  */
++      inform (loc, "failed to instantiate constraint variables");
++      return;
++    }
++
++  /* TODO: It would be better write these in a list. */
++  while (vars)
++    {
++      inform (loc, "    with %q#D", vars);
++      vars = TREE_CHAIN (vars);
++    }
++  orig = PARM_CONSTR_OPERAND (orig);
++  cur = PARM_CONSTR_OPERAND (cur);
++  return diagnose_constraint (loc, orig, cur, args);
++}
++
++/* Diagnose the constraint CUR for the given ARGS. This is only ever invoked
++   on the associated constraints, so we can only have conjunctions of
++   predicate constraints.  The ORIGinal (dependent) constructs follow
++   the current constraints to enable better diagnostics.  Note that ORIG
++   and CUR must be the same kinds of node, except when CUR is an error.  */
++
++void
++diagnose_constraint (location_t loc, tree orig, tree cur, tree args)
++{
++  switch (TREE_CODE (cur))
++    {
++    case EXPR_CONSTR:
++      diagnose_expression_constraint (loc, orig, cur, args);
++      break;
++
++    case TYPE_CONSTR:
++      diagnose_type_constraint (loc, orig, cur, args);
++      break;
++
++    case ICONV_CONSTR:
++      diagnose_implicit_conversion_constraint (loc, orig, cur, args);
++      break;
++
++    case DEDUCT_CONSTR:
++      diagnose_argument_deduction_constraint (loc, orig, cur, args);
++      break;
++
++    case EXCEPT_CONSTR:
++      diagnose_exception_constraint (loc, orig, cur, args);
++      break;
++
+     case CONJ_CONSTR:
+-      diagnose_conjunction (loc, t, args);
++    case DISJ_CONSTR:
++      diagnose_logical_constraint (loc, orig, cur, args);
+       break;
+ 
+     case PRED_CONSTR:
+-      diagnose_predicate_constraint (loc, t, args);
++      diagnose_predicate_constraint (loc, orig, cur, args);
+       break;
+ 
++    case PARM_CONSTR:
++      diagnose_parameterized_constraint (loc, orig, cur, args);
++      break;
++
++    case CHECK_CONSTR:
++      diagnose_check_constraint (loc, orig, cur, args);
++      break;
++
++    case EXPR_PACK_EXPANSION:
++      diagnose_pack_expansion (loc, orig, cur, args);
++      break;
++
++    case ERROR_MARK:
++      /* TODO: Can we improve the diagnostic with the original?  */
++      inform (input_location, "ill-formed constraint");
++      break;
++
+     default:
+       gcc_unreachable ();
+       break;
+@@ -2676,16 +3120,10 @@
+ 	args = TI_ARGS (ti);
+     }
+ 
+-  /* Check that the constraints are actually valid.  */
++  /* Recursively diagnose the associated constraints.  */
+   tree ci = get_constraints (decl);
+-  if (!valid_constraints_p (ci))
+-    {
+-      inform (loc, "    invalid constraints");
+-      return;
+-    }
+-
+-  /* Recursively diagnose the associated constraints.  */
+-  diagnose_constraint (loc, CI_ASSOCIATED_CONSTRAINTS (ci), args);
++  tree t = CI_ASSOCIATED_CONSTRAINTS (ci);
++  diagnose_constraint (loc, t, t, args);
+ }
+ 
+ } // namespace
+@@ -2697,8 +3135,17 @@
+ void
+ diagnose_constraints (location_t loc, tree t, tree args)
+ {
++  constraint_errors = 0;
++
+   if (constraint_p (t))
+-    diagnose_constraint (loc, t, args);
++    diagnose_constraint (loc, t, t, args);
++  else if (DECL_P (t))
++    diagnose_declaration_constraints (loc, t, args);
+   else
+-    diagnose_declaration_constraints (loc, t, args);
++    gcc_unreachable ();
++
++  /* Note the number of elided failures. */
++  int n = undiagnosed_constraint_failures ();
++  if (n > 0)
++    inform (loc, "... and %d more constraint errors not shown", n);
+ }
 Index: gcc/cp/decl2.c
 ===================================================================
 --- a/src/gcc/cp/decl2.c	(.../tags/gcc_6_1_0_release)
@@ -19220,7 +30425,70 @@ Index: gcc/cp/parser.c
 ===================================================================
 --- a/src/gcc/cp/parser.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/cp/parser.c	(.../branches/gcc-6-branch)
-@@ -13793,8 +13793,9 @@
+@@ -9747,10 +9747,12 @@
+ 
+     ok &= cp_parser_lambda_declarator_opt (parser, lambda_expr);
+ 
++    if (ok && cp_parser_error_occurred (parser))
++      ok = false;
++
+     if (ok)
+       {
+-	if (!cp_parser_error_occurred (parser)
+-	    && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
++	if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
+ 	    && cp_parser_start_tentative_firewall (parser))
+ 	  start = token;
+ 	cp_parser_lambda_body (parser, lambda_expr);
+@@ -11184,11 +11186,17 @@
+ 		     bool ivdep)
+ {
+   tree stmt, range_expr;
++  cxx_binding *binding = NULL;
++  tree name = NULL_TREE;
+ 
+   /* Get the range declaration momentarily out of the way so that
+      the range expression doesn't clash with it. */
+   if (range_decl != error_mark_node)
+-    pop_binding (DECL_NAME (range_decl), range_decl);
++    {
++      name = DECL_NAME (range_decl);
++      binding = IDENTIFIER_BINDING (name);
++      IDENTIFIER_BINDING (name) = binding->previous;
++    }
+ 
+   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+     {
+@@ -11200,7 +11208,10 @@
+ 
+   /* Put the range declaration back into scope. */
+   if (range_decl != error_mark_node)
+-    push_binding (DECL_NAME (range_decl), range_decl, current_binding_level);
++    {
++      binding->previous = IDENTIFIER_BINDING (name);
++      IDENTIFIER_BINDING (name) = binding;
++    }
+ 
+   /* If in template, STMT is converted to a normal for-statement
+      at instantiation. If not, it is done just ahead. */
+@@ -12434,8 +12445,15 @@
+       if (token->type == CPP_COMMA)
+ 	/* will be consumed next time around */;
+       /* If it's a `;', we are done.  */
+-      else if (token->type == CPP_SEMICOLON || maybe_range_for_decl)
++      else if (token->type == CPP_SEMICOLON)
+ 	break;
++      else if (maybe_range_for_decl)
++	{
++	  if (declares_class_or_enum && token->type == CPP_COLON)
++	    pedwarn (decl_specifiers.locations[ds_type_spec], 0,
++		     "types may not be defined in a for-range-declaration");
++	  break;
++	}
+       /* Anything else is an error.  */
+       else
+ 	{
+@@ -13793,8 +13811,9 @@
  	    /* Consume the `[' token.  */
  	    cp_lexer_consume_token (parser->lexer);
  	    /* Look for the `]' token.  */
@@ -19232,7 +30500,25 @@ Index: gcc/cp/parser.c
  	    id = ansi_opname (op == NEW_EXPR
  			      ? VEC_NEW_EXPR : VEC_DELETE_EXPR);
  	  }
-@@ -21178,7 +21179,7 @@
+@@ -14686,10 +14705,13 @@
+ 	cp_parser_require (parser, CPP_GREATER, RT_GREATER);
+ 
+         // If template requirements are present, parse them.
+-	tree reqs = get_shorthand_constraints (current_template_parms);
+-	if (tree r = cp_parser_requires_clause_opt (parser))
+-	  reqs = conjoin_constraints (reqs, make_predicate_constraint (r));
+-	TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
++	if (flag_concepts)
++          {
++	    tree reqs = get_shorthand_constraints (current_template_parms);
++	    if (tree r = cp_parser_requires_clause_opt (parser))
++              reqs = conjoin_constraints (reqs, normalize_expression (r));
++	    TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
++          }
+ 
+ 	/* Look for the `class' or 'typename' keywords.  */
+ 	cp_parser_type_parameter_key (parser);
+@@ -21178,7 +21200,7 @@
  	     resolution operator, object, function, and enumerator
  	     names are ignored.  */
  	  if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
@@ -19241,7 +30527,7 @@ Index: gcc/cp/parser.c
  	  /* Look up the name.  */
  	  decl = cp_parser_lookup_name (parser, identifier,
  					tag_type,
-@@ -24569,6 +24570,20 @@
+@@ -24569,6 +24591,20 @@
  
  /* Support Functions */
  
@@ -19262,7 +30548,7 @@ Index: gcc/cp/parser.c
  /* Looks up NAME in the current scope, as given by PARSER->SCOPE.
     NAME should have one of the representations used for an
     id-expression.  If NAME is the ERROR_MARK_NODE, the ERROR_MARK_NODE
-@@ -24705,7 +24720,7 @@
+@@ -24705,7 +24741,7 @@
  	     errors may be issued.  Even if we rollback the current
  	     tentative parse, those errors are valid.  */
  	  decl = lookup_qualified_name (parser->scope, name,
@@ -19271,7 +30557,7 @@ Index: gcc/cp/parser.c
  					/*complain=*/true);
  
  	  /* 3.4.3.1: In a lookup in which the constructor is an acceptable
-@@ -24726,7 +24741,7 @@
+@@ -24726,7 +24762,7 @@
  	      && DECL_SELF_REFERENCE_P (decl)
  	      && same_type_p (DECL_CONTEXT (decl), parser->scope))
  	    decl = lookup_qualified_name (parser->scope, ctor_identifier,
@@ -19280,7 +30566,7 @@ Index: gcc/cp/parser.c
  					  /*complain=*/true);
  
  	  /* If we have a single function from a using decl, pull it out.  */
-@@ -24782,7 +24797,7 @@
+@@ -24782,7 +24818,7 @@
  	decl = lookup_member (object_type,
  			      name,
  			      /*protect=*/0,
@@ -19289,7 +30575,7 @@ Index: gcc/cp/parser.c
  			      tf_warning_or_error);
        else
  	decl = NULL_TREE;
-@@ -24790,7 +24805,7 @@
+@@ -24790,7 +24826,7 @@
        if (!decl)
  	{
  	  /* Look it up in the enclosing context.  */
@@ -19298,7 +30584,7 @@ Index: gcc/cp/parser.c
  				   /*nonclass=*/0,
  				   /*block_p=*/true, is_namespace, 0);
  	  /* DR 141 says when looking for a template-name after -> or ., only
-@@ -24815,7 +24830,7 @@
+@@ -24815,7 +24851,7 @@
      }
    else
      {
@@ -19307,7 +30593,90 @@ Index: gcc/cp/parser.c
  			       /*nonclass=*/0,
  			       /*block_p=*/true, is_namespace, 0);
        parser->qualifying_scope = NULL_TREE;
-@@ -29949,6 +29964,8 @@
+@@ -25667,10 +25703,13 @@
+   cp_parser_skip_to_end_of_template_parameter_list (parser);
+ 
+   /* Manage template requirements */
+-  tree reqs = get_shorthand_constraints (current_template_parms);
+-  if (tree r = cp_parser_requires_clause_opt (parser))
+-    reqs = conjoin_constraints (reqs, make_predicate_constraint (r));
+-  TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
++  if (flag_concepts)
++  {
++    tree reqs = get_shorthand_constraints (current_template_parms);
++    if (tree r = cp_parser_requires_clause_opt (parser))
++      reqs = conjoin_constraints (reqs, normalize_expression (r));
++    TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
++  }
+ 
+   cp_parser_template_declaration_after_parameters (parser, parameter_list,
+ 						   member_p);
+@@ -25978,6 +26017,7 @@
+   cp_token *first;
+   cp_token *last;
+   tree fn;
++  bool function_try_block = false;
+ 
+   /* Create the FUNCTION_DECL.  */
+   fn = grokmethod (decl_specifiers, declarator, attributes);
+@@ -25999,9 +26039,43 @@
+   /* Save away the tokens that make up the body of the
+      function.  */
+   first = parser->lexer->next_token;
++
++  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRANSACTION_RELAXED))
++    cp_lexer_consume_token (parser->lexer);
++  else if (cp_lexer_next_token_is_keyword (parser->lexer,
++					   RID_TRANSACTION_ATOMIC))
++    {
++      cp_lexer_consume_token (parser->lexer);
++      /* Match cp_parser_txn_attribute_opt [[ identifier ]].  */
++      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)
++	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_SQUARE)
++	  && (cp_lexer_nth_token_is (parser->lexer, 3, CPP_NAME)
++	      || cp_lexer_nth_token_is (parser->lexer, 3, CPP_KEYWORD))
++	  && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_SQUARE)
++	  && cp_lexer_nth_token_is (parser->lexer, 5, CPP_CLOSE_SQUARE))
++	{
++	  cp_lexer_consume_token (parser->lexer);
++	  cp_lexer_consume_token (parser->lexer);
++	  cp_lexer_consume_token (parser->lexer);
++	  cp_lexer_consume_token (parser->lexer);
++	  cp_lexer_consume_token (parser->lexer);
++	}
++      else
++	while (cp_next_tokens_can_be_gnu_attribute_p (parser)
++	       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
++	  {
++	    cp_lexer_consume_token (parser->lexer);
++	    if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0))
++	      break;
++	  }
++    }
++
+   /* Handle function try blocks.  */
+   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
+-    cp_lexer_consume_token (parser->lexer);
++    {
++      cp_lexer_consume_token (parser->lexer);
++      function_try_block = true;
++    }
+   /* We can have braced-init-list mem-initializers before the fn body.  */
+   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+     {
+@@ -26019,8 +26093,9 @@
+     }
+   cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
+   /* Handle function try blocks.  */
+-  while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH))
+-    cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
++  if (function_try_block)
++    while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH))
++      cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
+   last = parser->lexer->next_token;
+ 
+   /* Save away the inline definition; we will process it when the
+@@ -29949,6 +30024,8 @@
  	  switch (kind)
  	    {
  	    case OMP_CLAUSE__CACHE_:
@@ -19316,7 +30685,7 @@ Index: gcc/cp/parser.c
  	      if (cp_lexer_peek_token (parser->lexer)->type != CPP_OPEN_SQUARE)
  		{
  		  error_at (token->location, "expected %<[%>");
-@@ -29965,6 +29982,7 @@
+@@ -29965,6 +30042,7 @@
  		    = cp_lexer_peek_token (parser->lexer)->location;
  		  cp_id_kind idk = CP_ID_KIND_NONE;
  		  cp_lexer_consume_token (parser->lexer);
@@ -19324,7 +30693,7 @@ Index: gcc/cp/parser.c
  		  decl
  		    = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT,
  							      decl, false,
-@@ -30000,25 +30018,6 @@
+@@ -30000,25 +30078,6 @@
  					  RT_CLOSE_SQUARE))
  		    goto skip_comma;
  
@@ -19350,7 +30719,7 @@ Index: gcc/cp/parser.c
  		  decl = tree_cons (low_bound, length, decl);
  		}
  	      break;
-@@ -33884,7 +33883,9 @@
+@@ -33884,7 +33943,9 @@
  
    strcat (p_name, " for");
    mask |= OMP_FOR_CLAUSE_MASK;
@@ -19361,7 +30730,7 @@ Index: gcc/cp/parser.c
      mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
    /* Composite distribute parallel for{, simd} disallows ordered clause.  */
    if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
-@@ -34223,7 +34224,8 @@
+@@ -34223,7 +34284,8 @@
  	}
      }
  
@@ -19371,7 +30740,7 @@ Index: gcc/cp/parser.c
    if (cclauses)
      {
        cp_omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
-@@ -35396,6 +35398,8 @@
+@@ -35396,6 +35458,8 @@
  cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
  		     omp_clause_mask mask, tree *cclauses, bool *if_p)
  {
@@ -19380,7 +30749,7 @@ Index: gcc/cp/parser.c
    strcat (p_name, " loop");
    mask |= OACC_LOOP_CLAUSE_MASK;
  
-@@ -35403,7 +35407,7 @@
+@@ -35403,7 +35467,7 @@
  					     cclauses == NULL);
    if (cclauses)
      {
@@ -19389,7 +30758,7 @@ Index: gcc/cp/parser.c
        if (*cclauses)
  	*cclauses = finish_omp_clauses (*cclauses, false);
        if (clauses)
-@@ -35496,8 +35500,6 @@
+@@ -35496,8 +35560,6 @@
        if (strcmp (p, "loop") == 0)
  	{
  	  cp_lexer_consume_token (parser->lexer);
@@ -19398,11 +30767,53 @@ Index: gcc/cp/parser.c
  	  tree block = begin_omp_parallel ();
  	  tree clauses;
  	  cp_parser_oacc_loop (parser, pragma_tok, p_name, mask, &clauses,
+@@ -37807,7 +37869,13 @@
+       implicit template scope, and we're trying to synthesize a
+       constrained parameter, try to find a previous parameter with
+       the same name.  This is the same-type rule for abbreviated
+-      function templates.  */
++      function templates.
++
++      NOTE: We can generate implicit parameters when tentatively
++      parsing a nested name specifier, only to reject that parse
++      later. However, matching the same template-id as part of a
++      direct-declarator should generate an identical template
++      parameter, so this rule will merge them. */
+   if (parser->implicit_template_scope && constr)
+     {
+       tree t = parser->implicit_template_parms;
 Index: gcc/cp/call.c
 ===================================================================
 --- a/src/gcc/cp/call.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/cp/call.c	(.../branches/gcc-6-branch)
-@@ -6360,8 +6360,9 @@
+@@ -3184,6 +3184,12 @@
+ 			     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
++     operators.  */
++  if (any_strictly_viable (*candidates))
++    return NULL;
++
+   return
+     add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
+ 				 NULL_TREE, arglist, return_type, access_path,
+@@ -4386,8 +4392,11 @@
+ 	result = build_over_call (cand, LOOKUP_NORMAL, complain);
+       else
+ 	{
+-	  obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1,
+-					   complain);
++	  if (DECL_P (cand->fn))
++	    obj = convert_like_with_context (cand->convs[0], obj, cand->fn,
++					     -1, complain);
++	  else
++	    obj = convert_like (cand->convs[0], obj, complain);
+ 	  obj = convert_from_reference (obj);
+ 	  result = cp_build_function_call_vec (obj, args, complain);
+ 	}
+@@ -6360,8 +6369,9 @@
  	/* When converting from an init list we consider explicit
  	   constructors, but actually trying to call one is an error.  */
  	if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
@@ -19413,6 +30824,58 @@ Index: gcc/cp/call.c
  	    /* And in C++98 a default constructor can't be explicit.  */
  	    && cxx_dialect >= cxx11)
  	  {
+@@ -6546,7 +6556,7 @@
+       expr = decay_conversion (expr, complain);
+       if (expr == error_mark_node)
+ 	{
+-	  if (complain)
++	  if (complain & tf_error)
+ 	    {
+ 	      maybe_print_user_conv_context (convs);
+ 	      if (fn)
+@@ -7169,10 +7179,11 @@
+ unsafe_copy_elision_p (tree target, tree exp)
+ {
+   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
+-  if (type == CLASSTYPE_AS_BASE (type))
++  /* It's safe to elide the copy for a class with no tail padding.  */
++  if (tree_int_cst_equal (TYPE_SIZE (type), CLASSTYPE_SIZE (type)))
+     return false;
+-  if (!is_base_field_ref (target)
+-      && resolves_to_fixed_type_p (target, NULL))
++  /* It's safe to elide the copy if we aren't initializing a base object.  */
++  if (!is_base_field_ref (target))
+     return false;
+   tree init = TARGET_EXPR_INITIAL (exp);
+   /* build_compound_expr pushes COMPOUND_EXPR inside TARGET_EXPR.  */
+Index: gcc/cp/cp-tree.def
+===================================================================
+--- a/src/gcc/cp/cp-tree.def	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/cp-tree.def	(.../branches/gcc-6-branch)
+@@ -536,6 +536,14 @@
+    PRED_CONSTR_EXPR has the expression to be evaluated. */
+ DEFTREECODE (PRED_CONSTR, "pred_constr", tcc_expression, 1)
+ 
++/* A check constraint represents the checking of a concept
++   C. It has two operands: the template defining the concept
++   and a sequence of template arguments.
++
++   CHECK_CONSTR_CONCEPT has the concept definition
++   CHECK_CONSTR_ARGUMENTS are the template arguments */
++DEFTREECODE (CHECK_CONSTR, "check_constr", tcc_expression, 2)
++
+ /* An expression constraint determines the validity of a expression E.
+ 
+    EXPR_CONST_EXPR has the expression being validated. */
+@@ -560,7 +568,7 @@
+    T must contain at least one place holder.
+ 
+    DEDUCT_CONSTR_EXPR has the expression E
+-   DEDUCT_CONSTR_PATTERN has the type patter T.
++   DEDUCT_CONSTR_PATTERN has the type pattern T.
+    DEDUCT_CONSTR_PLACEHOLDERS has the list of placeholder nodes in T. */
+ DEFTREECODE (DEDUCT_CONSTR, "deduct_constr", tcc_expression, 3)
+ 
 Index: gcc/cp/lambda.c
 ===================================================================
 --- a/src/gcc/cp/lambda.c	(.../tags/gcc_6_1_0_release)
@@ -19429,11 +30892,208 @@ Index: gcc/cp/lambda.c
      return;
  
    if (processing_template_decl)
+@@ -901,6 +903,8 @@
+   tree optype = TREE_TYPE (callop);
+   tree fn_result = TREE_TYPE (optype);
+ 
++  tree thisarg = build_nop (TREE_TYPE (DECL_ARGUMENTS (callop)),
++			    null_pointer_node);
+   if (generic_lambda_p)
+     {
+       /* Prepare the dependent member call for the static member function
+@@ -908,7 +912,8 @@
+ 	 return expression for a deduced return call op to allow for simple
+ 	 implementation of the conversion operator.  */
+ 
+-      tree instance = build_nop (type, null_pointer_node);
++      tree instance = cp_build_indirect_ref (thisarg, RO_NULL,
++					     tf_warning_or_error);
+       tree objfn = build_min (COMPONENT_REF, NULL_TREE,
+ 			      instance, DECL_NAME (callop), NULL_TREE);
+       int nargs = list_length (DECL_ARGUMENTS (callop)) - 1;
+@@ -920,9 +925,7 @@
+   else
+     {
+       direct_argvec = make_tree_vector ();
+-      direct_argvec->quick_push (build1 (NOP_EXPR,
+-					 TREE_TYPE (DECL_ARGUMENTS (callop)),
+-					 null_pointer_node));
++      direct_argvec->quick_push (thisarg);
+     }
+ 
+   /* Copy CALLOP's argument list (as per 'copy_list') as FN_ARGS in order to
+Index: gcc/cp/mangle.c
+===================================================================
+--- a/src/gcc/cp/mangle.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/mangle.c	(.../branches/gcc-6-branch)
+@@ -2774,6 +2774,39 @@
+       write_type (TREE_TYPE (TREE_OPERAND (expr, 0)));
+     }
+   else if (TREE_CODE (expr) == SIZEOF_EXPR
++	   && ARGUMENT_PACK_P (TREE_OPERAND (expr, 0)))
++    {
++      tree args = ARGUMENT_PACK_ARGS (TREE_OPERAND (expr, 0));
++      int length = TREE_VEC_LENGTH (args);
++      if (abi_warn_or_compat_version_crosses (10))
++	G.need_abi_warning = true;
++      if (abi_version_at_least (10))
++	{
++	  /* sP <template-arg>* E # sizeof...(T), size of a captured
++	     template parameter pack from an alias template */
++	  write_string ("sP");
++	  for (int i = 0; i < length; ++i)
++	    write_template_arg (TREE_VEC_ELT (args, i));
++	  write_char ('E');
++	}
++      else
++	{
++	  /* In GCC 5 we represented this sizeof wrong, with the effect
++	     that we mangled it as the last element of the pack.  */
++	  tree arg = TREE_VEC_ELT (args, length-1);
++	  if (TYPE_P (arg))
++	    {
++	      write_string ("st");
++	      write_type (arg);
++	    }
++	  else
++	    {
++	      write_string ("sz");
++	      write_expression (arg);
++	    }
++	}
++    }
++  else if (TREE_CODE (expr) == SIZEOF_EXPR
+ 	   && TYPE_P (TREE_OPERAND (expr, 0)))
+     {
+       write_string ("st");
+@@ -3094,6 +3127,29 @@
+ 			 "cannot be mangled");
+ 		  continue;
+ 		}
++	      else if (FOLD_EXPR_P (expr))
++		{
++		  /* The first 'operand' of a fold-expression is the operator
++		     that it folds over.  */
++		  if (i == 0)
++		    {
++		      int fcode = TREE_INT_CST_LOW (operand);
++		      write_string (operator_name_info[fcode].mangled_name);
++		      continue;
++		    }
++		  else if (code == BINARY_LEFT_FOLD_EXPR)
++		    {
++		      /* The order of operands of the binary left and right
++			 folds is the same, but we want to mangle them in
++			 lexical order, i.e. non-pack first.  */
++		      if (i == 1)
++			operand = FOLD_EXPR_INIT (expr);
++		      else
++			operand = FOLD_EXPR_PACK (expr);
++		    }
++		  if (PACK_EXPANSION_P (operand))
++		    operand = PACK_EXPANSION_PATTERN (operand);
++		}
+ 	      write_expression (operand);
+ 	    }
+ 	}
 Index: gcc/cp/cp-tree.h
 ===================================================================
 --- a/src/gcc/cp/cp-tree.h	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/cp/cp-tree.h	(.../branches/gcc-6-branch)
-@@ -4601,7 +4601,8 @@
+@@ -170,7 +170,7 @@
+       TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR)
+       FNDECL_USED_AUTO (in FUNCTION_DECL)
+       DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE)
+-      REF_PARENTHESIZED_P (in COMPONENT_REF, INDIRECT_REF)
++      REF_PARENTHESIZED_P (in COMPONENT_REF, INDIRECT_REF, SCOPE_REF)
+       AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR)
+       CONSTRUCTOR_MUTABLE_POISON (in CONSTRUCTOR)
+    3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
+@@ -891,10 +891,6 @@
+ // - a constraint expression introduced by a function declarator
+ // - the associated constraints, which are the conjunction of those,
+ //   and used for declaration matching
+-// - the cached normalized associated constraints which are used
+-//   to support satisfaction and subsumption.
+-// - assumptions which is the result of decomposing the normalized
+-//   constraints.
+ //
+ // The template and declarator requirements are kept to support pretty
+ // printing constrained declarations.
+@@ -903,8 +899,6 @@
+   tree template_reqs;
+   tree declarator_reqs;
+   tree associated_constr;
+-  tree normalized_constr;
+-  tree assumptions;
+ };
+ 
+ // Require that pointer P is non-null before returning.
+@@ -943,14 +937,6 @@
+ #define CI_ASSOCIATED_CONSTRAINTS(NODE) \
+   check_constraint_info (check_nonnull(NODE))->associated_constr
+ 
+-// The normalized associated constraints.
+-#define CI_NORMALIZED_CONSTRAINTS(NODE) \
+-  check_constraint_info (check_nonnull(NODE))->normalized_constr
+-
+-// Get the set of assumptions associated with the constraint info node.
+-#define CI_ASSUMPTIONS(NODE) \
+-  check_constraint_info (check_nonnull(NODE))->assumptions
+-
+ // Access the logical constraints on the template parameters introduced
+ // at a given template parameter list level indicated by NODE.
+ #define TEMPLATE_PARMS_CONSTRAINTS(NODE) \
+@@ -974,6 +960,14 @@
+ #define PRED_CONSTR_EXPR(NODE) \
+   TREE_OPERAND (TREE_CHECK (NODE, PRED_CONSTR), 0)
+ 
++/* The concept of a concept check. */
++#define CHECK_CONSTR_CONCEPT(NODE) \
++  TREE_OPERAND (TREE_CHECK (NODE, CHECK_CONSTR), 0)
++
++/* The template arguments of a concept check. */
++#define CHECK_CONSTR_ARGS(NODE) \
++  TREE_OPERAND (TREE_CHECK (NODE, CHECK_CONSTR), 1)
++
+ /* The expression validated by the predicate constraint. */
+ #define EXPR_CONSTR_EXPR(NODE) \
+   TREE_OPERAND (TREE_CHECK (NODE, EXPR_CONSTR), 0)
+@@ -3332,11 +3326,11 @@
+   TREE_CHECK2 (NODE, BINARY_LEFT_FOLD_EXPR, BINARY_RIGHT_FOLD_EXPR)
+ 
+ /* True if NODE is UNARY_FOLD_EXPR or a BINARY_FOLD_EXPR */
+-#define FOLD_EXPR_P(NODE) \
+-  TREE_CODE (NODE) == UNARY_LEFT_FOLD_EXPR \
+-    || TREE_CODE (NODE) == UNARY_RIGHT_FOLD_EXPR \
+-    || TREE_CODE (NODE) == BINARY_LEFT_FOLD_EXPR \
+-    || TREE_CODE (NODE) == BINARY_RIGHT_FOLD_EXPR
++#define FOLD_EXPR_P(NODE)				\
++  (TREE_CODE (NODE) == UNARY_LEFT_FOLD_EXPR		\
++   || TREE_CODE (NODE) == UNARY_RIGHT_FOLD_EXPR		\
++   || TREE_CODE (NODE) == BINARY_LEFT_FOLD_EXPR		\
++   || TREE_CODE (NODE) == BINARY_RIGHT_FOLD_EXPR)
+ 
+ /* True when NODE is a fold over a compound assignment operator. */
+ #define FOLD_EXPR_MODIFY_P(NODE) \
+@@ -3398,12 +3392,12 @@
+ #define PAREN_STRING_LITERAL_P(NODE) \
+   TREE_LANG_FLAG_0 (STRING_CST_CHECK (NODE))
+ 
+-/* Indicates whether a COMPONENT_REF has been parenthesized, or an
+-   INDIRECT_REF comes from parenthesizing a _DECL.  Currently only set
+-   some of the time in C++14 mode.  */
++/* Indicates whether a COMPONENT_REF or a SCOPE_REF has been parenthesized, or
++   an INDIRECT_REF comes from parenthesizing a _DECL.  Currently only set some
++   of the time in C++14 mode.  */
+ 
+ #define REF_PARENTHESIZED_P(NODE) \
+-  TREE_LANG_FLAG_2 (TREE_CHECK2 ((NODE), COMPONENT_REF, INDIRECT_REF))
++  TREE_LANG_FLAG_2 (TREE_CHECK3 ((NODE), COMPONENT_REF, INDIRECT_REF, SCOPE_REF))
+ 
+ /* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
+    constructor call, rather than an ordinary function call.  */
+@@ -4601,7 +4595,8 @@
    class_type,    /* "class" types.  */
    union_type,    /* "union" types.  */
    enum_type,     /* "enum" types.  */
@@ -19443,6 +31103,71 @@ Index: gcc/cp/cp-tree.h
  };
  
  /* The various kinds of lvalues we distinguish.  */
+@@ -6096,6 +6091,7 @@
+ extern tree get_pattern_parm			(tree, tree);
+ extern int comp_template_args			(tree, tree, tree * = NULL,
+ 						 tree * = NULL);
++extern int template_args_equal                  (tree, tree);
+ extern tree maybe_process_partial_specialization (tree);
+ extern tree most_specialized_instantiation	(tree);
+ extern void print_candidates			(tree);
+@@ -6809,10 +6805,8 @@
+ /* in constraint.cc */
+ extern void init_constraint_processing          ();
+ extern bool constraint_p                        (tree);
+-extern tree make_predicate_constraint           (tree);
+ extern tree conjoin_constraints                 (tree, tree);
+ extern tree conjoin_constraints                 (tree);
+-extern bool valid_constraints_p                 (tree);
+ extern tree get_constraints                     (tree);
+ extern void set_constraints                     (tree, tree);
+ extern void remove_constraints                  (tree);
+@@ -6843,7 +6837,9 @@
+ extern tree tsubst_constraint                   (tree, tree, tsubst_flags_t, tree);
+ extern tree tsubst_constraint_info              (tree, tree, tsubst_flags_t, tree);
+ extern bool function_concept_check_p            (tree);
+-
++extern tree normalize_expression                (tree);
++extern tree expand_concept                      (tree, tree);
++extern bool expanding_concept                   ();
+ extern tree evaluate_constraints                (tree, tree);
+ extern tree evaluate_function_concept           (tree, tree);
+ extern tree evaluate_variable_concept           (tree, tree);
+@@ -6850,6 +6846,14 @@
+ extern tree evaluate_constraint_expression      (tree, tree);
+ extern bool constraints_satisfied_p             (tree);
+ extern bool constraints_satisfied_p             (tree, tree);
++extern tree lookup_constraint_satisfaction      (tree, tree);
++extern tree memoize_constraint_satisfaction     (tree, tree, tree);
++extern tree lookup_concept_satisfaction         (tree, tree);
++extern tree memoize_concept_satisfaction        (tree, tree, tree);
++extern tree get_concept_expansion               (tree, tree);
++extern tree save_concept_expansion              (tree, tree, tree);
++extern bool* lookup_subsumption_result          (tree, tree);
++extern bool save_subsumption_result             (tree, tree, bool);
+ 
+ extern bool equivalent_constraints              (tree, tree);
+ extern bool equivalently_constrained            (tree, tree);
+@@ -6860,7 +6864,6 @@
+ extern void diagnose_constraints                (location_t, tree, tree);
+ 
+ /* in logic.cc */
+-extern tree decompose_assumptions               (tree);
+ extern tree decompose_conclusions               (tree);
+ extern bool subsumes                            (tree, tree);
+ 
+Index: gcc/cp/search.c
+===================================================================
+--- a/src/gcc/cp/search.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cp/search.c	(.../branches/gcc-6-branch)
+@@ -947,6 +947,7 @@
+      in default arguments for template parameters), and access
+      checking should be performed in the outermost parameter list.  */
+   if (processing_template_decl
++      && !expanding_concept ()
+       && (!processing_template_parmlist || processing_template_decl > 1))
+     return 1;
+ 
 Index: gcc/cp/name-lookup.c
 ===================================================================
 --- a/src/gcc/cp/name-lookup.c	(.../tags/gcc_6_1_0_release)
@@ -19575,7 +31300,30 @@ Index: gcc/dwarf2out.c
  }
  
  /* Determine what tag to use for a record type.  */
-@@ -27382,10 +27384,6 @@
+@@ -20724,14 +20726,17 @@
+ 	 void_type_node 2) an unprototyped function declaration (not a
+ 	 definition).  This just means that we have no info about the
+ 	 parameters at all.  */
+-      if (prototype_p (TREE_TYPE (decl)))
++      if (early_dwarf)
+ 	{
+-	  /* This is the prototyped case, check for....  */
+-	  if (stdarg_p (TREE_TYPE (decl)))
++	  if (prototype_p (TREE_TYPE (decl)))
++	    {
++	      /* This is the prototyped case, check for....  */
++	      if (stdarg_p (TREE_TYPE (decl)))
++		gen_unspecified_parameters_die (decl, subr_die);
++	    }
++	  else if (DECL_INITIAL (decl) == NULL_TREE)
+ 	    gen_unspecified_parameters_die (decl, subr_die);
+ 	}
+-      else if (DECL_INITIAL (decl) == NULL_TREE)
+-	gen_unspecified_parameters_die (decl, subr_die);
+     }
+ 
+   if (subr_die != old_die)
+@@ -27382,10 +27387,6 @@
    resolve_addr (comp_unit_die ());
    move_marked_base_types ();
  
@@ -19586,7 +31334,7 @@ Index: gcc/dwarf2out.c
    if (flag_eliminate_unused_debug_types)
      prune_unused_types ();
  
-@@ -27686,6 +27684,10 @@
+@@ -27686,6 +27687,10 @@
  static void
  dwarf2out_early_finish (void)
  {
@@ -19597,6 +31345,29 @@ Index: gcc/dwarf2out.c
    /* The point here is to flush out the limbo list so that it is empty
       and we don't need to stream it for LTO.  */
    flush_limbo_die_list ();
+Index: gcc/match.pd
+===================================================================
+--- a/src/gcc/match.pd	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/match.pd	(.../branches/gcc-6-branch)
+@@ -844,12 +844,16 @@
+   (ne (bit_and:c (bit_not @0) @1) integer_zerop)
+   (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
+        && TYPE_PRECISION (TREE_TYPE (@1)) == 1)
+-   (lt @0 @1)))
++   (if (TYPE_UNSIGNED (TREE_TYPE (@1)))
++    (lt @0 @1)
++    (gt @0 @1))))
+ (simplify
+   (ne (bit_ior:c (bit_not @0) @1) integer_zerop)
+   (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
+        && TYPE_PRECISION (TREE_TYPE (@1)) == 1)
+-   (le @0 @1)))
++   (if (TYPE_UNSIGNED (TREE_TYPE (@1)))
++    (le @0 @1)
++    (ge @0 @1))))
+ 
+ /* ~~x -> x */
+ (simplify
 Index: gcc/opts.h
 ===================================================================
 --- a/src/gcc/opts.h	(.../tags/gcc_6_1_0_release)
@@ -19609,6 +31380,19 @@ Index: gcc/opts.h
  					const char *base_option);
  
  #endif
+Index: gcc/timevar.def
+===================================================================
+--- a/src/gcc/timevar.def	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/timevar.def	(.../branches/gcc-6-branch)
+@@ -137,6 +137,8 @@
+ DEFTIMEVAR (TV_PARSE_INLINE          , "parser inl. func. body")
+ DEFTIMEVAR (TV_PARSE_INMETH          , "parser inl. meth. body")
+ DEFTIMEVAR (TV_TEMPLATE_INST         , "template instantiation")
++DEFTIMEVAR (TV_CONSTRAINT_SAT        , "constraint satisfaction")
++DEFTIMEVAR (TV_CONSTRAINT_SUB        , "constraint subsumption")
+ DEFTIMEVAR (TV_FLATTEN_INLINING      , "flatten inlining")
+ DEFTIMEVAR (TV_EARLY_INLINING        , "early inlining heuristics")
+ DEFTIMEVAR (TV_INLINE_PARAMETERS     , "inline parameters")
 Index: gcc/ada/s-osinte-gnu.ads
 ===================================================================
 --- a/src/gcc/ada/s-osinte-gnu.ads	(.../tags/gcc_6_1_0_release)
@@ -20388,6 +32172,48 @@ Index: gcc/ada/system-linux-ppc64.ads
     type Name is (SYSTEM_NAME_GNAT);
     System_Name : constant Name := SYSTEM_NAME_GNAT;
  
+Index: gcc/timevar.h
+===================================================================
+--- a/src/gcc/timevar.h	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/timevar.h	(.../branches/gcc-6-branch)
+@@ -229,6 +229,14 @@
+       m_timer->push (m_tv);
+   }
+ 
++  explicit auto_timevar (timevar_id_t tv)
++    : m_timer (g_timer)
++    , m_tv (tv)
++  {
++    if (m_timer)
++      m_timer->push (m_tv);
++  }
++
+   ~auto_timevar ()
+   {
+     if (m_timer)
+Index: gcc/asan.c
+===================================================================
+--- a/src/gcc/asan.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/asan.c	(.../branches/gcc-6-branch)
+@@ -2159,6 +2159,9 @@
+ tree
+ asan_dynamic_init_call (bool after_p)
+ {
++  if (shadow_ptr_types[0] == NULL_TREE)
++    asan_init_shadow_ptr_types ();
++
+   tree fn = builtin_decl_implicit (after_p
+ 				   ? BUILT_IN_ASAN_AFTER_DYNAMIC_INIT
+ 				   : BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT);
+@@ -2168,8 +2171,6 @@
+       pretty_printer module_name_pp;
+       pp_string (&module_name_pp, main_input_filename);
+ 
+-      if (shadow_ptr_types[0] == NULL_TREE)
+-	asan_init_shadow_ptr_types ();
+       module_name_cst = asan_pp_string (&module_name_pp);
+       module_name_cst = fold_convert (const_ptr_type_node,
+ 				      module_name_cst);
 Index: gcc/fortran/openmp.c
 ===================================================================
 --- a/src/gcc/fortran/openmp.c	(.../tags/gcc_6_1_0_release)
@@ -21007,7 +32833,20 @@ Index: gcc/fortran/trans-expr.c
        lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
  				     gfc_charlen_type_node,
  				     TREE_OPERAND (comp, 0),
-@@ -7245,7 +7251,7 @@
+@@ -7194,6 +7200,12 @@
+       tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
+       gfc_add_expr_to_block (&block, tmp);
+     }
++  else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
++    {
++      /* NULL initialization for allocatable components.  */
++      gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
++						  null_pointer_node));
++    }
+   else if (init && (cm->attr.allocatable
+ 	   || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
+ 	       && expr->ts.type != BT_CLASS)))
+@@ -7245,7 +7257,7 @@
  			fold_convert (TREE_TYPE (tmp), se.expr));
        gfc_add_block_to_block (&block, &se.post);
      }
@@ -21016,7 +32855,15 @@ Index: gcc/fortran/trans-expr.c
      {
        if (expr->expr_type != EXPR_STRUCTURE)
  	{
-@@ -7416,6 +7422,24 @@
+@@ -7352,7 +7364,6 @@
+     {
+       gfc_se se, lse;
+ 
+-      gcc_assert (cm->backend_decl == NULL);
+       gfc_init_se (&se, NULL);
+       gfc_init_se (&lse, NULL);
+       gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
+@@ -7416,6 +7427,24 @@
        return;
      }
  
@@ -21041,7 +32888,7 @@ Index: gcc/fortran/trans-expr.c
    cm = expr->ts.u.derived->components;
  
    for (c = gfc_constructor_first (expr->value.constructor);
-@@ -7462,6 +7486,7 @@
+@@ -7462,6 +7491,7 @@
  	  CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
  	}
      }
@@ -21049,7 +32896,7 @@ Index: gcc/fortran/trans-expr.c
    se->expr = build_constructor (type, v);
    if (init)
      TREE_CONSTANT (se->expr) = 1;
-@@ -8246,7 +8271,7 @@
+@@ -8246,7 +8276,7 @@
        gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
  			     rse->expr, ts.kind);
      }
@@ -21058,7 +32905,7 @@ Index: gcc/fortran/trans-expr.c
      {
        tree tmp_var = NULL_TREE;
        cond = NULL_TREE;
-@@ -8299,7 +8324,7 @@
+@@ -8299,7 +8329,7 @@
  	  gfc_add_expr_to_block (&block, tmp);
  	}
      }
@@ -21067,7 +32914,7 @@ Index: gcc/fortran/trans-expr.c
      {
        gfc_add_block_to_block (&block, &lse->pre);
        gfc_add_block_to_block (&block, &rse->pre);
-@@ -9503,7 +9528,7 @@
+@@ -9503,7 +9533,7 @@
      case BT_CHARACTER:
        return false;
  
@@ -22469,7 +34316,52 @@ Index: gcc/fortran/ChangeLog
 ===================================================================
 --- a/src/gcc/fortran/ChangeLog	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/fortran/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,218 @@
+@@ -1,3 +1,263 @@
++2016-07-22  Andre Vehreschild  <vehre at gcc.gnu.org>
++
++	Backported from trunk:
++	PR fortran/71807
++	* trans-expr.c (gfc_trans_subcomponent_assign): Special casing
++	when allocatable component is set to null() in initializer.
++
++2016-07-22  Andre Vehreschild  <vehre at gcc.gnu.org>
++
++	Backport from trunk:
++	PR fortran/70842
++	* simplify.c (gfc_simplify_len): Only for unlimited polymorphic
++	types replace the expression's _data ref with a _len ref.
++
++2016-07-15  Jerry DeLisle  <jvdelisle at gcc.gnu.org>
++
++	Backport from trunk:
++	PR fortran/71764
++	* trans-expr.c (gfc_trans_structure_assign): Remove assert.
++
++2016-07-13  Andre Vehreschild  <vehre at gcc.gnu.org>
++
++	Backport from trunk:
++	PR fortran/71623
++	* trans-stmt.c (gfc_trans_allocate): Add code of pre block of typespec
++	in allocate to parent block.
++
++2016-07-09  Thomas Koenig  <tkoenig at gcc.gnu.org>
++
++	Backport from trunk:
++	PR fortran/71783
++	* frontend-passes.c (create_var):  Always allocate a charlen
++	for character variables.
++
++2016-07-08  Cesar Philippidis  <cesar at codesourcery.com>
++
++	Backport from trunk:
++	2016-07-08  Cesar Philippidis  <cesar at codesourcery.com>
++
++	* parse.c (matcha): Define.
++	(decode_oacc_directive): Add spec_only local var and set it.  Use
++	matcha to parse acc directives except for routine and declare.  Return
++	ST_GET_FCN_CHARACTERISTICS if a non-declarative directive could be
++	matched.
++
 +2016-07-02  Jakub Jelinek  <jakub at redhat.com>
 +
 +	Backported from mainline
@@ -22692,7 +34584,52 @@ Index: gcc/fortran/trans-stmt.c
 ===================================================================
 --- a/src/gcc/fortran/trans-stmt.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/fortran/trans-stmt.c	(.../branches/gcc-6-branch)
-@@ -6275,7 +6275,7 @@
+@@ -5694,9 +5694,11 @@
+ 	  tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
+ 	  tmp = TYPE_SIZE_UNIT (tmp);
+ 	  tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
++	  gfc_add_block_to_block (&block, &se_sz.pre);
+ 	  expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
+ 					 TREE_TYPE (se_sz.expr),
+ 					 tmp, se_sz.expr);
++	  expr3_esize = gfc_evaluate_now (expr3_esize, &block);
+ 	}
+     }
+ 
+@@ -5895,6 +5897,7 @@
+ 		 source= or mold= expression.  */
+ 	      gfc_init_se (&se_sz, NULL);
+ 	      gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
++	      gfc_add_block_to_block (&block, &se_sz.pre);
+ 	      gfc_add_modify (&block, al_len,
+ 			      fold_convert (TREE_TYPE (al_len),
+ 					    se_sz.expr));
+@@ -5979,11 +5982,19 @@
+ 		 specified by a type spec for deferred length character
+ 		 arrays or unlimited polymorphic objects without a
+ 		 source= or mold= expression.  */
+-	      gfc_init_se (&se_sz, NULL);
+-	      gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
+-	      gfc_add_modify (&block, al_len,
+-			      fold_convert (TREE_TYPE (al_len),
+-					    se_sz.expr));
++	      if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
++		{
++		  gfc_init_se (&se_sz, NULL);
++		  gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
++		  gfc_add_block_to_block (&block, &se_sz.pre);
++		  gfc_add_modify (&block, al_len,
++				  fold_convert (TREE_TYPE (al_len),
++						se_sz.expr));
++		}
++	      else
++		gfc_add_modify (&block, al_len,
++				fold_convert (TREE_TYPE (al_len),
++					      expr3_esize));
+ 	    }
+ 	  else
+ 	    /* No length information needed, because type to allocate
+@@ -6275,7 +6286,7 @@
  	{
  	  gfc_ref *ref;
  
@@ -23100,7 +35037,22 @@ Index: gcc/fortran/frontend-passes.c
    n = create_var (expr2, "trim");
    co->expr2 = n;
    return 0;
-@@ -2812,6 +2821,12 @@
+@@ -656,12 +665,10 @@
+     {
+       gfc_expr *length;
+ 
++      symbol->ts.u.cl = gfc_new_charlen (ns, NULL);
+       length = constant_string_length (e);
+       if (length)
+-	{
+-	  symbol->ts.u.cl = gfc_new_charlen (ns, NULL);
+-	  symbol->ts.u.cl->length = length;
+-	}
++	symbol->ts.u.cl->length = length;
+       else
+ 	symbol->attr.allocatable = 1;
+     }
+@@ -2812,6 +2819,12 @@
    if (in_where)
      return 0;
  
@@ -24379,6 +36331,15 @@ Index: gcc/fortran/trans-decl.c
    while (decl)
      {
        tree next;
+@@ -6319,7 +6335,7 @@
+ 	 function has already called cgraph_create_node, which also created
+ 	 the cgraph node for this function.  */
+       if (!has_coarray_vars || flag_coarray != GFC_FCOARRAY_LIB)
+-	(void) cgraph_node::create (fndecl);
++	(void) cgraph_node::get_create (fndecl);
+     }
+   else
+     cgraph_node::finalize_function (fndecl, true);
 @@ -6452,7 +6468,7 @@
    if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
      generate_coarray_init (ns);
@@ -24610,13 +36571,16 @@ Index: gcc/fortran/parse.c
        match ("unlock", gfc_match_unlock, ST_UNLOCK);
        break;
  
-@@ -585,28 +589,6 @@
+@@ -585,21 +589,12 @@
    return ST_NONE;
  }
  
 -/* Like match, but set a flag simd_matched if keyword matched.  */
 -#define matchs(keyword, subr, st)				\
--    do {							\
++/* Like match and if spec_only, goto do_spec_only without actually
++   matching.  */
++#define matcha(keyword, subr, st)				\
+     do {							\
 -      if (match_word_omp_simd (keyword, subr, &old_locus,	\
 -			       &simd_matched) == MATCH_YES)	\
 -	return st;						\
@@ -24629,18 +36593,115 @@ Index: gcc/fortran/parse.c
 -    do {							\
 -      if (!flag_openmp)						\
 -	;							\
--      else if (match_word (keyword, subr, &old_locus)		\
--	       == MATCH_YES)					\
--	return st;						\
--      else							\
--	undo_new_statement ();				  	\
--    } while (0);
--
- static gfc_statement
- decode_oacc_directive (void)
++      if (spec_only && gfc_match (keyword) == MATCH_YES)	\
++	goto do_spec_only;					\
+       else if (match_word (keyword, subr, &old_locus)		\
+ 	       == MATCH_YES)					\
+ 	return st;						\
+@@ -612,6 +607,7 @@
  {
-@@ -698,6 +680,56 @@
+   locus old_locus;
+   char c;
++  bool spec_only = false;
+ 
+   gfc_enforce_clean_symbol_state ();
+ 
+@@ -626,6 +622,10 @@
+       return ST_NONE;
+     }
+ 
++  if (gfc_current_state () == COMP_FUNCTION
++      && gfc_current_block ()->result->ts.kind == -1)
++    spec_only = true;
++
+   gfc_unset_implicit_pure (NULL);
+ 
+   old_locus = gfc_current_locus;
+@@ -639,49 +639,52 @@
+   switch (c)
+     {
+     case 'a':
+-      match ("atomic", gfc_match_oacc_atomic, ST_OACC_ATOMIC);
++      matcha ("atomic", gfc_match_oacc_atomic, ST_OACC_ATOMIC);
+       break;
+     case 'c':
+-      match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
++      matcha ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
+       break;
+     case 'd':
+-      match ("data", gfc_match_oacc_data, ST_OACC_DATA);
++      matcha ("data", gfc_match_oacc_data, ST_OACC_DATA);
+       match ("declare", gfc_match_oacc_declare, ST_OACC_DECLARE);
+       break;
+     case 'e':
+-      match ("end atomic", gfc_match_omp_eos, ST_OACC_END_ATOMIC);
+-      match ("end data", gfc_match_omp_eos, ST_OACC_END_DATA);
+-      match ("end host_data", gfc_match_omp_eos, ST_OACC_END_HOST_DATA);
+-      match ("end kernels loop", gfc_match_omp_eos, ST_OACC_END_KERNELS_LOOP);
+-      match ("end kernels", gfc_match_omp_eos, ST_OACC_END_KERNELS);
+-      match ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
+-      match ("end parallel loop", gfc_match_omp_eos, ST_OACC_END_PARALLEL_LOOP);
+-      match ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
+-      match ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
+-      match ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
++      matcha ("end atomic", gfc_match_omp_eos, ST_OACC_END_ATOMIC);
++      matcha ("end data", gfc_match_omp_eos, ST_OACC_END_DATA);
++      matcha ("end host_data", gfc_match_omp_eos, ST_OACC_END_HOST_DATA);
++      matcha ("end kernels loop", gfc_match_omp_eos, ST_OACC_END_KERNELS_LOOP);
++      matcha ("end kernels", gfc_match_omp_eos, ST_OACC_END_KERNELS);
++      matcha ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
++      matcha ("end parallel loop", gfc_match_omp_eos,
++	      ST_OACC_END_PARALLEL_LOOP);
++      matcha ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
++      matcha ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
++      matcha ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
+       break;
+     case 'h':
+-      match ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
++      matcha ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
+       break;
+     case 'p':
+-      match ("parallel loop", gfc_match_oacc_parallel_loop, ST_OACC_PARALLEL_LOOP);
+-      match ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
++      matcha ("parallel loop", gfc_match_oacc_parallel_loop,
++	      ST_OACC_PARALLEL_LOOP);
++      matcha ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
+       break;
+     case 'k':
+-      match ("kernels loop", gfc_match_oacc_kernels_loop, ST_OACC_KERNELS_LOOP);
+-      match ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
++      matcha ("kernels loop", gfc_match_oacc_kernels_loop,
++	      ST_OACC_KERNELS_LOOP);
++      matcha ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
+       break;
+     case 'l':
+-      match ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
++      matcha ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
+       break;
+     case 'r':
+       match ("routine", gfc_match_oacc_routine, ST_OACC_ROUTINE);
+       break;
+     case 'u':
+-      match ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
++      matcha ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
+       break;
+     case 'w':
+-      match ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
++      matcha ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
+       break;
+     }
+ 
+@@ -696,8 +699,65 @@
+   gfc_error_recovery ();
+ 
    return ST_NONE;
++
++ do_spec_only:
++  reject_statement ();
++  gfc_clear_error ();
++  gfc_buffer_error (false);
++  gfc_current_locus = old_locus;
++  return ST_GET_FCN_CHARACTERISTICS;
  }
  
 +/* Like match, but set a flag simd_matched if keyword matched
@@ -24696,7 +36757,7 @@ Index: gcc/fortran/parse.c
  static gfc_statement
  decode_omp_directive (void)
  {
-@@ -704,6 +736,7 @@
+@@ -704,6 +764,7 @@
    locus old_locus;
    char c;
    bool simd_matched = false;
@@ -24704,7 +36765,7 @@ Index: gcc/fortran/parse.c
  
    gfc_enforce_clean_symbol_state ();
  
-@@ -718,6 +751,10 @@
+@@ -718,6 +779,10 @@
        return ST_NONE;
      }
  
@@ -24715,7 +36776,7 @@ Index: gcc/fortran/parse.c
    gfc_unset_implicit_pure (NULL);
  
    old_locus = gfc_current_locus;
-@@ -746,12 +783,12 @@
+@@ -746,12 +811,12 @@
        matcho ("critical", gfc_match_omp_critical, ST_OMP_CRITICAL);
        break;
      case 'd':
@@ -24734,7 +36795,7 @@ Index: gcc/fortran/parse.c
        matchs ("distribute parallel do simd",
  	      gfc_match_omp_distribute_parallel_do_simd,
  	      ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD);
-@@ -871,8 +908,8 @@
+@@ -871,8 +936,8 @@
        matcho ("teams distribute", gfc_match_omp_teams_distribute,
  	      ST_OMP_TEAMS_DISTRIBUTE);
        matcho ("teams", gfc_match_omp_teams, ST_OMP_TEAMS);
@@ -24745,7 +36806,7 @@ Index: gcc/fortran/parse.c
        break;
      case 'w':
        matcho ("workshare", gfc_match_omp_workshare, ST_OMP_WORKSHARE);
-@@ -895,6 +932,13 @@
+@@ -895,6 +960,13 @@
    gfc_error_recovery ();
  
    return ST_NONE;
@@ -24759,7 +36820,7 @@ Index: gcc/fortran/parse.c
  }
  
  static gfc_statement
-@@ -1315,10 +1359,13 @@
+@@ -1315,10 +1387,13 @@
  
    gfc_buffer_error (false);
  
@@ -24776,7 +36837,7 @@ Index: gcc/fortran/parse.c
        gfc_current_locus = old_locus;
      }
  
-@@ -1386,10 +1433,14 @@
+@@ -1386,10 +1461,14 @@
  
  #define case_decl case ST_ATTR_DECL: case ST_COMMON: case ST_DATA_DECL: \
    case ST_EQUIVALENCE: case ST_NAMELIST: case ST_STATEMENT_FUNCTION: \
@@ -24794,7 +36855,7 @@ Index: gcc/fortran/parse.c
  /* Block end statements.  Errors associated with interchanging these
     are detected in gfc_match_end().  */
  
-@@ -1642,6 +1693,15 @@
+@@ -1642,6 +1721,15 @@
      case ST_DEALLOCATE:
        p = "DEALLOCATE";
        break;
@@ -24810,7 +36871,7 @@ Index: gcc/fortran/parse.c
      case ST_DERIVED_DECL:
        p = _("derived type declaration");
        break;
-@@ -1711,6 +1771,15 @@
+@@ -1711,6 +1799,15 @@
      case ST_END_WHERE:
        p = "END WHERE";
        break;
@@ -24826,7 +36887,7 @@ Index: gcc/fortran/parse.c
      case ST_END_TYPE:
        p = "END TYPE";
        break;
-@@ -2457,6 +2526,7 @@
+@@ -2457,6 +2554,7 @@
  
      case ST_PUBLIC:
      case ST_PRIVATE:
@@ -24834,7 +36895,7 @@ Index: gcc/fortran/parse.c
      case ST_DERIVED_DECL:
      case_decl:
        if (p->state >= ORDER_EXEC)
-@@ -2465,6 +2535,14 @@
+@@ -2465,6 +2563,14 @@
  	p->state = ORDER_SPEC;
        break;
  
@@ -24849,7 +36910,7 @@ Index: gcc/fortran/parse.c
      case_executable:
      case_exec_markers:
        if (p->state < ORDER_EXEC)
-@@ -2646,6 +2724,358 @@
+@@ -2646,6 +2752,358 @@
  }
  
  
@@ -25208,7 +37269,7 @@ Index: gcc/fortran/parse.c
  /* Parse a derived type.  */
  
  static void
-@@ -2762,171 +3192,8 @@
+@@ -2762,171 +3220,8 @@
     */
    sym = gfc_current_block ();
    for (c = sym->components; c; c = c->next)
@@ -25381,7 +37442,7 @@ Index: gcc/fortran/parse.c
    if (!seen_component)
      sym->attr.zero_comp = 1;
  
-@@ -3348,8 +3615,10 @@
+@@ -3348,8 +3643,10 @@
      case ST_PARAMETER:
      case ST_PUBLIC:
      case ST_PRIVATE:
@@ -25392,7 +37453,7 @@ Index: gcc/fortran/parse.c
  declSt:
        if (!verify_st_order (&ss, st, false))
  	{
-@@ -3364,6 +3633,10 @@
+@@ -3364,6 +3661,10 @@
  	  parse_interface ();
  	  break;
  
@@ -25770,6 +37831,24 @@ Index: gcc/fortran/options.c
      }
  
    Fortran_handle_option_auto (&global_options, &global_options_set, 
+Index: gcc/fortran/simplify.c
+===================================================================
+--- a/src/gcc/fortran/simplify.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/fortran/simplify.c	(.../branches/gcc-6-branch)
+@@ -3814,8 +3814,12 @@
+     }
+   else if (e->expr_type == EXPR_VARIABLE && e->ts.type == BT_CHARACTER
+ 	   && e->symtree->n.sym
++	   && e->symtree->n.sym->ts.type != BT_DERIVED
+ 	   && e->symtree->n.sym->assoc && e->symtree->n.sym->assoc->target
+-	   && e->symtree->n.sym->assoc->target->ts.type == BT_DERIVED)
++	   && e->symtree->n.sym->assoc->target->ts.type == BT_DERIVED
++	   && e->symtree->n.sym->assoc->target->symtree->n.sym
++	   && UNLIMITED_POLY (e->symtree->n.sym->assoc->target->symtree->n.sym))
++
+     /* The expression in assoc->target points to a ref to the _data component
+        of the unlimited polymorphic entity.  To get the _len component the last
+        _data ref needs to be stripped and a ref to the _len component added.  */
 Index: gcc/configure.ac
 ===================================================================
 --- a/src/gcc/configure.ac	(.../tags/gcc_6_1_0_release)
@@ -25946,11 +38025,56 @@ Index: gcc/tree-vect-loop.c
  		    mask_producers.safe_push (stmt_info);
  		  bool_result = true;
  
+Index: gcc/ira-build.c
+===================================================================
+--- a/src/gcc/ira-build.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/ira-build.c	(.../branches/gcc-6-branch)
+@@ -2251,7 +2251,7 @@
+ 	     );
+       }
+   qsort (sorted_loops, n, sizeof (ira_loop_tree_node_t), loop_compare_func);
+-  for (i = 0; n - i + 1 > IRA_MAX_LOOPS_NUM; i++)
++  for (i = 0; i < n - IRA_MAX_LOOPS_NUM; i++)
+     {
+       sorted_loops[i]->to_remove_p = true;
+       if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
 Index: gcc/tree-vect-data-refs.c
 ===================================================================
 --- a/src/gcc/tree-vect-data-refs.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/tree-vect-data-refs.c	(.../branches/gcc-6-branch)
-@@ -2751,7 +2751,7 @@
+@@ -692,6 +692,7 @@
+   tree base, base_addr;
+   tree misalign = NULL_TREE;
+   tree aligned_to;
++  tree step;
+   unsigned HOST_WIDE_INT alignment;
+ 
+   if (dump_enabled_p ())
+@@ -822,16 +823,20 @@
+       DR_VECT_AUX (dr)->base_element_aligned = true;
+     }
+ 
++  if (loop && nested_in_vect_loop_p (loop, stmt))
++    step = STMT_VINFO_DR_STEP (stmt_info);
++  else
++    step = DR_STEP (dr);
+   /* If this is a backward running DR then first access in the larger
+      vectype actually is N-1 elements before the address in the DR.
+      Adjust misalign accordingly.  */
+-  if (tree_int_cst_sgn (DR_STEP (dr)) < 0)
++  if (tree_int_cst_sgn (step) < 0)
+     {
+       tree offset = ssize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
+       /* DR_STEP(dr) is the same as -TYPE_SIZE of the scalar type,
+ 	 otherwise we wouldn't be here.  */
+-      offset = fold_build2 (MULT_EXPR, ssizetype, offset, DR_STEP (dr));
+-      /* PLUS because DR_STEP was negative.  */
++      offset = fold_build2 (MULT_EXPR, ssizetype, offset, step);
++      /* PLUS because STEP was negative.  */
+       misalign = size_binop (PLUS_EXPR, misalign, offset);
+     }
+ 
+@@ -2751,7 +2756,7 @@
  	  /* Sorting has ensured that DR_INIT (dra) <= DR_INIT (drb).  */
  	  HOST_WIDE_INT init_a = TREE_INT_CST_LOW (DR_INIT (dra));
  	  HOST_WIDE_INT init_b = TREE_INT_CST_LOW (DR_INIT (drb));
@@ -26321,7 +38445,26 @@ Index: gcc/ipa-inline-analysis.c
  	  else
  	    continue;
  	}
-@@ -3377,7 +3404,8 @@
+@@ -2950,6 +2977,18 @@
+ 	  node->local.can_change_signature = !e;
+ 	}
+     }
++
++  /* Functions called by instrumentation thunk can't change signature
++     because instrumentation thunk modification is not supported.  */
++  if (node->local.can_change_signature)
++    for (e = node->callers; e; e = e->next_caller)
++      if (e->caller->thunk.thunk_p
++	  && e->caller->thunk.add_pointer_bounds_args)
++	{
++	  node->local.can_change_signature = false;
++	  break;
++	}
++
+   estimate_function_body_sizes (node, early);
+ 
+   for (e = node->callees; e; e = e->next_callee)
+@@ -3377,7 +3416,8 @@
  		    ap.by_ref = c->by_ref;
  		    cond_predicate = add_condition (info,
  						    operand_map[c->operand_num],
@@ -26331,7 +38474,7 @@ Index: gcc/ipa-inline-analysis.c
  		  }
  	      }
  	    /* Fixed conditions remains same, construct single
-@@ -4236,6 +4264,7 @@
+@@ -4236,6 +4276,7 @@
  	{
  	  struct condition c;
  	  c.operand_num = streamer_read_uhwi (&ib);
@@ -26339,7 +38482,7 @@ Index: gcc/ipa-inline-analysis.c
  	  c.code = (enum tree_code) streamer_read_uhwi (&ib);
  	  c.val = stream_read_tree (&ib, data_in);
  	  bp = streamer_read_bitpack (&ib);
-@@ -4400,6 +4429,7 @@
+@@ -4400,6 +4441,7 @@
  	  for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
  	    {
  	      streamer_write_uhwi (ob, c->operand_num);
@@ -26669,7 +38812,38 @@ Index: gcc/gimple-fold.c
 ===================================================================
 --- a/src/gcc/gimple-fold.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/gimple-fold.c	(.../branches/gcc-6-branch)
-@@ -3039,10 +3039,25 @@
+@@ -795,22 +795,21 @@
+ 	    {
+ 	      tree src_base, dest_base, fn;
+ 	      HOST_WIDE_INT src_offset = 0, dest_offset = 0;
+-	      HOST_WIDE_INT size = -1;
+-	      HOST_WIDE_INT maxsize = -1;
+-	      bool reverse;
++	      HOST_WIDE_INT maxsize;
+ 
+ 	      srcvar = TREE_OPERAND (src, 0);
+-	      src_base = get_ref_base_and_extent (srcvar, &src_offset,
+-						  &size, &maxsize, &reverse);
++	      src_base = get_addr_base_and_unit_offset (srcvar, &src_offset);
++	      if (src_base == NULL)
++		src_base = srcvar;
+ 	      destvar = TREE_OPERAND (dest, 0);
+-	      dest_base = get_ref_base_and_extent (destvar, &dest_offset,
+-						   &size, &maxsize, &reverse);
++	      dest_base = get_addr_base_and_unit_offset (destvar,
++							 &dest_offset);
++	      if (dest_base == NULL)
++		dest_base = destvar;
+ 	      if (tree_fits_uhwi_p (len))
+ 		maxsize = tree_to_uhwi (len);
+ 	      else
+ 		maxsize = -1;
+-	      src_offset /= BITS_PER_UNIT;
+-	      dest_offset /= BITS_PER_UNIT;
+ 	      if (SSA_VAR_P (src_base)
+ 		  && SSA_VAR_P (dest_base))
+ 		{
+@@ -3039,10 +3038,25 @@
  		}
  	      if (targets.length () == 1)
  		{
@@ -807535,7 +819709,26 @@ Index: gcc/tree-ssa.c
 ===================================================================
 --- a/src/gcc/tree-ssa.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/tree-ssa.c	(.../branches/gcc-6-branch)
-@@ -1590,9 +1590,16 @@
+@@ -1342,6 +1342,18 @@
+       tree decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
+       if (DECL_P (decl)
+ 	  && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (lhs))
++	  /* If the dynamic type of the decl has larger precision than
++	     the decl itself we can't use the decls type for SSA rewriting.  */
++	  && ((! INTEGRAL_TYPE_P (TREE_TYPE (decl))
++	       || compare_tree_int (DECL_SIZE (decl),
++				    TYPE_PRECISION (TREE_TYPE (decl))) == 0)
++	      || (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
++		  && (TYPE_PRECISION (TREE_TYPE (decl))
++		      >= TYPE_PRECISION (TREE_TYPE (lhs)))))
++	  /* Make sure we are not re-writing non-float copying into float
++	     copying as that can incur normalization.  */
++	  && (! FLOAT_TYPE_P (TREE_TYPE (decl))
++	      || types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (decl)))
+ 	  && (TREE_THIS_VOLATILE (decl) == TREE_THIS_VOLATILE (lhs)))
+ 	return false;
+     }
+@@ -1590,9 +1602,16 @@
  		if (gimple_assign_lhs (stmt) != lhs
  		    && !useless_type_conversion_p (TREE_TYPE (lhs),
  						   TREE_TYPE (rhs)))
@@ -807559,7 +819752,37 @@ Index: gcc/tree-vect-stmts.c
 ===================================================================
 --- a/src/gcc/tree-vect-stmts.c	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/tree-vect-stmts.c	(.../branches/gcc-6-branch)
-@@ -3022,8 +3022,10 @@
+@@ -1256,10 +1256,11 @@
+   gimple *init_stmt;
+   tree new_temp;
+ 
+-  if (TREE_CODE (type) == VECTOR_TYPE
+-      && TREE_CODE (TREE_TYPE (val)) != VECTOR_TYPE)
++  /* We abuse this function to push sth to a SSA name with initial 'val'.  */
++  if (! useless_type_conversion_p (type, TREE_TYPE (val)))
+     {
+-      if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
++      gcc_assert (TREE_CODE (type) == VECTOR_TYPE);
++      if (! types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
+ 	{
+ 	  /* Scalar boolean value should be transformed into
+ 	     all zeros or all ones value before building a vector.  */
+@@ -1284,7 +1285,13 @@
+ 	  else
+ 	    {
+ 	      new_temp = make_ssa_name (TREE_TYPE (type));
+-	      init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val);
++	      if (! INTEGRAL_TYPE_P (TREE_TYPE (val)))
++		init_stmt = gimple_build_assign (new_temp,
++						 fold_build1 (VIEW_CONVERT_EXPR,
++							      TREE_TYPE (type),
++							      val));
++	      else
++		init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val);
+ 	      vect_init_vector_1 (stmt, init_stmt, gsi);
+ 	      val = new_temp;
+ 	    }
+@@ -3022,8 +3029,10 @@
      {
        STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_push (bestn->decl);
        for (i = 0; i < nargs; i++)
@@ -807572,7 +819795,7 @@ Index: gcc/tree-vect-stmts.c
  	  {
  	    STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_grow_cleared (i * 3
  									+ 1);
-@@ -3159,6 +3161,7 @@
+@@ -3159,6 +3168,7 @@
  	      vargs.safe_push (op);
  	      break;
  	    case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP:
@@ -807580,7 +819803,7 @@ Index: gcc/tree-vect-stmts.c
  	      if (j == 0)
  		{
  		  gimple_seq stmts;
-@@ -3222,6 +3225,8 @@
+@@ -3222,6 +3232,8 @@
  		  vargs.safe_push (new_temp);
  		}
  	      break;
@@ -807589,6 +819812,20 @@ Index: gcc/tree-vect-stmts.c
  	    case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP:
  	    case SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP:
  	    case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP:
+@@ -5074,11 +5086,8 @@
+ 	    vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
+ 			       slp_node, -1);
+ 	  if (op_type == ternary_op)
+-	    {
+-	      vec_oprnds2.create (1);
+-	      vec_oprnds2.quick_push (vect_get_vec_def_for_operand (op2,
+-		                                                    stmt));
+-	    }
++	    vect_get_vec_defs (op2, NULL_TREE, stmt, &vec_oprnds2, NULL,
++			       slp_node, -1);
+ 	}
+       else
+ 	{
 Index: gcc/tree-inline.c
 ===================================================================
 --- a/src/gcc/tree-inline.c	(.../tags/gcc_6_1_0_release)
@@ -807602,6 +819839,24 @@ Index: gcc/tree-inline.c
      return 0;
    if (!id->dependence_map)
      id->dependence_map = new hash_map<dependence_hash, unsigned short>;
+Index: gcc/tree-object-size.c
+===================================================================
+--- a/src/gcc/tree-object-size.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/tree-object-size.c	(.../branches/gcc-6-branch)
+@@ -43,7 +43,12 @@
+   unsigned int *stack, *tos;
+ };
+ 
+-static const unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 };
++static const unsigned HOST_WIDE_INT unknown[4] = {
++  HOST_WIDE_INT_M1U,
++  HOST_WIDE_INT_M1U,
++  0,
++  0
++};
+ 
+ static tree compute_object_offset (const_tree, const_tree);
+ static unsigned HOST_WIDE_INT addr_object_size (struct object_size_info *,
 Index: gcc/hsa-gen.c
 ===================================================================
 --- a/src/gcc/hsa-gen.c	(.../tags/gcc_6_1_0_release)
@@ -807966,6 +820221,53 @@ Index: gcc/config/s390/s390.c
  
    tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
    unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+@@ -12405,17 +12405,13 @@
+     {
+       /* Store the alignment to be able to check if we can use
+ 	 a larl/load-relative instruction.  We only handle the cases
+-	 that can go wrong (i.e. no FUNC_DECLs).  If a symref does
+-	 not have any flag we assume it to be correctly aligned.  */
+-
+-      if (DECL_ALIGN (decl) % 64)
+-	SYMBOL_FLAG_SET_NOTALIGN8 (XEXP (rtl, 0));
+-
+-      if (DECL_ALIGN (decl) % 32)
+-	SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
+-
++	 that can go wrong (i.e. no FUNC_DECLs).  */
+       if (DECL_ALIGN (decl) == 0 || DECL_ALIGN (decl) % 16)
+ 	SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
++      else if (DECL_ALIGN (decl) % 32)
++	SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
++      else if (DECL_ALIGN (decl) % 64)
++	SYMBOL_FLAG_SET_NOTALIGN8 (XEXP (rtl, 0));
+     }
+ 
+   /* Literal pool references don't have a decl so they are handled
+@@ -12423,18 +12419,14 @@
+      entry to decide upon the alignment.  */
+   if (MEM_P (rtl)
+       && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
+-      && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl, 0))
+-      && MEM_ALIGN (rtl) != 0
+-      && GET_MODE_BITSIZE (GET_MODE (rtl)) != 0)
++      && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl, 0)))
+     {
+-      if (MEM_ALIGN (rtl) % 64)
+-	SYMBOL_FLAG_SET_NOTALIGN8 (XEXP (rtl, 0));
+-
+-      if (MEM_ALIGN (rtl) % 32)
+-	SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
+-
+       if (MEM_ALIGN (rtl) == 0 || MEM_ALIGN (rtl) % 16)
+ 	SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
++      else if (MEM_ALIGN (rtl) % 32)
++	SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
++      else if (MEM_ALIGN (rtl) % 64)
++	SYMBOL_FLAG_SET_NOTALIGN8 (XEXP (rtl, 0));
+     }
+ }
+ 
 Index: gcc/config/sparc/driver-sparc.c
 ===================================================================
 --- a/src/gcc/config/sparc/driver-sparc.c	(.../tags/gcc_6_1_0_release)
@@ -810272,6 +822574,21 @@ Index: gcc/config/avr/gen-avr-mmcu-specs.c
        fprintf (f, "\n\n");
      }
  
+Index: gcc/config/avr/avr.c
+===================================================================
+--- a/src/gcc/config/avr/avr.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/avr/avr.c	(.../branches/gcc-6-branch)
+@@ -9721,7 +9721,9 @@
+             {
+               const char *sname = ACONCAT ((new_prefix,
+                                             name + strlen (old_prefix), NULL));
+-              return get_section (sname, sect->common.flags, sect->named.decl);
++              return get_section (sname,
++                                  sect->common.flags & ~SECTION_DECLARED,
++                                  sect->named.decl);
+             }
+         }
+ 
 Index: gcc/config/rtems.h
 ===================================================================
 --- a/src/gcc/config/rtems.h	(.../tags/gcc_6_1_0_release)
@@ -810284,6 +822601,56 @@ Index: gcc/config/rtems.h
 + -latomic -lc -lgcc --end-group %{!qnolinkcmds: -T linkcmds%s}}}"
  
  #define TARGET_POSIX_IO
+Index: gcc/config/aarch64/arm_neon.h
+===================================================================
+--- a/src/gcc/config/aarch64/arm_neon.h	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/aarch64/arm_neon.h	(.../branches/gcc-6-branch)
+@@ -17856,19 +17856,19 @@
+ __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+ vmaxnm_f32 (float32x2_t __a, float32x2_t __b)
+ {
+-  return __builtin_aarch64_smaxv2sf (__a, __b);
++  return __builtin_aarch64_fmaxv2sf (__a, __b);
+ }
+ 
+ __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+ vmaxnmq_f32 (float32x4_t __a, float32x4_t __b)
+ {
+-  return __builtin_aarch64_smaxv4sf (__a, __b);
++  return __builtin_aarch64_fmaxv4sf (__a, __b);
+ }
+ 
+ __extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
+ vmaxnmq_f64 (float64x2_t __a, float64x2_t __b)
+ {
+-  return __builtin_aarch64_smaxv2df (__a, __b);
++  return __builtin_aarch64_fmaxv2df (__a, __b);
+ }
+ 
+ /* vmaxv  */
+@@ -18086,19 +18086,19 @@
+ __extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+ vminnm_f32 (float32x2_t __a, float32x2_t __b)
+ {
+-  return __builtin_aarch64_sminv2sf (__a, __b);
++  return __builtin_aarch64_fminv2sf (__a, __b);
+ }
+ 
+ __extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+ vminnmq_f32 (float32x4_t __a, float32x4_t __b)
+ {
+-  return __builtin_aarch64_sminv4sf (__a, __b);
++  return __builtin_aarch64_fminv4sf (__a, __b);
+ }
+ 
+ __extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
+ vminnmq_f64 (float64x2_t __a, float64x2_t __b)
+ {
+-  return __builtin_aarch64_sminv2df (__a, __b);
++  return __builtin_aarch64_fminv2df (__a, __b);
+ }
+ 
+ /* vminv  */
 Index: gcc/config/aarch64/aarch64-simd.md
 ===================================================================
 --- a/src/gcc/config/aarch64/aarch64-simd.md	(.../tags/gcc_6_1_0_release)
@@ -810305,6 +822672,114 @@ Index: gcc/config/aarch64/aarch64-simd.md
  ;; FP Max/Min
  ;; Max/Min are introduced by idiom recognition by GCC's mid-end.  An
  ;; expression like:
+Index: gcc/config/aarch64/aarch64-simd-builtins.def
+===================================================================
+--- a/src/gcc/config/aarch64/aarch64-simd-builtins.def	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/aarch64/aarch64-simd-builtins.def	(.../branches/gcc-6-branch)
+@@ -244,13 +244,17 @@
+   /* Implemented by <maxmin><mode>3.
+      smax variants map to fmaxnm,
+      smax_nan variants map to fmax.  */
+-  BUILTIN_VDQIF (BINOP, smax, 3)
+-  BUILTIN_VDQIF (BINOP, smin, 3)
++  BUILTIN_VDQ_BHSI (BINOP, smax, 3)
++  BUILTIN_VDQ_BHSI (BINOP, smin, 3)
+   BUILTIN_VDQ_BHSI (BINOP, umax, 3)
+   BUILTIN_VDQ_BHSI (BINOP, umin, 3)
+   BUILTIN_VDQF (BINOP, smax_nan, 3)
+   BUILTIN_VDQF (BINOP, smin_nan, 3)
+ 
++  /* Implemented by <fmaxmin><mode>3.  */
++  BUILTIN_VDQF (BINOP, fmax, 3)
++  BUILTIN_VDQF (BINOP, fmin, 3)
++
+   /* Implemented by aarch64_<maxmin_uns>p<mode>.  */
+   BUILTIN_VDQ_BHSI (BINOP, smaxp, 0)
+   BUILTIN_VDQ_BHSI (BINOP, sminp, 0)
+Index: gcc/config/rs6000/476.md
+===================================================================
+--- a/src/gcc/config/rs6000/476.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/476.md	(.../branches/gcc-6-branch)
+@@ -124,7 +124,7 @@
+    ppc476_f_pipe+ppc476_i_pipe")
+ 
+ (define_insn_reservation "ppc476-fp" 6
+-  (and (eq_attr "type" "fp,dmul")
++  (and (eq_attr "type" "fp,fpsimple,dmul")
+        (eq_attr "cpu" "ppc476"))
+   "ppc476_issue_fp,\
+    ppc476_f_pipe")
+Index: gcc/config/rs6000/e300c2c3.md
+===================================================================
+--- a/src/gcc/config/rs6000/e300c2c3.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/e300c2c3.md	(.../branches/gcc-6-branch)
+@@ -150,7 +150,7 @@
+   "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,nothing,ppce300c3_retire")
+ 
+ (define_insn_reservation "ppce300c3_fp" 3
+-  (and (eq_attr "type" "fp")
++  (and (eq_attr "type" "fp,fpsimple")
+        (eq_attr "cpu" "ppce300c3"))
+   "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,nothing,ppce300c3_retire")
+ 
+Index: gcc/config/rs6000/power8.md
+===================================================================
+--- a/src/gcc/config/rs6000/power8.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/power8.md	(.../branches/gcc-6-branch)
+@@ -317,7 +317,7 @@
+ 
+ ; VS Unit (includes FP/VSX/VMX/DFP/Crypto)
+ (define_insn_reservation "power8-fp" 6
+-  (and (eq_attr "type" "fp,dmul")
++  (and (eq_attr "type" "fp,fpsimple,dmul,dfp")
+        (eq_attr "cpu" "power8"))
+   "DU_any_power8,VSU_power8")
+ 
+@@ -350,7 +350,8 @@
+   "DU_any_power8,VSU_power8")
+ 
+ (define_insn_reservation "power8-vecsimple" 2
+-  (and (eq_attr "type" "vecperm,vecsimple,veccmp")
++  (and (eq_attr "type" "vecperm,vecsimple,veclogical,vecmove,veccmp,
++			veccmpfx")
+        (eq_attr "cpu" "power8"))
+   "DU_any_power8,VSU_power8")
+ 
+Index: gcc/config/rs6000/6xx.md
+===================================================================
+--- a/src/gcc/config/rs6000/6xx.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/6xx.md	(.../branches/gcc-6-branch)
+@@ -160,7 +160,7 @@
+   "fpu_6xx")
+ 
+ (define_insn_reservation "ppc604-fp" 3
+-  (and (eq_attr "type" "fp")
++  (and (eq_attr "type" "fp,fpsimple")
+        (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+   "fpu_6xx")
+ 
+Index: gcc/config/rs6000/8540.md
+===================================================================
+--- a/src/gcc/config/rs6000/8540.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/8540.md	(.../branches/gcc-6-branch)
+@@ -190,7 +190,7 @@
+ 
+ ;; Simple vector
+ (define_insn_reservation "ppc8540_simple_vector" 1
+-  (and (eq_attr "type" "vecsimple")
++  (and (eq_attr "type" "vecsimple,veclogical,vecmove")
+        (eq_attr "cpu" "ppc8540,ppc8548"))
+   "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+ 
+@@ -202,7 +202,7 @@
+ 
+ ;; Vector compare
+ (define_insn_reservation "ppc8540_vector_compare" 1
+-  (and (eq_attr "type" "veccmp")
++  (and (eq_attr "type" "veccmp,veccmpfx")
+        (eq_attr "cpu" "ppc8540,ppc8548"))
+   "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+ 
 Index: gcc/config/rs6000/vector.md
 ===================================================================
 --- a/src/gcc/config/rs6000/vector.md	(.../tags/gcc_6_1_0_release)
@@ -810349,6 +822824,50 @@ Index: gcc/config/rs6000/vector.md
  

  ;; Same size conversions
  (define_expand "float<VEC_int><mode>2"
+Index: gcc/config/rs6000/7450.md
+===================================================================
+--- a/src/gcc/config/rs6000/7450.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/7450.md	(.../branches/gcc-6-branch)
+@@ -120,7 +120,7 @@
+   "ppc7450_du,fpu_7450")
+ 
+ (define_insn_reservation "ppc7450-fp" 5
+-  (and (eq_attr "type" "fp,dmul")
++  (and (eq_attr "type" "fp,fpsimple,dmul")
+        (eq_attr "cpu" "ppc7450"))
+   "ppc7450_du,fpu_7450")
+ 
+@@ -162,7 +162,7 @@
+ 
+ ;; Altivec
+ (define_insn_reservation "ppc7450-vecsimple" 1
+-  (and (eq_attr "type" "vecsimple")
++  (and (eq_attr "type" "vecsimple,veclogical,vecmove")
+        (eq_attr "cpu" "ppc7450"))
+   "ppc7450_du,ppc7450_vec_du,vecsmpl_7450")
+ 
+@@ -172,7 +172,7 @@
+   "ppc7450_du,ppc7450_vec_du,veccmplx_7450")
+ 
+ (define_insn_reservation "ppc7450-veccmp" 2
+-  (and (eq_attr "type" "veccmp")
++  (and (eq_attr "type" "veccmp,veccmpfx")
+        (eq_attr "cpu" "ppc7450"))
+   "ppc7450_du,ppc7450_vec_du,veccmplx_7450")
+ 
+Index: gcc/config/rs6000/440.md
+===================================================================
+--- a/src/gcc/config/rs6000/440.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/440.md	(.../branches/gcc-6-branch)
+@@ -107,7 +107,7 @@
+   "ppc440_issue,ppc440_f_pipe+ppc440_i_pipe")
+ 
+ (define_insn_reservation "ppc440-fp" 5
+-  (and (eq_attr "type" "fp,dmul")
++  (and (eq_attr "type" "fp,fpsimple,dmul")
+        (eq_attr "cpu" "ppc440"))
+   "ppc440_issue,ppc440_f_pipe")
+ 
 Index: gcc/config/rs6000/constraints.md
 ===================================================================
 --- a/src/gcc/config/rs6000/constraints.md	(.../tags/gcc_6_1_0_release)
@@ -810391,6 +822910,37 @@ Index: gcc/config/rs6000/constraints.md
  ;; Altivec style load/store that ignores the bottom bits of the address
  (define_memory_constraint "wZ"
    "Indexed or indirect memory operand, ignoring the bottom 4 bits"
+Index: gcc/config/rs6000/power6.md
+===================================================================
+--- a/src/gcc/config/rs6000/power6.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/power6.md	(.../branches/gcc-6-branch)
+@@ -500,7 +500,7 @@
+ (define_bypass 9 "power6-mtcr" "power6-branch")
+ 
+ (define_insn_reservation "power6-fp" 6
+-  (and (eq_attr "type" "fp,dmul")
++  (and (eq_attr "type" "fp,fpsimple,dmul,dfp")
+        (eq_attr "cpu" "power6"))
+   "FPU_power6")
+ 
+@@ -556,7 +556,7 @@
+   "LSF_power6")
+ 
+ (define_insn_reservation "power6-vecsimple" 3
+-  (and (eq_attr "type" "vecsimple")
++  (and (eq_attr "type" "vecsimple,veclogical,vecmove")
+        (eq_attr "cpu" "power6"))
+   "FPU_power6")
+ 
+@@ -568,7 +568,7 @@
+ (define_bypass 4 "power6-vecsimple" "power6-vecstore" )
+ 
+ (define_insn_reservation "power6-veccmp" 1
+-  (and (eq_attr "type" "veccmp")
++  (and (eq_attr "type" "veccmp,veccmpfx")
+        (eq_attr "cpu" "power6"))
+   "FPU_power6")
+ 
 Index: gcc/config/rs6000/predicates.md
 ===================================================================
 --- a/src/gcc/config/rs6000/predicates.md	(.../tags/gcc_6_1_0_release)
@@ -810561,28 +823111,616 @@ Index: gcc/config/rs6000/predicates.md
  ;; Return 1 if OP is a comparison operation that is valid for a branch
  ;; insn, which is true if the corresponding bit in the CC register is set.
  (define_predicate "branch_positive_comparison_operator"
+Index: gcc/config/rs6000/htm.md
+===================================================================
+--- a/src/gcc/config/rs6000/htm.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/htm.md	(.../branches/gcc-6-branch)
+@@ -72,7 +72,7 @@
+    (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
+   "TARGET_HTM"
+   "tabort. %0"
+-  [(set_attr "type" "htm")
++  [(set_attr "type" "htmsimple")
+    (set_attr "length" "4")])
+ 
+ (define_expand "tabort<wd>c"
+@@ -98,7 +98,7 @@
+    (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))]
+   "TARGET_HTM"
+   "tabort<wd>c. %0,%1,%2"
+-  [(set_attr "type" "htm")
++  [(set_attr "type" "htmsimple")
+    (set_attr "length" "4")])
+ 
+ (define_expand "tabort<wd>ci"
+@@ -124,7 +124,7 @@
+    (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))]
+   "TARGET_HTM"
+   "tabort<wd>ci. %0,%1,%2"
+-  [(set_attr "type" "htm")
++  [(set_attr "type" "htmsimple")
+    (set_attr "length" "4")])
+ 
+ (define_expand "tbegin"
+@@ -208,7 +208,7 @@
+    (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))]
+   "TARGET_HTM"
+   "trechkpt."
+-  [(set_attr "type" "htm")
++  [(set_attr "type" "htmsimple")
+    (set_attr "length" "4")])
+ 
+ (define_expand "treclaim"
+@@ -230,7 +230,7 @@
+    (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
+   "TARGET_HTM"
+   "treclaim. %0"
+-  [(set_attr "type" "htm")
++  [(set_attr "type" "htmsimple")
+    (set_attr "length" "4")])
+ 
+ (define_expand "tsr"
+@@ -252,7 +252,7 @@
+    (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
+   "TARGET_HTM"
+   "tsr. %0"
+-  [(set_attr "type" "htm")
++  [(set_attr "type" "htmsimple")
+    (set_attr "length" "4")])
+ 
+ (define_expand "ttest"
+@@ -272,7 +272,7 @@
+    (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))]
+   "TARGET_HTM"
+   "tabortwci. 0,1,0"
+-  [(set_attr "type" "htm")
++  [(set_attr "type" "htmsimple")
+    (set_attr "length" "4")])
+ 
+ (define_insn "htm_mfspr_<mode>"
+Index: gcc/config/rs6000/rs64.md
+===================================================================
+--- a/src/gcc/config/rs6000/rs64.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/rs64.md	(.../branches/gcc-6-branch)
+@@ -111,7 +111,7 @@
+   "mciu_rs64,fpu_rs64,bpu_rs64")
+ 
+ (define_insn_reservation "rs64a-fp" 4
+-  (and (eq_attr "type" "fp,dmul")
++  (and (eq_attr "type" "fp,fpsimple,dmul")
+        (eq_attr "cpu" "rs64a"))
+   "mciu_rs64,fpu_rs64")
+ 
+Index: gcc/config/rs6000/e6500.md
+===================================================================
+--- a/src/gcc/config/rs6000/e6500.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/e6500.md	(.../branches/gcc-6-branch)
+@@ -205,7 +205,7 @@
+ 
+ ;; VSFX.
+ (define_insn_reservation "e6500_vecsimple" 1
+-  (and (eq_attr "type" "vecsimple,veccmp")
++  (and (eq_attr "type" "vecsimple,veclogical,vecmove,veccmp,veccmpfx")
+        (eq_attr "cpu" "ppce6500"))
+   "e6500_decode,e6500_vec")
+ 
+Index: gcc/config/rs6000/power9.md
+===================================================================
+--- a/src/gcc/config/rs6000/power9.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/power9.md	(.../branches/gcc-6-branch)
+@@ -0,0 +1,477 @@
++;; Scheduling description for IBM POWER9 processor.
++;; Copyright (C) 2016 Free Software Foundation, Inc.
++;;
++;; Contributed by Pat Haugen (pthaugen at us.ibm.com).
++
++;; This file is part of GCC.
++;;
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++;;
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++
++(define_automaton "power9dsp,power9lsu,power9vsu,power9misc")
++
++(define_cpu_unit "lsu0_power9,lsu1_power9,lsu2_power9,lsu3_power9" "power9lsu")
++(define_cpu_unit "vsu0_power9,vsu1_power9,vsu2_power9,vsu3_power9" "power9vsu")
++; Two vector permute units, part of vsu
++(define_cpu_unit "prm0_power9,prm1_power9" "power9vsu")
++; Two fixed point divide units, not pipelined
++(define_cpu_unit "fx_div0_power9,fx_div1_power9" "power9misc")
++(define_cpu_unit "bru_power9,cryptu_power9,dfu_power9" "power9misc")
++
++(define_cpu_unit "x0_power9,x1_power9,xa0_power9,xa1_power9,
++		  x2_power9,x3_power9,xb0_power9,xb1_power9,
++		  br0_power9,br1_power9" "power9dsp")
++
++
++; Dispatch port reservations
++;
++; Power9 can dispatch a maximum of 6 iops per cycle with the following
++; general restrictions (other restrictions also apply):
++;   1) At most 2 iops per execution slice
++;   2) At most 2 iops to the branch unit
++; Note that insn position in a dispatch group of 6 insns does not infer which
++; execution slice the insn is routed to.  The units are used to infer the
++; conflicts that exist (i.e. an 'even' requirement will preclude dispatch
++; with 2 insns with 'superslice' requirement).
++
++; The xa0/xa1 units really represent the 3rd dispatch port for a superslice but
++; are listed as separate units to allow those insns that preclude its use to
++; still be scheduled two to a superslice while reserving the 3rd slot.  The
++; same applies for xb0/xb1.
++(define_reservation "DU_xa_power9" "xa0_power9+xa1_power9")
++(define_reservation "DU_xb_power9" "xb0_power9+xb1_power9")
++
++; Any execution slice dispatch
++(define_reservation "DU_any_power9"
++		    "x0_power9|x1_power9|DU_xa_power9|x2_power9|x3_power9|
++		     DU_xb_power9")
++
++; Even slice, actually takes even/odd slots
++(define_reservation "DU_even_power9" "x0_power9+x1_power9|x2_power9+x3_power9")
++
++; Slice plus 3rd slot
++(define_reservation "DU_slice_3_power9"
++		    "x0_power9+xa0_power9|x1_power9+xa1_power9|
++		     x2_power9+xb0_power9|x3_power9+xb1_power9")
++
++; Superslice
++(define_reservation "DU_super_power9"
++		    "x0_power9+x1_power9|x2_power9+x3_power9")
++
++; 2-way cracked
++(define_reservation "DU_C2_power9" "x0_power9+x1_power9|
++				    x1_power9+DU_xa_power9|
++				    x1_power9+x2_power9|
++				    DU_xa_power9+x2_power9|
++				    x2_power9+x3_power9|
++				    x3_power9+DU_xb_power9")
++
++; 2-way cracked plus 3rd slot
++(define_reservation "DU_C2_3_power9" "x0_power9+x1_power9+xa0_power9|
++				      x1_power9+x2_power9+xa0_power9|
++				      x1_power9+x2_power9+xb0_power9|
++				      x2_power9+x3_power9+xb0_power9")
++
++; 3-way cracked (consumes whole decode/dispatch cycle)
++(define_reservation "DU_C3_power9"
++		    "x0_power9+x1_power9+xa0_power9+xa1_power9+x2_power9+
++		     x3_power9+xb0_power9+xb1_power9+br0_power9+br1_power9")
++
++; Branch ports
++(define_reservation "DU_branch_power9" "br0_power9|br1_power9")
++
++
++; Execution unit reservations
++(define_reservation "LSU_power9"
++		    "lsu0_power9|lsu1_power9|lsu2_power9|lsu3_power9")
++
++(define_reservation "LSU_pair_power9"
++		    "lsu0_power9+lsu1_power9|lsu1_power9+lsu2_power9|
++		     lsu2_power9+lsu3_power9|lsu3_power9+lsu0_power9")
++
++(define_reservation "VSU_power9"
++		    "vsu0_power9|vsu1_power9|vsu2_power9|vsu3_power9")
++
++(define_reservation "VSU_super_power9"
++		    "vsu0_power9+vsu1_power9|vsu2_power9+vsu3_power9")
++
++(define_reservation "VSU_PRM_power9" "prm0_power9|prm1_power9")
++
++
++; LS Unit
++(define_insn_reservation "power9-load" 4
++  (and (eq_attr "type" "load")
++       (eq_attr "sign_extend" "no")
++       (eq_attr "update" "no")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,LSU_power9")
++
++(define_insn_reservation "power9-load-update" 4
++  (and (eq_attr "type" "load")
++       (eq_attr "sign_extend" "no")
++       (eq_attr "update" "yes")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_power9,LSU_power9+VSU_power9")
++
++(define_insn_reservation "power9-load-ext" 6
++  (and (eq_attr "type" "load")
++       (eq_attr "sign_extend" "yes")
++       (eq_attr "update" "no")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_power9,LSU_power9")
++
++(define_insn_reservation "power9-load-ext-update" 6
++  (and (eq_attr "type" "load")
++       (eq_attr "sign_extend" "yes")
++       (eq_attr "update" "yes")
++       (eq_attr "cpu" "power9"))
++  "DU_C3_power9,LSU_power9+VSU_power9")
++
++(define_insn_reservation "power9-fpload-double" 4
++  (and (eq_attr "type" "fpload")
++       (eq_attr "update" "no")
++       (eq_attr "size" "64")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,LSU_power9")
++
++(define_insn_reservation "power9-fpload-update-double" 4
++  (and (eq_attr "type" "fpload")
++       (eq_attr "update" "yes")
++       (eq_attr "size" "64")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_3_power9,LSU_power9+VSU_power9")
++
++; SFmode loads are cracked and have additional 2 cycles over DFmode
++(define_insn_reservation "power9-fpload-single" 6
++  (and (eq_attr "type" "fpload")
++       (eq_attr "update" "no")
++       (eq_attr "size" "32")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_3_power9,LSU_power9")
++
++(define_insn_reservation "power9-fpload-update-single" 6
++  (and (eq_attr "type" "fpload")
++       (eq_attr "update" "yes")
++       (eq_attr "size" "32")
++       (eq_attr "cpu" "power9"))
++  "DU_C3_power9,LSU_power9+VSU_power9")
++
++(define_insn_reservation "power9-vecload" 5
++  (and (eq_attr "type" "vecload")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,LSU_pair_power9")
++
++; Store data can issue 2 cycles after AGEN issue, 3 cycles for vector store
++(define_insn_reservation "power9-store" 0
++  (and (eq_attr "type" "store")
++       (eq_attr "update" "no")
++       (eq_attr "indexed" "no")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,LSU_power9")
++
++(define_insn_reservation "power9-store-indexed" 0
++  (and (eq_attr "type" "store")
++       (eq_attr "update" "no")
++       (eq_attr "indexed" "yes")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,LSU_power9")
++
++; Update forms have 2 cycle latency for updated addr reg
++(define_insn_reservation "power9-store-update" 2
++  (and (eq_attr "type" "store")
++       (eq_attr "update" "yes")
++       (eq_attr "indexed" "no")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_3_power9,LSU_power9+VSU_power9")
++
++; Update forms have 2 cycle latency for updated addr reg
++(define_insn_reservation "power9-store-update-indexed" 2
++  (and (eq_attr "type" "store")
++       (eq_attr "update" "yes")
++       (eq_attr "indexed" "yes")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_3_power9,LSU_power9+VSU_power9")
++
++(define_insn_reservation "power9-fpstore" 0
++  (and (eq_attr "type" "fpstore")
++       (eq_attr "update" "no")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,LSU_power9")
++
++; Update forms have 2 cycle latency for updated addr reg
++(define_insn_reservation "power9-fpstore-update" 2
++  (and (eq_attr "type" "fpstore")
++       (eq_attr "update" "yes")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_3_power9,LSU_power9+VSU_power9")
++
++(define_insn_reservation "power9-vecstore" 0
++  (and (eq_attr "type" "vecstore")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,LSU_pair_power9")
++
++(define_insn_reservation "power9-larx" 4
++  (and (eq_attr "type" "load_l")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,LSU_power9")
++
++(define_insn_reservation "power9-stcx" 2
++  (and (eq_attr "type" "store_c")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_3_power9,LSU_power9+VSU_power9")
++
++(define_insn_reservation "power9-sync" 4
++  (and (eq_attr "type" "sync,isync")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,LSU_power9")
++
++
++; VSU Execution Unit
++
++; Fixed point ops
++
++; Most ALU insns are simple 2 cycle, including record form
++(define_insn_reservation "power9-alu" 2
++  (and (ior (eq_attr "type" "add,cmp,exts,integer,logical,isel")
++	    (and (eq_attr "type" "insert,shift")
++		 (eq_attr "dot" "no")))
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,VSU_power9")
++
++; Record form rotate/shift are cracked
++(define_insn_reservation "power9-cracked-alu" 2
++  (and (eq_attr "type" "insert,shift")
++       (eq_attr "dot" "yes")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_power9,VSU_power9")
++; 4 cycle CR latency
++(define_bypass 4 "power9-cracked-alu"
++		 "power9-crlogical,power9-mfcr,power9-mfcrf,power9-branch")
++
++(define_insn_reservation "power9-alu2" 3
++  (and (eq_attr "type" "cntlz,popcnt,trap")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,VSU_power9")
++
++; Treat 'two' and 'three' types as 2 or 3 way cracked
++(define_insn_reservation "power9-two" 4
++  (and (eq_attr "type" "two")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_power9,VSU_power9")
++
++(define_insn_reservation "power9-three" 6
++  (and (eq_attr "type" "three")
++       (eq_attr "cpu" "power9"))
++  "DU_C3_power9,VSU_power9")
++
++(define_insn_reservation "power9-mul" 4
++  (and (eq_attr "type" "mul")
++       (eq_attr "dot" "no")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,VSU_power9")
++
++(define_insn_reservation "power9-mul-compare" 4
++  (and (eq_attr "type" "mul")
++       (eq_attr "dot" "yes")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_power9,VSU_power9")
++; 6 cycle CR latency
++(define_bypass 6 "power9-mul-compare"
++		 "power9-crlogical,power9-mfcr,power9-mfcrf,power9-branch")
++
++; Fixed point divides reserve the divide units for a minimum of 8 cycles
++(define_insn_reservation "power9-idiv" 16
++  (and (eq_attr "type" "div")
++       (eq_attr "size" "32")
++       (eq_attr "cpu" "power9"))
++  "DU_even_power9,fx_div0_power9*8|fx_div1_power9*8")
++
++(define_insn_reservation "power9-ldiv" 24
++  (and (eq_attr "type" "div")
++       (eq_attr "size" "64")
++       (eq_attr "cpu" "power9"))
++  "DU_even_power9,fx_div0_power9*8|fx_div1_power9*8")
++
++(define_insn_reservation "power9-crlogical" 2
++  (and (eq_attr "type" "cr_logical,delayed_cr")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,VSU_power9")
++
++(define_insn_reservation "power9-mfcrf" 2
++  (and (eq_attr "type" "mfcrf")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,VSU_power9")
++
++(define_insn_reservation "power9-mfcr" 6
++  (and (eq_attr "type" "mfcr")
++       (eq_attr "cpu" "power9"))
++  "DU_C3_power9,VSU_power9")
++
++; Should differentiate between 1 cr field and > 1 since target of > 1 cr
++; is cracked
++(define_insn_reservation "power9-mtcr" 2
++  (and (eq_attr "type" "mtcr")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,VSU_power9")
++
++; Move to LR/CTR are executed in VSU
++(define_insn_reservation "power9-mtjmpr" 5
++  (and (eq_attr "type" "mtjmpr")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,VSU_power9")
++
++; Floating point/Vector ops
++(define_insn_reservation "power9-fpsimple" 2
++  (and (eq_attr "type" "fpsimple")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,VSU_power9")
++
++(define_insn_reservation "power9-fp" 7
++  (and (eq_attr "type" "fp,dmul")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,VSU_power9")
++
++(define_insn_reservation "power9-fpcompare" 3
++  (and (eq_attr "type" "fpcompare")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,VSU_power9")
++
++; FP div/sqrt are executed in the VSU slices.  They are not pipelined wrt other
++; divide insns, but for the most part do not block pipelined ops.
++(define_insn_reservation "power9-sdiv" 22
++  (and (eq_attr "type" "sdiv")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,VSU_power9")
++
++(define_insn_reservation "power9-ddiv" 33
++  (and (eq_attr "type" "ddiv")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,VSU_power9")
++
++(define_insn_reservation "power9-sqrt" 26
++  (and (eq_attr "type" "ssqrt")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,VSU_power9")
++
++(define_insn_reservation "power9-dsqrt" 36
++  (and (eq_attr "type" "dsqrt")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,VSU_power9")
++
++(define_insn_reservation "power9-vec-2cyc" 2
++  (and (eq_attr "type" "vecmove,veclogical,vecexts,veccmpfx")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,VSU_super_power9")
++
++(define_insn_reservation "power9-veccmp" 3
++  (and (eq_attr "type" "veccmp")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,VSU_super_power9")
++
++(define_insn_reservation "power9-vecsimple" 3
++  (and (eq_attr "type" "vecsimple")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,VSU_super_power9")
++
++(define_insn_reservation "power9-vecnormal" 7
++  (and (eq_attr "type" "vecfloat,vecdouble")
++       (eq_attr "size" "!128")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,VSU_super_power9")
++
++; Quad-precision FP ops, execute in DFU
++(define_insn_reservation "power9-qp" 12
++  (and (eq_attr "type" "vecfloat,vecdouble")
++       (eq_attr "size" "128")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,dfu_power9")
++
++(define_insn_reservation "power9-vecperm" 3
++  (and (eq_attr "type" "vecperm")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,VSU_PRM_power9")
++
++(define_insn_reservation "power9-veccomplex" 7
++  (and (eq_attr "type" "veccomplex")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,VSU_super_power9")
++
++(define_insn_reservation "power9-vecfdiv" 28
++  (and (eq_attr "type" "vecfdiv")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,VSU_super_power9")
++
++(define_insn_reservation "power9-vecdiv" 32
++  (and (eq_attr "type" "vecdiv")
++       (eq_attr "size" "!128")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,VSU_super_power9")
++
++(define_insn_reservation "power9-qpdiv" 56
++  (and (eq_attr "type" "vecdiv")
++       (eq_attr "size" "128")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,dfu_power9")
++
++(define_insn_reservation "power9-mffgpr" 2
++  (and (eq_attr "type" "mffgpr")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,VSU_power9")
++
++(define_insn_reservation "power9-mftgpr" 2
++  (and (eq_attr "type" "mftgpr")
++       (eq_attr "cpu" "power9"))
++  "DU_slice_3_power9,VSU_power9")
++
++
++; Branch Unit
++; Move from LR/CTR are executed in BRU but consume a writeback port from an
++; execution slice.
++(define_insn_reservation "power9-mfjmpr" 6
++  (and (eq_attr "type" "mfjmpr")
++       (eq_attr "cpu" "power9"))
++  "DU_branch_power9,bru_power9+VSU_power9")
++
++; Branch is 2 cycles
++(define_insn_reservation "power9-branch" 2
++  (and (eq_attr "type" "jmpreg,branch")
++       (eq_attr "cpu" "power9"))
++  "DU_branch_power9,bru_power9")
++
++
++; Crypto Unit
++(define_insn_reservation "power9-crypto" 6
++  (and (eq_attr "type" "crypto")
++       (eq_attr "cpu" "power9"))
++  "DU_super_power9,cryptu_power9")
++
++
++; HTM Unit
++(define_insn_reservation "power9-htm" 4
++  (and (eq_attr "type" "htm")
++       (eq_attr "cpu" "power9"))
++  "DU_C2_power9,LSU_power9")
++
++(define_insn_reservation "power9-htm-simple" 2
++  (and (eq_attr "type" "htmsimple")
++       (eq_attr "cpu" "power9"))
++  "DU_any_power9,VSU_power9")
++
++
++; DFP Unit
++(define_insn_reservation "power9-dfp" 12
++  (and (eq_attr "type" "dfp")
++       (eq_attr "cpu" "power9"))
++  "DU_even_power9,dfu_power9")
++
 Index: gcc/config/rs6000/rs6000-cpus.def
 ===================================================================
 --- a/src/gcc/config/rs6000/rs6000-cpus.def	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/config/rs6000/rs6000-cpus.def	(.../branches/gcc-6-branch)
-@@ -60,13 +60,14 @@
+@@ -60,15 +60,26 @@
  				 | OPTION_MASK_UPPER_REGS_SF)
  
  /* Add ISEL back into ISA 3.0, since it is supposed to be a win.  Do not add
 -   P9_DFORM or P9_MINMAX until they are fully debugged.  */
-+   P9_MINMAX until the hardware that supports it is available.  */
++   P9_MINMAX until the hardware that supports it is available.  Do not add
++   FLOAT128_HW here until we are ready to make -mfloat128 on by default.  */
  #define ISA_3_0_MASKS_SERVER	(ISA_2_7_MASKS_SERVER			\
- 				 | OPTION_MASK_FLOAT128_HW		\
+-				 | OPTION_MASK_FLOAT128_HW		\
  				 | OPTION_MASK_ISEL			\
  				 | OPTION_MASK_MODULO			\
  				 | OPTION_MASK_P9_FUSION		\
 -				 | OPTION_MASK_P9_DFORM			\
 +				 | OPTION_MASK_P9_DFORM_SCALAR		\
 +				 | OPTION_MASK_P9_DFORM_VECTOR		\
++				 | OPTION_MASK_P9_MISC			\
  				 | OPTION_MASK_P9_VECTOR)
  
++/* Support for the IEEE 128-bit floating point hardware requires a lot of the
++   VSX instructions that are part of ISA 3.0.  */
++#define ISA_3_0_MASKS_IEEE	(OPTION_MASK_VSX			\
++				 | OPTION_MASK_P8_VECTOR		\
++				 | OPTION_MASK_P9_VECTOR		\
++				 | OPTION_MASK_DIRECT_MOVE		\
++				 | OPTION_MASK_UPPER_REGS_DF		\
++				 | OPTION_MASK_UPPER_REGS_SF)
++
  #define POWERPC_7400_MASK	(OPTION_MASK_PPC_GFXOPT | OPTION_MASK_ALTIVEC)
-@@ -94,6 +95,7 @@
+ 
+ /* Deal with ports that do not have -mstrict-align.  */
+@@ -94,6 +105,7 @@
  				 | OPTION_MASK_FPRND			\
  				 | OPTION_MASK_HTM			\
  				 | OPTION_MASK_ISEL			\
@@ -810590,7 +823728,7 @@ Index: gcc/config/rs6000/rs6000-cpus.def
  				 | OPTION_MASK_MFCRF			\
  				 | OPTION_MASK_MFPGPR			\
  				 | OPTION_MASK_MODULO			\
-@@ -101,7 +103,8 @@
+@@ -101,9 +113,11 @@
  				 | OPTION_MASK_NO_UPDATE		\
  				 | OPTION_MASK_P8_FUSION		\
  				 | OPTION_MASK_P8_VECTOR		\
@@ -810599,7 +823737,10 @@ Index: gcc/config/rs6000/rs6000-cpus.def
 +				 | OPTION_MASK_P9_DFORM_VECTOR		\
  				 | OPTION_MASK_P9_FUSION		\
  				 | OPTION_MASK_P9_MINMAX		\
++				 | OPTION_MASK_P9_MISC			\
  				 | OPTION_MASK_P9_VECTOR		\
+ 				 | OPTION_MASK_POPCNTB			\
+ 				 | OPTION_MASK_POPCNTD			\
 Index: gcc/config/rs6000/rs6000-protos.h
 ===================================================================
 --- a/src/gcc/config/rs6000/rs6000-protos.h	(.../tags/gcc_6_1_0_release)
@@ -810620,6 +823761,201 @@ Index: gcc/config/rs6000/rs6000-protos.h
  extern bool quad_load_store_p (rtx, rtx);
  extern bool fusion_gpr_load_p (rtx, rtx, rtx, rtx);
  extern void expand_fusion_gpr_load (rtx *);
+@@ -133,6 +135,7 @@
+ 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/40x.md
+===================================================================
+--- a/src/gcc/config/rs6000/40x.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/40x.md	(.../branches/gcc-6-branch)
+@@ -119,6 +119,6 @@
+   "bpu_40x")
+ 
+ (define_insn_reservation "ppc405-float" 11
+-  (and (eq_attr "type" "fpload,fpstore,fpcompare,fp,dmul,sdiv,ddiv")
++  (and (eq_attr "type" "fpload,fpstore,fpcompare,fp,fpsimple,dmul,sdiv,ddiv")
+        (eq_attr "cpu" "ppc405"))
+   "fpu_405*10")
+Index: gcc/config/rs6000/power4.md
+===================================================================
+--- a/src/gcc/config/rs6000/power4.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/power4.md	(.../branches/gcc-6-branch)
+@@ -381,7 +381,7 @@
+ 
+ ; Basic FP latency is 6 cycles
+ (define_insn_reservation "power4-fp" 6
+-  (and (eq_attr "type" "fp,dmul")
++  (and (eq_attr "type" "fp,fpsimple,dmul")
+        (eq_attr "cpu" "power4"))
+   "fpq_power4")
+ 
+@@ -410,7 +410,7 @@
+ 
+ ; VMX
+ (define_insn_reservation "power4-vecsimple" 2
+-  (and (eq_attr "type" "vecsimple")
++  (and (eq_attr "type" "vecsimple,veclogical,vecmove")
+        (eq_attr "cpu" "power4"))
+   "vq_power4")
+ 
+@@ -421,7 +421,7 @@
+ 
+ ; vecfp compare
+ (define_insn_reservation "power4-veccmp" 8
+-  (and (eq_attr "type" "veccmp")
++  (and (eq_attr "type" "veccmp,veccmpfx")
+        (eq_attr "cpu" "power4"))
+   "vq_power4")
+ 
+Index: gcc/config/rs6000/xfpu.md
+===================================================================
+--- a/src/gcc/config/rs6000/xfpu.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/xfpu.md	(.../branches/gcc-6-branch)
+@@ -55,7 +55,7 @@
+ 
+ (define_insn_reservation "fp-default" 2
+   (and (and 
+-        (eq_attr "type" "fp")
++        (eq_attr "type" "fp,fpsimple")
+         (eq_attr "fp_type" "fp_default"))
+        (eq_attr "cpu" "ppc405"))
+   "Xfpu_issue*2")
+@@ -67,7 +67,7 @@
+ 
+ (define_insn_reservation "fp-addsub-s" 14
+   (and (and
+-        (eq_attr "type" "fp")
++        (eq_attr "type" "fp,fpsimple")
+         (eq_attr "fp_type" "fp_addsub_s"))
+        (eq_attr "cpu" "ppc405"))
+   "Xfpu_issue*2,Xfpu_addsub")
+@@ -74,7 +74,7 @@
+ 
+ (define_insn_reservation "fp-addsub-d" 18
+   (and (and
+-        (eq_attr "type" "fp")
++        (eq_attr "type" "fp,fpsimple")
+         (eq_attr "fp_type" "fp_addsub_d"))
+        (eq_attr "cpu" "ppc405"))
+   "Xfpu_issue*2,Xfpu_addsub")
+Index: gcc/config/rs6000/t-rs6000
+===================================================================
+--- a/src/gcc/config/rs6000/t-rs6000	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/t-rs6000	(.../branches/gcc-6-branch)
+@@ -50,6 +50,7 @@
+ 	$(srcdir)/config/rs6000/power6.md \
+ 	$(srcdir)/config/rs6000/power7.md \
+ 	$(srcdir)/config/rs6000/power8.md \
++	$(srcdir)/config/rs6000/power9.md \
+ 	$(srcdir)/config/rs6000/cell.md \
+ 	$(srcdir)/config/rs6000/xfpu.md \
+ 	$(srcdir)/config/rs6000/a2.md \
+Index: gcc/config/rs6000/603.md
+===================================================================
+--- a/src/gcc/config/rs6000/603.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/603.md	(.../branches/gcc-6-branch)
+@@ -105,7 +105,7 @@
+   "(fpu_603+iu_603*2),bpu_603")
+ 
+ (define_insn_reservation "ppc603-fp" 3
+-  (and (eq_attr "type" "fp")
++  (and (eq_attr "type" "fp,fpsimple")
+        (eq_attr "cpu" "ppc603"))
+   "fpu_603")
+ 
+Index: gcc/config/rs6000/mpc.md
+===================================================================
+--- a/src/gcc/config/rs6000/mpc.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/mpc.md	(.../branches/gcc-6-branch)
+@@ -81,7 +81,7 @@
+   "fpu_mpc,bpu_mpc")
+ 
+ (define_insn_reservation "mpccore-fp" 4
+-  (and (eq_attr "type" "fp")
++  (and (eq_attr "type" "fp,fpsimple")
+        (eq_attr "cpu" "mpccore"))
+   "fpu_mpc*2")
+ 
+Index: gcc/config/rs6000/cell.md
+===================================================================
+--- a/src/gcc/config/rs6000/cell.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/cell.md	(.../branches/gcc-6-branch)
+@@ -306,7 +306,7 @@
+ 
+ ; Basic FP latency is 10 cycles, thoughput is 1/cycle
+ (define_insn_reservation "cell-fp" 10
+-  (and (eq_attr "type" "fp,dmul")
++  (and (eq_attr "type" "fp,fpsimple,dmul")
+        (eq_attr "cpu" "cell"))
+   "slot01,vsu1_cell,vsu1_cell*8")
+ 
+@@ -329,7 +329,7 @@
+ 
+ ; VMX
+ (define_insn_reservation "cell-vecsimple" 4
+-  (and (eq_attr "type" "vecsimple")
++  (and (eq_attr "type" "vecsimple,veclogical,vecmove")
+        (eq_attr "cpu" "cell"))
+   "slot01,vsu1_cell,vsu1_cell*2")
+ 
+@@ -341,7 +341,7 @@
+ 
+ ;; TODO: add support for recording instructions
+ (define_insn_reservation "cell-veccmp" 4
+-  (and (eq_attr "type" "veccmp")
++  (and (eq_attr "type" "veccmp,veccmpfx")
+        (eq_attr "cpu" "cell"))
+   "slot01,vsu1_cell,vsu1_cell*2")
+ 
+Index: gcc/config/rs6000/power7.md
+===================================================================
+--- a/src/gcc/config/rs6000/power7.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/power7.md	(.../branches/gcc-6-branch)
+@@ -292,7 +292,7 @@
+ 
+ ; VS Unit (includes FP/VSX/VMX/DFP)
+ (define_insn_reservation "power7-fp" 6
+-  (and (eq_attr "type" "fp,dmul")
++  (and (eq_attr "type" "fp,fpsimple,dmul,dfp")
+        (eq_attr "cpu" "power7"))
+   "DU_power7,VSU_power7")
+ 
+@@ -324,7 +324,7 @@
+   "DU_power7,VSU_power7")
+ 
+ (define_insn_reservation "power7-vecsimple" 2
+-  (and (eq_attr "type" "vecsimple,veccmp")
++  (and (eq_attr "type" "vecsimple,veclogical,vecmove,veccmp,veccmpfx")
+        (eq_attr "cpu" "power7"))
+   "DU_power7,vsu1_power7")
+ 
+Index: gcc/config/rs6000/7xx.md
+===================================================================
+--- a/src/gcc/config/rs6000/7xx.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/7xx.md	(.../branches/gcc-6-branch)
+@@ -113,7 +113,7 @@
+   "ppc750_du,fpu_7xx")
+ 
+ (define_insn_reservation "ppc750-fp" 3
+-  (and (eq_attr "type" "fp")
++  (and (eq_attr "type" "fp,fpsimple")
+        (eq_attr "cpu" "ppc750,ppc7400"))
+   "ppc750_du,fpu_7xx")
+ 
+@@ -165,7 +165,7 @@
+ 
+ ;; Altivec
+ (define_insn_reservation "ppc7400-vecsimple" 1
+-  (and (eq_attr "type" "vecsimple,veccmp")
++  (and (eq_attr "type" "vecsimple,veclogical,vecmove,veccmp,veccmpfx")
+        (eq_attr "cpu" "ppc7400"))
+   "ppc750_du,ppc7400_vec_du,veccmplx_7xx")
+ 
 Index: gcc/config/rs6000/rs6000-builtin.def
 ===================================================================
 --- a/src/gcc/config/rs6000/rs6000-builtin.def	(.../tags/gcc_6_1_0_release)
@@ -810643,17 +823979,25 @@ Index: gcc/config/rs6000/rs6000-builtin.def
  #ifndef RS6000_BUILTIN_1
    #error "RS6000_BUILTIN_1 is not defined."
  #endif
-@@ -637,6 +642,41 @@
+@@ -637,6 +642,91 @@
  		     | RS6000_BTC_TERNARY),				\
  		    CODE_FOR_ ## ICODE)			/* ICODE */
  
 +/* Miscellaneous builtins for instructions added in ISA 3.0.  These
 +   instructions don't require either the DFP or VSX options, just the basic
 +   ISA 3.0 enablement since they operate on general purpose registers.  */
++#define BU_P9_MISC_0(ENUM, NAME, ATTR, ICODE)                      \
++  RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
++		    "__builtin_" NAME,			/* NAME */	\
++		    RS6000_BTM_P9_MISC,			/* MASK */	\
++		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
++		     | RS6000_BTC_SPECIAL),				\
++		    CODE_FOR_ ## ICODE)			/* ICODE */
++
 +#define BU_P9_MISC_1(ENUM, NAME, ATTR, ICODE)				\
 +  RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
 +		    "__builtin_" NAME,			/* NAME */	\
-+		    RS6000_BTM_MODULO,			/* MASK */	\
++		    RS6000_BTM_P9_MISC,			/* MASK */	\
 +		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
 +		     | RS6000_BTC_UNARY),				\
 +		    CODE_FOR_ ## ICODE)			/* ICODE */
@@ -810665,27 +824009,69 @@ Index: gcc/config/rs6000/rs6000-builtin.def
 +#define BU_P9_64BIT_MISC_0(ENUM, NAME, ATTR, ICODE)			\
 +  RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
 +		    "__builtin_" NAME,			/* NAME */	\
-+		    RS6000_BTM_MODULO                                   \
++		    RS6000_BTM_P9_MISC					\
 +                     | RS6000_BTM_64BIT,		/* MASK */	\
 +		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
 +		     | RS6000_BTC_SPECIAL),				\
 +		    CODE_FOR_ ## ICODE)			/* ICODE */
 +
-+/* Miscellaneous builtins for instructions added in ISA 3.0.  These
-+   instructions don't require either the DFP or VSX options, just the basic
-+   ISA 3.0 enablement since they operate on general purpose registers.  */
-+#define BU_P9_MISC_0(ENUM, NAME, ATTR, ICODE)                      \
++/* Miscellaneous builtins for decimal floating point instructions
++   added in ISA 3.0.  These instructions don't require the VSX
++   options, just the basic ISA 3.0 enablement since they operate on
++   general purpose registers.  */
++#define BU_P9_DFP_MISC_0(ENUM, NAME, ATTR, ICODE)			\
 +  RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
 +		    "__builtin_" NAME,			/* NAME */	\
-+		    RS6000_BTM_MODULO,			/* MASK */	\
++		    RS6000_BTM_P9_MISC,			/* MASK */	\
 +		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
 +		     | RS6000_BTC_SPECIAL),				\
 +		    CODE_FOR_ ## ICODE)			/* ICODE */
 +
++#define BU_P9_DFP_MISC_1(ENUM, NAME, ATTR, ICODE)			\
++  RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
++		    "__builtin_" NAME,			/* NAME */	\
++		    RS6000_BTM_P9_MISC,			/* MASK */	\
++		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
++		     | RS6000_BTC_SPECIAL),				\
++		    CODE_FOR_ ## ICODE)			/* ICODE */
++
++#define BU_P9_DFP_MISC_2(ENUM, NAME, ATTR, ICODE)			\
++  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
++		    "__builtin_" NAME,			/* NAME */	\
++		    RS6000_BTM_P9_MISC,			/* MASK */	\
++		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
++		     | RS6000_BTC_SPECIAL),				\
++		    CODE_FOR_ ## ICODE)			/* ICODE */
++
++/* Decimal floating point overloaded functions added in ISA 3.0 */
++#define BU_P9_DFP_OVERLOAD_1(ENUM, NAME)				\
++  RS6000_BUILTIN_1 (P9_BUILTIN_DFP_ ## ENUM,		/* ENUM */	\
++		    "__builtin_dfp_" NAME,		/* NAME */	\
++		    RS6000_BTM_P9_MISC,			/* MASK */	\
++		    (RS6000_BTC_OVERLOADED		/* ATTR */	\
++		     | RS6000_BTC_UNARY),				\
++		    CODE_FOR_nothing)			/* ICODE */
++
++#define BU_P9_DFP_OVERLOAD_2(ENUM, NAME)				\
++  RS6000_BUILTIN_2 (P9_BUILTIN_DFP_ ## ENUM,		/* ENUM */	\
++		    "__builtin_dfp_" NAME,		/* NAME */	\
++		    RS6000_BTM_P9_MISC,			/* MASK */	\
++		    (RS6000_BTC_OVERLOADED		/* ATTR */	\
++		     | RS6000_BTC_BINARY),				\
++		    CODE_FOR_nothing)			/* ICODE */
++
++#define BU_P9_DFP_OVERLOAD_3(ENUM, NAME)				\
++  RS6000_BUILTIN_3 (P9_BUILTIN_DFP_ ## ENUM,		/* ENUM */	\
++		    "__builtin_dfp_" NAME,		/* NAME */	\
++		    RS6000_BTM_P9_MISC,			/* MASK */	\
++		    (RS6000_BTC_OVERLOADED		/* ATTR */	\
++		     | RS6000_BTC_TERNARY),				\
++		    CODE_FOR_nothing)			/* ICODE */
++
  /* 128-bit long double floating point builtins.  */
  #define BU_LDBL128_2(ENUM, NAME, ATTR, ICODE)				\
    RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
-@@ -647,8 +687,129 @@
+@@ -647,8 +737,94 @@
  		     | RS6000_BTC_BINARY),				\
  		    CODE_FOR_ ## ICODE)			/* ICODE */
  
@@ -810706,41 +824092,6 @@ Index: gcc/config/rs6000/rs6000-builtin.def
 +		     | RS6000_BTC_UNARY),                               \
 +		    CODE_FOR_ ## ICODE)                 /* ICODE */
 +
-+/* Miscellaneous builtins for instructions added in ISA 3.0.  These
-+   instructions don't require either the DFP or VSX options, just the basic 
-+   ISA 3.0 enablement since they operate on general purpose registers.  */
-+#define BU_P9_MISC_1(ENUM, NAME, ATTR, ICODE)				\
-+  RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
-+		    "__builtin_" NAME,			/* NAME */	\
-+		    RS6000_BTM_MODULO,			/* MASK */	\
-+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
-+		     | RS6000_BTC_UNARY),				\
-+		    CODE_FOR_ ## ICODE)			/* ICODE */
-+
-+/* Miscellaneous builtins for instructions added in ISA 3.0.  These
-+   instructions don't require either the DFP or VSX options, just the basic 
-+   ISA 3.0 enablement since they operate on general purpose registers,
-+   and they require 64-bit addressing.  */
-+#define BU_P9_64BIT_MISC_0(ENUM, NAME, ATTR, ICODE)			\
-+  RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
-+		    "__builtin_" NAME,			/* NAME */	\
-+		    RS6000_BTM_MODULO                                   \
-+                     | RS6000_BTM_64BIT,		/* MASK */	\
-+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
-+		     | RS6000_BTC_SPECIAL),				\
-+		    CODE_FOR_ ## ICODE)			/* ICODE */
-+
-+/* Miscellaneous builtins for instructions added in ISA 3.0.  These
-+   instructions don't require either the DFP or VSX options, just the basic 
-+   ISA 3.0 enablement since they operate on general purpose registers.  */
-+#define BU_P9_MISC_0(ENUM, NAME, ATTR, ICODE)                      \
-+  RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
-+		    "__builtin_" NAME,			/* NAME */	\
-+		    RS6000_BTM_MODULO,			/* MASK */	\
-+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
-+		     | RS6000_BTC_SPECIAL),				\
-+		    CODE_FOR_ ## ICODE)			/* ICODE */
-+
 +/* ISA 3.0 (power9) vector convenience macros.  */
 +/* For the instructions that are encoded as altivec instructions use
 +   __builtin_altivec_ as the builtin name.  */
@@ -810815,7 +824166,7 @@ Index: gcc/config/rs6000/rs6000-builtin.def
  /* Insure 0 is not a legitimate index.  */
  BU_SPECIAL_X (RS6000_BUILTIN_NONE, NULL, 0, RS6000_BTC_MISC)
  
-@@ -1391,13 +1552,25 @@
+@@ -1391,13 +1567,25 @@
  BU_VSX_X (LXVW4X_V8HI,        "lxvw4x_v8hi",	MEM)
  BU_VSX_X (LXVW4X_V16QI,	      "lxvw4x_v16qi",	MEM)
  BU_VSX_X (STXSDX,	      "stxsdx",		MEM)
@@ -810848,7 +824199,7 @@ Index: gcc/config/rs6000/rs6000-builtin.def
  BU_VSX_X (XSABSDP,	      "xsabsdp",	CONST)
  BU_VSX_X (XSADDDP,	      "xsadddp",	FP)
  BU_VSX_X (XSCMPODP,	      "xscmpodp",	FP)
-@@ -1455,6 +1628,8 @@
+@@ -1455,6 +1643,8 @@
  /* VSX builtins that are handled as special cases.  */
  BU_VSX_OVERLOAD_X (LD,	     "ld")
  BU_VSX_OVERLOAD_X (ST,	     "st")
@@ -810857,7 +824208,7 @@ Index: gcc/config/rs6000/rs6000-builtin.def
  

  /* 1 argument VSX instructions added in ISA 2.07.  */
  BU_P8V_VSX_1 (XSCVSPDPN,      "xscvspdpn",	CONST,	vsx_xscvspdpn)
-@@ -1589,6 +1764,25 @@
+@@ -1589,6 +1779,25 @@
  BU_P8V_OVERLOAD_3 (VSUBECUQ,	"vsubecuq")
  BU_P8V_OVERLOAD_3 (VSUBEUQM,	"vsubeuqm")
  
@@ -810883,7 +824234,7 @@ Index: gcc/config/rs6000/rs6000-builtin.def
  

  /* 2 argument extended divide functions added in ISA 2.06.  */
  BU_P7_MISC_2 (DIVWE,		"divwe",	CONST,	dive_si)
-@@ -1639,6 +1833,11 @@
+@@ -1639,6 +1848,11 @@
  BU_DFP_MISC_2 (PACK_TD,		"pack_dec128",		CONST,	packtd)
  BU_DFP_MISC_2 (UNPACK_TD,	"unpack_dec128",	CONST,	unpacktd)
  
@@ -810895,10 +824246,40 @@ Index: gcc/config/rs6000/rs6000-builtin.def
  BU_LDBL128_2 (PACK_TF,		"pack_longdouble",	CONST,	packtf)
  BU_LDBL128_2 (UNPACK_TF,	"unpack_longdouble",	CONST,	unpacktf)
  
-@@ -1645,6 +1844,31 @@
+@@ -1645,6 +1859,61 @@
  BU_P7_MISC_2 (PACK_V1TI,	"pack_vector_int128",	CONST,	packv1ti)
  BU_P7_MISC_2 (UNPACK_V1TI,	"unpack_vector_int128",	CONST,	unpackv1ti)
  
++/* 2 argument DFP (Decimal Floating Point) functions added in ISA 3.0.  */
++BU_P9_DFP_MISC_2 (TSTSFI_LT_DD, "dtstsfi_lt_dd", CONST, dfptstsfi_lt_dd)
++BU_P9_DFP_MISC_2 (TSTSFI_LT_TD, "dtstsfi_lt_td", CONST, dfptstsfi_lt_td)
++
++BU_P9_DFP_MISC_2 (TSTSFI_EQ_DD, "dtstsfi_eq_dd", CONST, dfptstsfi_eq_dd)
++BU_P9_DFP_MISC_2 (TSTSFI_EQ_TD, "dtstsfi_eq_td", CONST, dfptstsfi_eq_td)
++
++BU_P9_DFP_MISC_2 (TSTSFI_GT_DD, "dtstsfi_gt_dd", CONST, dfptstsfi_gt_dd)
++BU_P9_DFP_MISC_2 (TSTSFI_GT_TD, "dtstsfi_gt_td", CONST, dfptstsfi_gt_td)
++
++BU_P9_DFP_MISC_2 (TSTSFI_OV_DD, "dtstsfi_ov_dd", CONST, dfptstsfi_unordered_dd)
++BU_P9_DFP_MISC_2 (TSTSFI_OV_TD, "dtstsfi_ov_td", CONST, dfptstsfi_unordered_td)
++
++/* 2 argument overloaded DFP functions added in ISA 3.0.  */
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_LT,	"dtstsfi_lt")
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_LT_DD,	"dtstsfi_lt_dd")
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_LT_TD,	"dtstsfi_lt_td")
++
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_EQ,	"dtstsfi_eq")
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_EQ_DD,	"dtstsfi_eq_dd")
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_EQ_TD,	"dtstsfi_eq_td")
++
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_GT,	"dtstsfi_gt")
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_GT_DD,	"dtstsfi_gt_dd")
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_GT_TD,	"dtstsfi_gt_td")
++
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_OV,	"dtstsfi_ov")
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_OV_DD,	"dtstsfi_ov_dd")
++BU_P9_DFP_OVERLOAD_2 (TSTSFI_OV_TD,	"dtstsfi_ov_td")
++
 +/* 1 argument vector functions added in ISA 3.0 (power9).  */
 +BU_P9V_AV_1 (VCTZB,		"vctzb",		CONST,  ctzv16qi2)
 +BU_P9V_AV_1 (VCTZH,		"vctzh",		CONST,  ctzv8hi2)
@@ -810927,7 +824308,7 @@ Index: gcc/config/rs6000/rs6000-builtin.def
  

  /* 1 argument crypto functions.  */
  BU_CRYPTO_1 (VSBOX,		"vsbox",	  CONST, crypto_vsbox)
-@@ -2022,6 +2246,18 @@
+@@ -2022,6 +2291,18 @@
  BU_SPECIAL_X (RS6000_BUILTIN_CPU_SUPPORTS, "__builtin_cpu_supports",
  	      RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
  
@@ -811056,10 +824437,50 @@ Index: gcc/config/rs6000/rs6000-c.c
    { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
      RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE },
    { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
-@@ -4123,6 +4215,65 @@
+@@ -4123,6 +4215,105 @@
    { P8V_BUILTIN_VEC_VCLZD, P8V_BUILTIN_VCLZD,
      RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 },
  
++  { P9_BUILTIN_DFP_TSTSFI_LT, MISC_BUILTIN_TSTSFI_LT_TD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 },
++  { P9_BUILTIN_DFP_TSTSFI_LT, MISC_BUILTIN_TSTSFI_LT_DD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 },
++
++  { P9_BUILTIN_DFP_TSTSFI_LT_TD, MISC_BUILTIN_TSTSFI_LT_TD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 },
++  { P9_BUILTIN_DFP_TSTSFI_LT_DD, MISC_BUILTIN_TSTSFI_LT_DD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 },
++
++  { P9_BUILTIN_DFP_TSTSFI_EQ, MISC_BUILTIN_TSTSFI_EQ_TD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 },
++  { P9_BUILTIN_DFP_TSTSFI_EQ, MISC_BUILTIN_TSTSFI_EQ_DD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 },
++
++  { P9_BUILTIN_DFP_TSTSFI_EQ_TD, MISC_BUILTIN_TSTSFI_EQ_TD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 },
++  { P9_BUILTIN_DFP_TSTSFI_EQ_DD, MISC_BUILTIN_TSTSFI_EQ_DD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 },
++
++  { P9_BUILTIN_DFP_TSTSFI_GT, MISC_BUILTIN_TSTSFI_GT_TD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 },
++  { P9_BUILTIN_DFP_TSTSFI_GT, MISC_BUILTIN_TSTSFI_GT_DD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 },
++
++  { P9_BUILTIN_DFP_TSTSFI_GT_TD, MISC_BUILTIN_TSTSFI_GT_TD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 },
++  { P9_BUILTIN_DFP_TSTSFI_GT_DD, MISC_BUILTIN_TSTSFI_GT_DD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 },
++
++  { P9_BUILTIN_DFP_TSTSFI_OV, MISC_BUILTIN_TSTSFI_OV_TD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 },
++  { P9_BUILTIN_DFP_TSTSFI_OV, MISC_BUILTIN_TSTSFI_OV_DD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 },
++
++  { P9_BUILTIN_DFP_TSTSFI_OV_TD, MISC_BUILTIN_TSTSFI_OV_TD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 },
++  { P9_BUILTIN_DFP_TSTSFI_OV_DD, MISC_BUILTIN_TSTSFI_OV_DD,
++    RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 },
++
 +  { P9V_BUILTIN_VEC_VCTZ, P9V_BUILTIN_VCTZB,
 +    RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
 +  { P9V_BUILTIN_VEC_VCTZ, P9V_BUILTIN_VCTZB,
@@ -811122,7 +824543,7 @@ Index: gcc/config/rs6000/rs6000-c.c
    { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD,
      RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
    { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD,
-@@ -4252,6 +4403,42 @@
+@@ -4252,6 +4443,42 @@
    { P8V_BUILTIN_VEC_VPOPCNTD, P8V_BUILTIN_VPOPCNTD,
      RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 },
  
@@ -811165,7 +824586,7 @@ Index: gcc/config/rs6000/rs6000-c.c
    { P8V_BUILTIN_VEC_VPKUDUM, P8V_BUILTIN_VPKUDUM,
      RS6000_BTI_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
    { P8V_BUILTIN_VEC_VPKUDUM, P8V_BUILTIN_VPKUDUM,
-@@ -4328,6 +4515,13 @@
+@@ -4328,6 +4555,13 @@
    { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD,
      RS6000_BTI_unsigned_V16QI, 0, 0, 0 },
  
@@ -811194,9 +824615,18 @@ Index: gcc/config/rs6000/rs6000.opt
  
  msched-costly-dep=
  Target RejectNegative Joined Var(rs6000_sched_costly_dep_str)
-@@ -609,9 +609,17 @@
+@@ -605,13 +605,25 @@
+ Target Report Mask(P9_FUSION) Var(rs6000_isa_flags)
+ Fuse certain operations together for better performance on power9.
+ 
++mpower9-misc
++Target Undocumented Report Mask(P9_MISC) Var(rs6000_isa_flags)
++Use/do not use certain scalar instructions added in ISA 3.0.
++
+ mpower9-vector
  Target Report Mask(P9_VECTOR) Var(rs6000_isa_flags)
- Use/do not use vector and scalar instructions added in ISA 3.0.
+-Use/do not use vector and scalar instructions added in ISA 3.0.
++Use/do not use vector instructions added in ISA 3.0.
  
 +mpower9-dform-scalar
 +Target Undocumented Mask(P9_DFORM_SCALAR) Var(rs6000_isa_flags)
@@ -811243,6 +824673,29 @@ Index: gcc/config/rs6000/rs6000.c
  

  /* Target cpu costs.  */
  
+@@ -1093,16 +1104,16 @@
+   COSTS_N_INSNS (3),	/* mulsi_const */
+   COSTS_N_INSNS (3),	/* mulsi_const9 */
+   COSTS_N_INSNS (3),	/* muldi */
+-  COSTS_N_INSNS (19),	/* divsi */
+-  COSTS_N_INSNS (35),	/* divdi */
++  COSTS_N_INSNS (8),	/* divsi */
++  COSTS_N_INSNS (12),	/* divdi */
+   COSTS_N_INSNS (3),	/* fp */
+   COSTS_N_INSNS (3),	/* dmul */
+-  COSTS_N_INSNS (14),	/* sdiv */
+-  COSTS_N_INSNS (17),	/* ddiv */
++  COSTS_N_INSNS (13),	/* sdiv */
++  COSTS_N_INSNS (18),	/* ddiv */
+   128,			/* cache line size */
+   32,			/* l1 cache */
+-  256,			/* l2 cache */
+-  12,			/* prefetch streams */
++  512,			/* l2 cache */
++  8,			/* prefetch streams */
+   COSTS_N_INSNS (3),	/* SF->DF convert */
+ };
+ 
 @@ -1128,6 +1139,7 @@
  
  

@@ -811413,11 +824866,12 @@ Index: gcc/config/rs6000/rs6000.c
      rs6000_constraints[RS6000_CONSTRAINT_wb] = ALTIVEC_REGS;
  
    /* Support for ISA 3.0 (power9) vectors.  */
-@@ -3621,11 +3668,15 @@
+@@ -3621,11 +3668,16 @@
  	  | ((TARGET_POPCNTD)		    ? RS6000_BTM_POPCNTD   : 0)
  	  | ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL      : 0)
  	  | ((TARGET_P8_VECTOR)		    ? RS6000_BTM_P8_VECTOR : 0)
 +	  | ((TARGET_P9_VECTOR)		    ? RS6000_BTM_P9_VECTOR : 0)
++	  | ((TARGET_P9_MISC)		    ? RS6000_BTM_P9_MISC   : 0)
 +	  | ((TARGET_MODULO)		    ? RS6000_BTM_MODULO    : 0)
 +	  | ((TARGET_64BIT)		    ? RS6000_BTM_64BIT     : 0)
  	  | ((TARGET_CRYPTO)		    ? RS6000_BTM_CRYPTO	   : 0)
@@ -811430,7 +824884,31 @@ Index: gcc/config/rs6000/rs6000.c
  }
  
  /* Implement TARGET_MD_ASM_ADJUST.  All asm statements are considered
-@@ -3974,7 +4025,8 @@
+@@ -3784,22 +3836,7 @@
+   if (rs6000_tune_index >= 0)
+     tune_index = rs6000_tune_index;
+   else if (have_cpu)
+-    {
+-      /* Until power9 tuning is available, use power8 tuning if -mcpu=power9.  */
+-      if (processor_target_table[cpu_index].processor != PROCESSOR_POWER9)
+-	rs6000_tune_index = tune_index = cpu_index;
+-      else
+-	{
+-	  size_t i;
+-	  tune_index = -1;
+-	  for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
+-	    if (processor_target_table[i].processor == PROCESSOR_POWER8)
+-	      {
+-		rs6000_tune_index = tune_index = i;
+-		break;
+-	      }
+-	}
+-    }
++    rs6000_tune_index = tune_index = cpu_index;
+   else
+     {
+       size_t i;
+@@ -3974,7 +4011,8 @@
  
    /* For the newer switches (vsx, dfp, etc.) set some of the older options,
       unless the user explicitly used the -mno-<option> to disable the code.  */
@@ -811440,10 +824918,18 @@ Index: gcc/config/rs6000/rs6000.c
      rs6000_isa_flags |= (ISA_3_0_MASKS_SERVER & ~rs6000_isa_flags_explicit);
    else if (TARGET_P8_VECTOR || TARGET_DIRECT_MOVE || TARGET_CRYPTO)
      rs6000_isa_flags |= (ISA_2_7_MASKS_SERVER & ~rs6000_isa_flags_explicit);
-@@ -4188,26 +4240,46 @@
+@@ -4188,36 +4226,82 @@
        && !(rs6000_isa_flags_explicit & OPTION_MASK_TOC_FUSION))
      rs6000_isa_flags |= OPTION_MASK_TOC_FUSION;
  
++  /* ISA 3.0 vector instructions include ISA 2.07.  */
++  if (TARGET_P9_VECTOR && !TARGET_P8_VECTOR)
++    {
++      if (rs6000_isa_flags_explicit & OPTION_MASK_P8_VECTOR)
++	error ("-mpower9-vector requires -mpower8-vector");
++      rs6000_isa_flags &= ~OPTION_MASK_P9_VECTOR;
++    }
++
 +  /* -mpower9-dform turns on both -mpower9-dform-scalar and
 +      -mpower9-dform-vector.  */
 +  if (TARGET_P9_DFORM_BOTH > 0)
@@ -811492,11 +824978,8 @@ Index: gcc/config/rs6000/rs6000.c
 +      rs6000_isa_flags &= ~OPTION_MASK_P9_DFORM_SCALAR;
      }
  
-   /* ISA 3.0 vector instructions include ISA 2.07.  */
-@@ -4218,6 +4290,32 @@
-       rs6000_isa_flags &= ~OPTION_MASK_P9_VECTOR;
-     }
- 
+-  /* ISA 3.0 vector instructions include ISA 2.07.  */
+-  if (TARGET_P9_VECTOR && !TARGET_P8_VECTOR)
 +  /* There have been bugs with -mvsx-timode that don't show up with -mlra,
 +     but do show up with -mno-lra.  Given -mlra will become the default once
 +     PR 69847 is fixed, turn off the options with problems by default if
@@ -811505,7 +824988,10 @@ Index: gcc/config/rs6000/rs6000.c
 +     Enable -mpower9-dform-vector by default if LRA and other power9 options.
 +     Enable -mvsx-timode by default if LRA and VSX.  */
 +  if (!TARGET_LRA)
-+    {
+     {
+-      if (rs6000_isa_flags_explicit & OPTION_MASK_P8_VECTOR)
+-	error ("-mpower9-vector requires -mpower8-vector");
+-      rs6000_isa_flags &= ~OPTION_MASK_P9_VECTOR;
 +      if (TARGET_VSX_TIMODE)
 +	{
 +	  if ((rs6000_isa_flags_explicit & OPTION_MASK_VSX_TIMODE) != 0)
@@ -811514,8 +825000,8 @@ Index: gcc/config/rs6000/rs6000.c
 +	  else
 +	    rs6000_isa_flags &= ~OPTION_MASK_VSX_TIMODE;
 +	}
-+    }
-+
+     }
+ 
 +  else
 +    {
 +      if (TARGET_VSX && !TARGET_VSX_TIMODE
@@ -811526,7 +825012,54 @@ Index: gcc/config/rs6000/rs6000.c
    /* Set -mallow-movmisalign to explicitly on if we have full ISA 2.07
       support. If we only have ISA 2.06 support, and the user did not specify
       the switch, leave it set to -1 so the movmisalign patterns are enabled,
-@@ -6134,6 +6232,128 @@
+@@ -4267,13 +4351,21 @@
+       rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128 | OPTION_MASK_FLOAT128_HW);
+     }
+ 
++  /* If we have -mfloat128 and full ISA 3.0 support, enable -mfloat128-hardware
++     by default.  */
++  if (TARGET_FLOAT128 && !TARGET_FLOAT128_HW
++      && (rs6000_isa_flags & ISA_3_0_MASKS_IEEE) == ISA_3_0_MASKS_IEEE
++      && !(rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW))
++    {
++      rs6000_isa_flags |= OPTION_MASK_FLOAT128_HW;
++      if ((rs6000_isa_flags & OPTION_MASK_FLOAT128) != 0)
++	rs6000_isa_flags_explicit |= OPTION_MASK_FLOAT128_HW;
++    }
++
+   /* IEEE 128-bit floating point hardware instructions imply enabling
+      __float128.  */
+   if (TARGET_FLOAT128_HW
+-      && (rs6000_isa_flags & (OPTION_MASK_P9_VECTOR
+-			      | OPTION_MASK_DIRECT_MOVE
+-			      | OPTION_MASK_UPPER_REGS_DF
+-			      | OPTION_MASK_UPPER_REGS_SF)) == 0)
++      && (rs6000_isa_flags & ISA_3_0_MASKS_IEEE) != ISA_3_0_MASKS_IEEE)
+     {
+       if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW) != 0)
+ 	error ("-mfloat128-hardware requires full ISA 3.0 support");
+@@ -4281,10 +4373,6 @@
+       rs6000_isa_flags &= ~OPTION_MASK_FLOAT128_HW;
+     }
+ 
+-  else if (TARGET_P9_VECTOR && !TARGET_FLOAT128_HW
+-	   && (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW) == 0)
+-    rs6000_isa_flags |= OPTION_MASK_FLOAT128_HW;
+-
+   if (TARGET_FLOAT128_HW
+       && (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128) == 0)
+     rs6000_isa_flags |= OPTION_MASK_FLOAT128;
+@@ -4494,8 +4582,7 @@
+   rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
+ 			 || rs6000_cpu == PROCESSOR_POWER5
+ 			 || rs6000_cpu == PROCESSOR_POWER7
+-			 || rs6000_cpu == PROCESSOR_POWER8
+-			 || rs6000_cpu == PROCESSOR_POWER9);
++			 || rs6000_cpu == PROCESSOR_POWER8);
+   rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
+ 				 || rs6000_cpu == PROCESSOR_POWER5
+ 				 || rs6000_cpu == PROCESSOR_POWER6
+@@ -6134,6 +6221,128 @@
    gcc_unreachable ();
  }
  
@@ -811655,7 +825188,7 @@ Index: gcc/config/rs6000/rs6000.c
  const char *
  output_vec_const_move (rtx *operands)
  {
-@@ -6147,24 +6367,61 @@
+@@ -6147,24 +6356,61 @@
  
    if (TARGET_VSX)
      {
@@ -811725,7 +825258,7 @@ Index: gcc/config/rs6000/rs6000.c
        /* Do we need to construct a value using VSLDOI?  */
        shift = vspltis_shifted (vec);
        if (shift != 0)
-@@ -6436,6 +6693,15 @@
+@@ -6436,6 +6682,15 @@
        return;
      }
  
@@ -811741,7 +825274,7 @@ Index: gcc/config/rs6000/rs6000.c
    /* With single precision floating point on VSX, know that internally single
       precision is actually represented as a double, and either make 2 V2DF
       vectors, and convert these vectors to single precision, or do one
-@@ -6444,14 +6710,23 @@
+@@ -6444,14 +6699,23 @@
      {
        if (all_same)
  	{
@@ -811772,7 +825305,7 @@ Index: gcc/config/rs6000/rs6000.c
  	}
        else
  	{
-@@ -6572,21 +6847,29 @@
+@@ -6572,21 +6836,29 @@
  			gen_rtvec (3, target, reg,
  				   force_reg (V16QImode, x)),
  			UNSPEC_VPERM);
@@ -811815,7 +825348,7 @@ Index: gcc/config/rs6000/rs6000.c
      }
  
    emit_insn (gen_rtx_SET (target, x));
-@@ -6902,6 +7185,49 @@
+@@ -6902,6 +7174,49 @@
    return false;
  }
  
@@ -811865,7 +825398,7 @@ Index: gcc/config/rs6000/rs6000.c
  /* Return true if this is a load or store quad operation.  This function does
     not handle the atomic quad memory instructions.  */
  
-@@ -6994,6 +7320,10 @@
+@@ -6994,6 +7309,10 @@
    if (TARGET_POWERPC64 && (offset & 3) != 0)
      return false;
  
@@ -811876,7 +825409,7 @@ Index: gcc/config/rs6000/rs6000.c
    extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD;
    if (extra < 0)
      extra = 0;
-@@ -7023,13 +7353,14 @@
+@@ -7023,13 +7342,14 @@
      case TImode:
      case TFmode:
      case KFmode:
@@ -811897,7 +825430,7 @@ Index: gcc/config/rs6000/rs6000.c
        break;
  
      case V4HImode:
-@@ -7096,6 +7427,11 @@
+@@ -7096,6 +7416,11 @@
    if (GET_CODE (op) != SYMBOL_REF)
      return false;
  
@@ -811909,7 +825442,7 @@ Index: gcc/config/rs6000/rs6000.c
    dsize = GET_MODE_SIZE (mode);
    decl = SYMBOL_REF_DECL (op);
    if (!decl)
-@@ -7250,6 +7586,8 @@
+@@ -7250,6 +7575,8 @@
      return false;
    if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
      return false;
@@ -811918,7 +825451,7 @@ Index: gcc/config/rs6000/rs6000.c
    if (!reg_offset_addressing_ok_p (mode))
      return virtual_stack_registers_memory_p (x);
    if (legitimate_constant_pool_address_p (x, mode, strict || lra_in_progress))
-@@ -7388,6 +7726,9 @@
+@@ -7388,6 +7715,9 @@
      return false;
    if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
      return false;
@@ -811928,7 +825461,7 @@ Index: gcc/config/rs6000/rs6000.c
    /* Restrict addressing for DI because of our SUBREG hackery.  */
    if (TARGET_E500_DOUBLE && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
      return false;
-@@ -7399,7 +7740,7 @@
+@@ -7399,7 +7729,7 @@
  
        if (DEFAULT_ABI == ABI_V4 && flag_pic)
  	return false;
@@ -811937,7 +825470,7 @@ Index: gcc/config/rs6000/rs6000.c
  	 push_reload from reload pass code.  LEGITIMIZE_RELOAD_ADDRESS
  	 recognizes some LO_SUM addresses as valid although this
  	 function says opposite.  In most cases, LRA through different
-@@ -7453,7 +7794,8 @@
+@@ -7453,7 +7783,8 @@
  {
    unsigned int extra;
  
@@ -811947,7 +825480,7 @@ Index: gcc/config/rs6000/rs6000.c
      {
        if (virtual_stack_registers_memory_p (x))
  	return x;
-@@ -8148,13 +8490,18 @@
+@@ -8148,13 +8479,18 @@
  				  int ind_levels ATTRIBUTE_UNUSED, int *win)
  {
    bool reg_offset_p = reg_offset_addressing_ok_p (mode);
@@ -811969,7 +825502,7 @@ Index: gcc/config/rs6000/rs6000.c
      reg_offset_p = false;
  
    /* We must recognize output that we have already generated ourselves.  */
-@@ -8164,6 +8511,11 @@
+@@ -8164,6 +8500,11 @@
        && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
        && GET_CODE (XEXP (x, 1)) == CONST_INT)
      {
@@ -811981,7 +825514,7 @@ Index: gcc/config/rs6000/rs6000.c
        push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
  		   BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
  		   opnum, (enum reload_type) type);
-@@ -8175,6 +8527,11 @@
+@@ -8175,6 +8516,11 @@
    if (GET_CODE (x) == LO_SUM
        && GET_CODE (XEXP (x, 0)) == HIGH)
      {
@@ -811993,7 +825526,7 @@ Index: gcc/config/rs6000/rs6000.c
        push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
  		   BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
  		   opnum, (enum reload_type) type);
-@@ -8203,10 +8560,16 @@
+@@ -8203,10 +8549,16 @@
  
    if (TARGET_CMODEL != CMODEL_SMALL
        && reg_offset_p
@@ -812010,7 +825543,7 @@ Index: gcc/config/rs6000/rs6000.c
        push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
  		   BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
  		   opnum, (enum reload_type) type);
-@@ -8215,14 +8578,14 @@
+@@ -8215,14 +8567,14 @@
      }
  
    if (GET_CODE (x) == PLUS
@@ -812028,7 +825561,7 @@ Index: gcc/config/rs6000/rs6000.c
      {
        HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
        HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
-@@ -8229,8 +8592,10 @@
+@@ -8229,8 +8581,10 @@
        HOST_WIDE_INT high
  	= (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
  
@@ -812041,7 +825574,7 @@ Index: gcc/config/rs6000/rs6000.c
  	{
  	  *win = 0;
  	  return x;
-@@ -8244,6 +8609,11 @@
+@@ -8244,6 +8598,11 @@
  				      GEN_INT (high)),
  			GEN_INT (low));
  
@@ -812053,7 +825586,7 @@ Index: gcc/config/rs6000/rs6000.c
        push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
  		   BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
  		   opnum, (enum reload_type) type);
-@@ -8253,6 +8623,7 @@
+@@ -8253,6 +8612,7 @@
  
    if (GET_CODE (x) == SYMBOL_REF
        && reg_offset_p
@@ -812061,7 +825594,7 @@ Index: gcc/config/rs6000/rs6000.c
        && (!VECTOR_MODE_P (mode) || VECTOR_MEM_NONE_P (mode))
        && !SPE_VECTOR_MODE (mode)
  #if TARGET_MACHO
-@@ -8304,6 +8675,11 @@
+@@ -8304,6 +8664,11 @@
  	x = gen_rtx_LO_SUM (GET_MODE (x),
  	      gen_rtx_HIGH (Pmode, x), x);
  
@@ -812073,7 +825606,7 @@ Index: gcc/config/rs6000/rs6000.c
        push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
  		   BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
  		   opnum, (enum reload_type) type);
-@@ -8332,14 +8708,22 @@
+@@ -8332,14 +8697,22 @@
  
    if (TARGET_TOC
        && reg_offset_p
@@ -812099,7 +825632,7 @@ Index: gcc/config/rs6000/rs6000.c
        *win = 1;
        return x;
      }
-@@ -8395,6 +8779,7 @@
+@@ -8395,6 +8768,7 @@
  rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
  {
    bool reg_offset_p = reg_offset_addressing_ok_p (mode);
@@ -812107,7 +825640,7 @@ Index: gcc/config/rs6000/rs6000.c
  
    /* If this is an unaligned stvx/ldvx type address, discard the outer AND.  */
    if (VECTOR_MEM_ALTIVEC_P (mode)
-@@ -8412,17 +8797,27 @@
+@@ -8412,17 +8786,27 @@
        && mode_supports_pre_incdec_p (mode)
        && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
      return 1;
@@ -812144,7 +825677,7 @@ Index: gcc/config/rs6000/rs6000.c
    /* For TImode, if we have load/store quad and TImode in VSX registers, only
       allow register indirect addresses.  This will allow the values to go in
       either GPRs or VSX registers without reloading.  The vector types would
-@@ -8461,7 +8856,8 @@
+@@ -8461,7 +8845,8 @@
  	      && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
        && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
      return 1;
@@ -812154,7 +825687,7 @@ Index: gcc/config/rs6000/rs6000.c
      return 1;
    return 0;
  }
-@@ -10044,6 +10440,35 @@
+@@ -10044,6 +10429,35 @@
      return must_pass_in_stack_var_size_or_pad (mode, type);
  }
  
@@ -812190,7 +825723,7 @@ Index: gcc/config/rs6000/rs6000.c
  /* If defined, a C expression which determines whether, and in which
     direction, to pad out an argument with extra space.  The value
     should be of type `enum direction': either `upward' to pad above
-@@ -10128,6 +10553,7 @@
+@@ -10128,6 +10542,7 @@
        && (GET_MODE_SIZE (mode) == 8
  	  || (TARGET_HARD_FLOAT
  	      && TARGET_FPRS
@@ -812198,7 +825731,7 @@ Index: gcc/config/rs6000/rs6000.c
  	      && FLOAT128_2REG_P (mode))))
      return 64;
    else if (FLOAT128_VECTOR_P (mode))
-@@ -10507,11 +10933,7 @@
+@@ -10507,11 +10922,7 @@
      }
    else if (DEFAULT_ABI == ABI_V4)
      {
@@ -812211,7 +825744,7 @@ Index: gcc/config/rs6000/rs6000.c
  	{
  	  /* _Decimal128 must use an even/odd register pair.  This assumes
  	     that the register number is odd when fregno is odd.  */
-@@ -11168,11 +11590,7 @@
+@@ -11168,11 +11579,7 @@
  
    else if (abi == ABI_V4)
      {
@@ -812224,7 +825757,7 @@ Index: gcc/config/rs6000/rs6000.c
  	{
  	  /* _Decimal128 must use an even/odd register pair.  This assumes
  	     that the register number is odd when fregno is odd.  */
-@@ -12093,12 +12511,8 @@
+@@ -12093,12 +12500,8 @@
    rsize = (size + 3) / 4;
    align = 1;
  
@@ -812239,7 +825772,7 @@ Index: gcc/config/rs6000/rs6000.c
      {
        /* FP args go in FP registers, if present.  */
        reg = fpr;
-@@ -12105,7 +12519,7 @@
+@@ -12105,7 +12508,7 @@
        n_reg = (size + 7) / 8;
        sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
        sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
@@ -812248,7 +825781,7 @@ Index: gcc/config/rs6000/rs6000.c
  	align = 8;
      }
    else
-@@ -12125,7 +12539,7 @@
+@@ -12125,7 +12528,7 @@
    addr = create_tmp_var (ptr_type_node, "addr");
  
    /*  AltiVec vectors never go in registers when -mabi=altivec.  */
@@ -812257,7 +825790,7 @@ Index: gcc/config/rs6000/rs6000.c
      align = 16;
    else
      {
-@@ -12146,7 +12560,7 @@
+@@ -12146,7 +12549,7 @@
  	}
        /* _Decimal128 is passed in even/odd fpr pairs; the stored
  	 reg number is 0 for f1, so we want to make it odd.  */
@@ -812266,7 +825799,7 @@ Index: gcc/config/rs6000/rs6000.c
  	{
  	  t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
  		      build_int_cst (TREE_TYPE (reg), 1));
-@@ -12173,7 +12587,7 @@
+@@ -12173,7 +12576,7 @@
  	 FP register for 32-bit binaries.  */
        if (TARGET_32BIT
  	  && TARGET_HARD_FLOAT && TARGET_FPRS
@@ -812275,7 +825808,7 @@ Index: gcc/config/rs6000/rs6000.c
  	t = fold_build_pointer_plus_hwi (t, size);
  
        gimplify_assign (addr, t, pre_p);
-@@ -12260,7 +12674,7 @@
+@@ -12260,7 +12663,7 @@
        /* const function, function only depends on the inputs.  */
        TREE_READONLY (t) = 1;
        TREE_NOTHROW (t) = 1;
@@ -812284,7 +825817,7 @@ Index: gcc/config/rs6000/rs6000.c
      }
    else if ((classify & RS6000_BTC_PURE) != 0)
      {
-@@ -12268,7 +12682,7 @@
+@@ -12268,7 +12671,7 @@
  	 external state.  */
        DECL_PURE_P (t) = 1;
        TREE_NOTHROW (t) = 1;
@@ -812293,7 +825826,7 @@ Index: gcc/config/rs6000/rs6000.c
      }
    else if ((classify & RS6000_BTC_FP) != 0)
      {
-@@ -12300,6 +12714,7 @@
+@@ -12300,6 +12703,7 @@
  
  /* Simple ternary operations: VECd = foo (VECa, VECb, VECc).  */
  
@@ -812301,7 +825834,7 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -12312,6 +12727,7 @@
+@@ -12312,6 +12716,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -812309,7 +825842,7 @@ Index: gcc/config/rs6000/rs6000.c
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
-@@ -12333,6 +12749,7 @@
+@@ -12333,6 +12738,7 @@
  
  /* DST operations: void foo (void *, const int, const char).  */
  
@@ -812317,7 +825850,7 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -12345,6 +12762,7 @@
+@@ -12345,6 +12751,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -812325,7 +825858,7 @@ Index: gcc/config/rs6000/rs6000.c
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-@@ -12366,6 +12784,7 @@
+@@ -12366,6 +12773,7 @@
  
  /* Simple binary operations: VECc = foo (VECa, VECb).  */
  
@@ -812333,7 +825866,7 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -12378,6 +12797,7 @@
+@@ -12378,6 +12786,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -812341,7 +825874,7 @@ Index: gcc/config/rs6000/rs6000.c
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \
    { MASK, ICODE, NAME, ENUM },
-@@ -12397,6 +12817,7 @@
+@@ -12397,6 +12806,7 @@
  #include "rs6000-builtin.def"
  };
  
@@ -812349,7 +825882,7 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -12409,6 +12830,7 @@
+@@ -12409,6 +12819,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -812357,7 +825890,7 @@ Index: gcc/config/rs6000/rs6000.c
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-@@ -12431,6 +12853,7 @@
+@@ -12431,6 +12842,7 @@
  };
  
  /* SPE predicates.  */
@@ -812365,7 +825898,7 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -12443,6 +12866,7 @@
+@@ -12443,6 +12855,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -812373,7 +825906,7 @@ Index: gcc/config/rs6000/rs6000.c
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-@@ -12463,6 +12887,7 @@
+@@ -12463,6 +12876,7 @@
  };
  
  /* SPE evsel predicates.  */
@@ -812381,7 +825914,7 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -12475,6 +12900,7 @@
+@@ -12475,6 +12889,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -812389,7 +825922,7 @@ Index: gcc/config/rs6000/rs6000.c
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-@@ -12495,6 +12921,7 @@
+@@ -12495,6 +12910,7 @@
  };
  
  /* PAIRED predicates.  */
@@ -812397,7 +825930,7 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -12507,6 +12934,7 @@
+@@ -12507,6 +12923,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -812405,7 +825938,7 @@ Index: gcc/config/rs6000/rs6000.c
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-@@ -12528,6 +12956,7 @@
+@@ -12528,6 +12945,7 @@
  
  /* ABS* operations.  */
  
@@ -812413,7 +825946,7 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -12540,6 +12969,7 @@
+@@ -12540,6 +12958,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -812421,7 +825954,7 @@ Index: gcc/config/rs6000/rs6000.c
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-@@ -12562,6 +12992,7 @@
+@@ -12562,6 +12981,7 @@
  /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
     foo (VECa).  */
  
@@ -812429,7 +825962,7 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -12574,6 +13005,7 @@
+@@ -12574,6 +12994,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -812437,7 +825970,7 @@ Index: gcc/config/rs6000/rs6000.c
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
    { MASK, ICODE, NAME, ENUM },
  
-@@ -12593,7 +13025,43 @@
+@@ -12593,7 +13014,43 @@
  #include "rs6000-builtin.def"
  };
  
@@ -812481,7 +826014,7 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -12606,6 +13074,7 @@
+@@ -12606,6 +13063,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -812489,7 +826022,7 @@ Index: gcc/config/rs6000/rs6000.c
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
  #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-@@ -12625,6 +13094,7 @@
+@@ -12625,6 +13083,7 @@
  #include "rs6000-builtin.def"
  };
  
@@ -812497,7 +826030,32 @@ Index: gcc/config/rs6000/rs6000.c
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -14129,6 +14599,47 @@
+@@ -12845,6 +13304,24 @@
+ 	  return const0_rtx;
+ 	}
+     }
++  else if (icode == CODE_FOR_dfptstsfi_eq_dd
++      || icode == CODE_FOR_dfptstsfi_lt_dd
++      || icode == CODE_FOR_dfptstsfi_gt_dd
++      || icode == CODE_FOR_dfptstsfi_unordered_dd
++      || icode == CODE_FOR_dfptstsfi_eq_td
++      || icode == CODE_FOR_dfptstsfi_lt_td
++      || icode == CODE_FOR_dfptstsfi_gt_td
++      || icode == CODE_FOR_dfptstsfi_unordered_td)
++    {
++      /* Only allow 6-bit unsigned literals.  */
++      STRIP_NOPS (arg0);
++      if (TREE_CODE (arg0) != INTEGER_CST
++	  || !IN_RANGE (TREE_INT_CST_LOW (arg0), 0, 63))
++	{
++	  error ("argument 1 must be a 6-bit unsigned literal");
++	  return CONST0_RTX (tmode);
++	}
++    }
+ 
+   if (target == 0
+       || GET_MODE (target) != tmode
+@@ -14129,6 +14606,47 @@
      case VSX_BUILTIN_STXVW4X_V16QI:
        return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
  
@@ -812545,7 +826103,7 @@ Index: gcc/config/rs6000/rs6000.c
      case ALTIVEC_BUILTIN_MFVSCR:
        icode = CODE_FOR_altivec_mfvscr;
        tmode = insn_data[icode].operand[0].mode;
-@@ -14323,6 +14834,46 @@
+@@ -14323,6 +14841,46 @@
      case VSX_BUILTIN_LXVW4X_V16QI:
        return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
  					exp, target, false);
@@ -812592,16 +826150,22 @@ Index: gcc/config/rs6000/rs6000.c
        break;
      default:
        break;
-@@ -14792,6 +15343,8 @@
+@@ -14792,6 +15350,14 @@
      error ("Builtin function %s requires the -mhard-dfp option", name);
    else if ((fnmask & RS6000_BTM_P8_VECTOR) != 0)
      error ("Builtin function %s requires the -mpower8-vector option", name);
 +  else if ((fnmask & RS6000_BTM_P9_VECTOR) != 0)
 +    error ("Builtin function %s requires the -mpower9-vector option", name);
++  else if ((fnmask & (RS6000_BTM_P9_MISC | RS6000_BTM_64BIT))
++	   == (RS6000_BTM_P9_MISC | RS6000_BTM_64BIT))
++    error ("Builtin function %s requires the -mpower9-misc and"
++	   " -m64 options", name);
++  else if ((fnmask & RS6000_BTM_P9_MISC) == RS6000_BTM_P9_MISC)
++    error ("Builtin function %s requires the -mpower9-misc option", name);
    else if ((fnmask & (RS6000_BTM_HARD_FLOAT | RS6000_BTM_LDBL128))
  	   == (RS6000_BTM_HARD_FLOAT | RS6000_BTM_LDBL128))
      error ("Builtin function %s requires the -mhard-float and"
-@@ -14798,11 +15351,57 @@
+@@ -14798,11 +15364,57 @@
  	   " -mlong-double-128 options", name);
    else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
      error ("Builtin function %s requires the -mhard-float option", name);
@@ -812659,7 +826223,7 @@ Index: gcc/config/rs6000/rs6000.c
  /* Expand an expression EXP that calls a built-in function,
     with result going to TARGET if that's convenient
     (and in mode MODE if that's convenient).
-@@ -14990,9 +15589,11 @@
+@@ -14990,9 +15602,11 @@
      }  
  
    unsigned attr = rs6000_builtin_info[uns_fcode].attr & RS6000_BTC_TYPE_MASK;
@@ -812672,7 +826236,7 @@ Index: gcc/config/rs6000/rs6000.c
  
    /* Handle simple unary operations.  */
    d = bdesc_1arg;
-@@ -15012,6 +15613,12 @@
+@@ -15012,6 +15626,12 @@
      if (d->code == fcode)
        return rs6000_expand_ternop_builtin (d->icode, exp, target);
  
@@ -812685,7 +826249,7 @@ Index: gcc/config/rs6000/rs6000.c
    gcc_unreachable ();
  }
  
-@@ -15049,6 +15656,10 @@
+@@ -15049,6 +15669,10 @@
    opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
    opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
  
@@ -812696,7 +826260,7 @@ Index: gcc/config/rs6000/rs6000.c
    /* We use V1TI mode as a special container to hold __int128_t items that
       must live in VSX registers.  */
    if (intTI_type_node)
-@@ -15111,6 +15722,12 @@
+@@ -15111,6 +15735,12 @@
        lang_hooks.types.register_builtin_type (ibm128_float_type_node,
  					      "__ibm128");
      }
@@ -812709,7 +826273,7 @@ Index: gcc/config/rs6000/rs6000.c
  
    /* Initialize the modes for builtin_function_type, mapping a machine mode to
       tree type node.  */
-@@ -15252,6 +15869,15 @@
+@@ -15252,6 +15882,15 @@
    if (TARGET_EXTRA_BUILTINS || TARGET_SPE || TARGET_PAIRED_FLOAT)
      rs6000_common_init_builtins ();
  
@@ -812725,7 +826289,7 @@ Index: gcc/config/rs6000/rs6000.c
    ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
  				 RS6000_BUILTIN_RECIP, "__builtin_recipdiv");
    def_builtin ("__builtin_recipdiv", ftype, RS6000_BUILTIN_RECIP);
-@@ -15816,10 +16442,44 @@
+@@ -15816,10 +16455,44 @@
  	       VSX_BUILTIN_STXVW4X_V8HI);
    def_builtin ("__builtin_vsx_stxvw4x_v16qi", void_ftype_v16qi_long_pvoid,
  	       VSX_BUILTIN_STXVW4X_V16QI);
@@ -812770,7 +826334,7 @@ Index: gcc/config/rs6000/rs6000.c
  
    def_builtin ("__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
    def_builtin ("__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
-@@ -16351,10 +17011,6 @@
+@@ -16351,10 +17024,6 @@
    while (num_args > 0 && h.mode[num_args] == VOIDmode)
      num_args--;
  
@@ -812781,7 +826345,7 @@ Index: gcc/config/rs6000/rs6000.c
    ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
    if (!ret_type && h.uns_p[0])
      ret_type = builtin_mode_to_type[h.mode[0]][0];
-@@ -16406,6 +17062,7 @@
+@@ -16406,6 +17075,7 @@
    tree opaque_ftype_opaque = NULL_TREE;
    tree opaque_ftype_opaque_opaque = NULL_TREE;
    tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
@@ -812789,7 +826353,7 @@ Index: gcc/config/rs6000/rs6000.c
    tree v2si_ftype_qi = NULL_TREE;
    tree v2si_ftype_v2si_qi = NULL_TREE;
    tree v2si_ftype_int_qi = NULL_TREE;
-@@ -16622,6 +17279,64 @@
+@@ -16622,6 +17292,64 @@
  
        def_builtin (d->name, type, d->code);
      }
@@ -812854,7 +826418,7 @@ Index: gcc/config/rs6000/rs6000.c
  }
  
  /* Set up AIX/Darwin/64-bit Linux quad floating point routines.  */
-@@ -18006,25 +18721,33 @@
+@@ -18006,25 +18734,33 @@
      addr_mask = (reg_addr[mode].addr_mask[RELOAD_REG_VMX]
  		 & ~RELOAD_REG_AND_M16);
  
@@ -812899,7 +826463,7 @@ Index: gcc/config/rs6000/rs6000.c
  
        return -1;
      }
-@@ -18152,6 +18875,16 @@
+@@ -18152,6 +18888,16 @@
  	    }
  	}
  
@@ -812916,7 +826480,7 @@ Index: gcc/config/rs6000/rs6000.c
        /* Make sure the register class can handle offset addresses.  */
        else if (rs6000_legitimate_offset_address_p (mode, addr, false, true))
  	{
-@@ -18158,7 +18891,7 @@
+@@ -18158,7 +18904,7 @@
  	  if ((addr_mask & RELOAD_REG_OFFSET) == 0)
  	    {
  	      extra_cost = 1;
@@ -812925,7 +826489,7 @@ Index: gcc/config/rs6000/rs6000.c
  	    }
  	}
  
-@@ -18171,8 +18904,15 @@
+@@ -18171,8 +18917,15 @@
        break;
  
      case LO_SUM:
@@ -812942,7 +826506,7 @@ Index: gcc/config/rs6000/rs6000.c
  	  fail_msg = "bad LO_SUM";
  	  extra_cost = -1;
  	}
-@@ -18188,8 +18928,17 @@
+@@ -18188,8 +18941,17 @@
      case CONST:
      case SYMBOL_REF:
      case LABEL_REF:
@@ -812962,7 +826526,7 @@ Index: gcc/config/rs6000/rs6000.c
        break;
  
        /* TOC references look like offsetable memory.  */
-@@ -18200,6 +18949,12 @@
+@@ -18200,6 +18962,12 @@
  	  extra_cost = -1;
  	}
  
@@ -812975,7 +826539,7 @@ Index: gcc/config/rs6000/rs6000.c
        else if ((addr_mask & RELOAD_REG_OFFSET) == 0)
  	{
  	  extra_cost = 1;
-@@ -18256,7 +19011,8 @@
+@@ -18256,7 +19024,8 @@
       simple move insns are issued.  At present, 32-bit integers are not allowed
       in FPR/VSX registers.  Single precision binary floating is not a simple
       move because we need to convert to the single precision memory layout.
@@ -812985,7 +826549,7 @@ Index: gcc/config/rs6000/rs6000.c
    size = GET_MODE_SIZE (mode);
    if (TARGET_DIRECT_MOVE
        && ((mode == SDmode) || (TARGET_POWERPC64 && size == 8))
-@@ -18264,7 +19020,7 @@
+@@ -18264,7 +19033,7 @@
  	  || (to_type == VSX_REG_TYPE && from_type == GPR_REG_TYPE)))
      return true;
  
@@ -812994,7 +826558,7 @@ Index: gcc/config/rs6000/rs6000.c
  	   && ((to_type == VSX_REG_TYPE && from_type == GPR_REG_TYPE)
  	       || (to_type == GPR_REG_TYPE && from_type == VSX_REG_TYPE)))
      return true;
-@@ -18653,6 +19409,9 @@
+@@ -18653,6 +19422,9 @@
  	fprintf (stderr, ", reload func = %s, extra cost = %d",
  		 insn_data[sri->icode].name, sri->extra_cost);
  
@@ -813004,7 +826568,7 @@ Index: gcc/config/rs6000/rs6000.c
        fputs ("\n", stderr);
        debug_rtx (x);
      }
-@@ -18827,6 +19586,16 @@
+@@ -18827,6 +19599,16 @@
  	    }
  	}
  
@@ -813021,7 +826585,7 @@ Index: gcc/config/rs6000/rs6000.c
        /* Make sure the register class can handle offset addresses.  */
        else if (rs6000_legitimate_offset_address_p (mode, addr, false, true))
  	{
-@@ -18857,6 +19626,13 @@
+@@ -18857,6 +19639,13 @@
  	    }
  	}
  
@@ -813035,7 +826599,7 @@ Index: gcc/config/rs6000/rs6000.c
        /* Make sure the register class can handle offset addresses.  */
        else if (legitimate_lo_sum_address_p (mode, addr, false))
  	{
-@@ -19046,6 +19822,16 @@
+@@ -19046,6 +19835,16 @@
    machine_mode mode = GET_MODE (x);
    bool is_constant = CONSTANT_P (x);
  
@@ -813052,7 +826616,7 @@ Index: gcc/config/rs6000/rs6000.c
    /* For VSX, see if we should prefer FLOAT_REGS or ALTIVEC_REGS.  Do not allow
       the reloading of address expressions using PLUS into floating point
       registers.  */
-@@ -19067,7 +19853,8 @@
+@@ -19067,7 +19866,8 @@
  	}
  
        /* D-form addressing can easily reload the value.  */
@@ -813062,7 +826626,7 @@ Index: gcc/config/rs6000/rs6000.c
  	return rclass;
  
        /* If this is a scalar floating point value and we don't have D-form
-@@ -19095,6 +19882,25 @@
+@@ -19095,6 +19895,25 @@
        return NO_REGS;
      }
  
@@ -813088,7 +826652,7 @@ Index: gcc/config/rs6000/rs6000.c
    if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
      return GENERAL_REGS;
  
-@@ -19483,8 +20289,16 @@
+@@ -19483,8 +20302,16 @@
  
        else if (TARGET_VSX && dest_vsx_p)
  	{
@@ -813106,7 +826670,7 @@ Index: gcc/config/rs6000/rs6000.c
  	  else
  	    return "lxvd2x %x0,%y1";
  	}
-@@ -19513,8 +20327,16 @@
+@@ -19513,8 +20340,16 @@
  
        else if (TARGET_VSX && src_vsx_p)
  	{
@@ -813124,7 +826688,7 @@ Index: gcc/config/rs6000/rs6000.c
  	  else
  	    return "stxvd2x %x1,%y0";
  	}
-@@ -19536,10 +20358,8 @@
+@@ -19536,10 +20371,8 @@
        if (dest_gpr_p)
  	return "#";
  
@@ -813137,7 +826701,7 @@ Index: gcc/config/rs6000/rs6000.c
  	return output_vec_const_move (operands);
      }
  
-@@ -21747,6 +22567,101 @@
+@@ -21747,6 +22580,101 @@
    return 1;
  }
  
@@ -813239,7 +826803,7 @@ Index: gcc/config/rs6000/rs6000.c
  /* Emit a conditional move: move TRUE_COND to DEST if OP of the
     operands of the last comparison is nonzero/true, FALSE_COND if it
     is zero/false.  Return 0 if the hardware has no such operation.  */
-@@ -21773,6 +22688,18 @@
+@@ -21773,6 +22701,18 @@
    if (GET_MODE (false_cond) != result_mode)
      return 0;
  
@@ -813258,7 +826822,56 @@ Index: gcc/config/rs6000/rs6000.c
    /* Don't allow using floating point comparisons for integer results for
       now.  */
    if (FLOAT_MODE_P (compare_mode) && !FLOAT_MODE_P (result_mode))
-@@ -25949,7 +26876,7 @@
+@@ -22034,6 +22974,48 @@
+     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 (REG_P (dest));
++  gcc_assert (REG_P (src) || MEM_P (src));
++  gcc_assert (s_mode == KFmode || s_mode == TFmode);
++
++  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 = REGNO (src);
++
++      /* If this is a VSX register, generate the special mfvsrd instruction
++	 to get it in a GPR.  Until we support SF and DF modes, that will
++	 always be true.  */
++      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.  */
+ 
+@@ -25949,7 +26931,7 @@
  	if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
  	  {
  	    rtx areg, savereg, mem;
@@ -813267,7 +826880,7 @@ Index: gcc/config/rs6000/rs6000.c
  
  	    offset = (info->altivec_save_offset + frame_off
  		      + 16 * (i - info->first_altivec_reg_save));
-@@ -25956,18 +26883,30 @@
+@@ -25956,18 +26938,30 @@
  
  	    savereg = gen_rtx_REG (V4SImode, i);
  
@@ -813308,7 +826921,7 @@ Index: gcc/config/rs6000/rs6000.c
  
  	    rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
  				  areg, GEN_INT (offset));
-@@ -26687,23 +27626,35 @@
+@@ -26687,23 +27681,35 @@
  	  for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
  	    if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
  	      {
@@ -813358,7 +826971,7 @@ Index: gcc/config/rs6000/rs6000.c
  	      }
  	}
  
-@@ -26890,23 +27841,35 @@
+@@ -26890,23 +27896,35 @@
  	  for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
  	    if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
  	      {
@@ -813408,7 +827021,7 @@ Index: gcc/config/rs6000/rs6000.c
  	      }
  	}
  
-@@ -27724,6 +28687,11 @@
+@@ -27724,6 +28742,11 @@
  				   const0_rtx, const0_rtx));
    call_fusage = NULL_RTX;
    use_reg (&call_fusage, r12);
@@ -813420,7 +827033,428 @@ Index: gcc/config/rs6000/rs6000.c
    add_function_usage_to (insn, call_fusage);
    emit_insn (gen_frame_load (r0, r1, info->lr_save_offset));
    insn = emit_move_insn (lr, r0);
-@@ -33448,17 +34416,25 @@
+@@ -28763,7 +29786,7 @@
+ 
+ /* The following variable value is the last issued insn.  */
+ 
+-static rtx last_scheduled_insn;
++static rtx_insn *last_scheduled_insn;
+ 
+ /* The following variable helps to balance issuing of load and
+    store instructions */
+@@ -28770,6 +29793,13 @@
+ 
+ static int load_store_pendulum;
+ 
++/* The following variable helps pair divide insns during scheduling.  */
++static int divide_cnt;
++/* The following variable helps pair and alternate vector and vector load
++   insns during scheduling.  */
++static int vec_load_pendulum;
++
++
+ /* Power4 load update and store update instructions are cracked into a
+    load or store and an integer insn which are executed in the same cycle.
+    Branches have their own dispatch slot which does not count against the
+@@ -28844,7 +29874,7 @@
+ 	   some cycles later.  */
+ 
+ 	/* Separate a load from a narrower, dependent store.  */
+-	if (rs6000_sched_groups
++	if ((rs6000_sched_groups || rs6000_cpu_attr == CPU_POWER9)
+ 	    && GET_CODE (PATTERN (insn)) == SET
+ 	    && GET_CODE (PATTERN (dep_insn)) == SET
+ 	    && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
+@@ -29070,7 +30100,9 @@
+           switch (attr_type)
+             {
+             case TYPE_FP:
+-              if (get_attr_type (dep_insn) == TYPE_FP)
++            case TYPE_FPSIMPLE:
++              if (get_attr_type (dep_insn) == TYPE_FP
++		  || get_attr_type (dep_insn) == TYPE_FPSIMPLE)
+                 return 1;
+               break;
+             case TYPE_FPLOAD:
+@@ -29082,6 +30114,8 @@
+               break;
+             }
+         }
++      /* Fall through, no cost for output dependency.  */
++
+     case REG_DEP_ANTI:
+       /* Anti dependency; DEP_INSN reads a register that INSN writes some
+ 	 cycles later.  */
+@@ -29454,8 +30488,9 @@
+   case CPU_POWER7:
+     return 5;
+   case CPU_POWER8:
++    return 7;
+   case CPU_POWER9:
+-    return 7;
++    return 6;
+   default:
+     return 1;
+   }
+@@ -29613,6 +30648,28 @@
+   return is_store_insn1 (PATTERN (insn), str_mem);
+ }
+ 
++/* Return whether TYPE is a Power9 pairable vector instruction type.  */
++
++static bool
++is_power9_pairable_vec_type (enum attr_type type)
++{
++  switch (type)
++    {
++      case TYPE_VECSIMPLE:
++      case TYPE_VECCOMPLEX:
++      case TYPE_VECDIV:
++      case TYPE_VECCMP:
++      case TYPE_VECPERM:
++      case TYPE_VECFLOAT:
++      case TYPE_VECFDIV:
++      case TYPE_VECDOUBLE:
++	return true;
++      default:
++	break;
++    }
++  return false;
++}
++
+ /* Returns whether the dependence between INSN and NEXT is considered
+    costly by the given target.  */
+ 
+@@ -29689,6 +30746,229 @@
+   return insn;
+ }
+ 
++/* Do Power9 specific sched_reorder2 reordering of ready list.  */
++
++static int
++power9_sched_reorder2 (rtx_insn **ready, int lastpos)
++{
++  int pos;
++  int i;
++  rtx_insn *tmp;
++  enum attr_type type;
++
++  type = get_attr_type (last_scheduled_insn);
++
++  /* Try to issue fixed point divides back-to-back in pairs so they will be
++     routed to separate execution units and execute in parallel.  */
++  if (type == TYPE_DIV && divide_cnt == 0)
++    {
++      /* First divide has been scheduled.  */
++      divide_cnt = 1;
++
++      /* Scan the ready list looking for another divide, if found move it
++	 to the end of the list so it is chosen next.  */
++      pos = lastpos;
++      while (pos >= 0)
++	{
++	  if (recog_memoized (ready[pos]) >= 0
++	      && get_attr_type (ready[pos]) == TYPE_DIV)
++	    {
++	      tmp = ready[pos];
++	      for (i = pos; i < lastpos; i++)
++		ready[i] = ready[i + 1];
++	      ready[lastpos] = tmp;
++	      break;
++	    }
++	  pos--;
++	}
++    }
++  else
++    {
++      /* Last insn was the 2nd divide or not a divide, reset the counter.  */
++      divide_cnt = 0;
++
++      /* Power9 can execute 2 vector operations and 2 vector loads in a single
++	 cycle.  So try to pair up and alternate groups of vector and vector
++	 load instructions.
++
++	 To aid this formation, a counter is maintained to keep track of
++	 vec/vecload insns issued.  The value of vec_load_pendulum maintains
++	 the current state with the following values:
++
++	     0  : Initial state, no vec/vecload group has been started.
++
++	     -1 : 1 vector load has been issued and another has been found on
++		  the ready list and moved to the end.
++
++	     -2 : 2 vector loads have been issued and a vector operation has
++		  been found and moved to the end of the ready list.
++
++	     -3 : 2 vector loads and a vector insn have been issued and a
++		  vector operation has been found and moved to the end of the
++		  ready list.
++
++	     1  : 1 vector insn has been issued and another has been found and
++		  moved to the end of the ready list.
++
++	     2  : 2 vector insns have been issued and a vector load has been
++		  found and moved to the end of the ready list.
++
++	     3  : 2 vector insns and a vector load have been issued and another
++		  vector load has been found and moved to the end of the ready
++		  list.	 */
++      if (type == TYPE_VECLOAD)
++	{
++	  /* Issued a vecload.  */
++	  if (vec_load_pendulum == 0)
++	    {
++	      /* We issued a single vecload, look for another and move it to
++		 the end of the ready list so it will be scheduled next.
++		 Set pendulum if found.  */
++	      pos = lastpos;
++	      while (pos >= 0)
++		{
++		  if (recog_memoized (ready[pos]) >= 0
++		      && get_attr_type (ready[pos]) == TYPE_VECLOAD)
++		    {
++		      tmp = ready[pos];
++		      for (i = pos; i < lastpos; i++)
++			ready[i] = ready[i + 1];
++		      ready[lastpos] = tmp;
++		      vec_load_pendulum = -1;
++		      return cached_can_issue_more;
++		    }
++		  pos--;
++		}
++	    }
++	  else if (vec_load_pendulum == -1)
++	    {
++	      /* This is the second vecload we've issued, search the ready
++	         list for a vector operation so we can try to schedule a
++	         pair of those next.  If found move to the end of the ready
++	         list so it is scheduled next and set the pendulum.  */
++	      pos = lastpos;
++	      while (pos >= 0)
++		{
++		  if (recog_memoized (ready[pos]) >= 0
++		      && is_power9_pairable_vec_type (
++			   get_attr_type (ready[pos])))
++		    {
++		      tmp = ready[pos];
++		      for (i = pos; i < lastpos; i++)
++			ready[i] = ready[i + 1];
++		      ready[lastpos] = tmp;
++		      vec_load_pendulum = -2;
++		      return cached_can_issue_more;
++		    }
++		  pos--;
++		}
++	    }
++	  else if (vec_load_pendulum == 2)
++	    {
++	      /* Two vector ops have been issued and we've just issued a
++		 vecload, look for another vecload and move to end of ready
++		 list if found.  */
++	      pos = lastpos;
++	      while (pos >= 0)
++	        {
++		  if (recog_memoized (ready[pos]) >= 0
++		      && get_attr_type (ready[pos]) == TYPE_VECLOAD)
++		    {
++		      tmp = ready[pos];
++		      for (i = pos; i < lastpos; i++)
++			ready[i] = ready[i + 1];
++		      ready[lastpos] = tmp;
++		      /* Set pendulum so that next vecload will be seen as
++			 finishing a group, not start of one.  */
++		      vec_load_pendulum = 3;
++		      return cached_can_issue_more;
++		    }
++		  pos--;
++		}
++	    }
++	}
++      else if (is_power9_pairable_vec_type (type))
++	{
++	  /* Issued a vector operation.  */
++	  if (vec_load_pendulum == 0)
++	    /* We issued a single vec op, look for another and move it
++	       to the end of the ready list so it will be scheduled next.
++	       Set pendulum if found.  */
++	    {
++	      pos = lastpos;
++	      while (pos >= 0)
++		{
++		  if (recog_memoized (ready[pos]) >= 0
++		      && is_power9_pairable_vec_type (
++			   get_attr_type (ready[pos])))
++		    {
++		      tmp = ready[pos];
++		      for (i = pos; i < lastpos; i++)
++			ready[i] = ready[i + 1];
++		      ready[lastpos] = tmp;
++		      vec_load_pendulum = 1;
++		      return cached_can_issue_more;
++		    }
++		  pos--;
++		}
++	    }
++	  else if (vec_load_pendulum == 1)
++	    {
++	      /* This is the second vec op we've issued, search the ready
++		 list for a vecload operation so we can try to schedule a
++		 pair of those next.  If found move to the end of the ready
++		 list so it is scheduled next and set the pendulum.  */
++	      pos = lastpos;
++	      while (pos >= 0)
++		{
++		  if (recog_memoized (ready[pos]) >= 0
++		      && get_attr_type (ready[pos]) == TYPE_VECLOAD)
++		    {
++		      tmp = ready[pos];
++		      for (i = pos; i < lastpos; i++)
++			ready[i] = ready[i + 1];
++		      ready[lastpos] = tmp;
++		      vec_load_pendulum = 2;
++		      return cached_can_issue_more;
++		    }
++		  pos--;
++		}
++	    }
++	  else if (vec_load_pendulum == -2)
++	    {
++	      /* Two vecload ops have been issued and we've just issued a
++		 vec op, look for another vec op and move to end of ready
++	  	 list if found.  */
++	      pos = lastpos;
++	      while (pos >= 0)
++		{
++		  if (recog_memoized (ready[pos]) >= 0
++		      && is_power9_pairable_vec_type (
++			   get_attr_type (ready[pos])))
++		    {
++		      tmp = ready[pos];
++		      for (i = pos; i < lastpos; i++)
++			ready[i] = ready[i + 1];
++		      ready[lastpos] = tmp;
++		      /* Set pendulum so that next vec op will be seen as
++			 finishing a group, not start of one.  */
++		      vec_load_pendulum = -3;
++		      return cached_can_issue_more;
++		    }
++		  pos--;
++		}
++	    }
++	}
++
++      /* We've either finished a vec/vecload group, couldn't find an insn to
++	 continue the current group, or the last insn had nothing to do with
++	 with a group.  In any case, reset the pendulum.  */
++      vec_load_pendulum = 0;
++    }
++
++  return cached_can_issue_more;
++}
++
+ /* We are about to begin issuing insns for this clock cycle. */
+ 
+ static int
+@@ -29920,6 +31200,11 @@
+         }
+     }
+ 
++  /* Do Power9 dependent reordering if necessary.  */
++  if (rs6000_cpu == PROCESSOR_POWER9 && last_scheduled_insn
++      && recog_memoized (last_scheduled_insn) >= 0)
++    return power9_sched_reorder2 (ready, *pn_ready - 1);
++
+   return cached_can_issue_more;
+ }
+ 
+@@ -30088,7 +31373,6 @@
+         }
+       break;
+     case PROCESSOR_POWER8:
+-    case PROCESSOR_POWER9:
+       type = get_attr_type (insn);
+ 
+       switch (type)
+@@ -30219,7 +31503,6 @@
+     }
+     break;
+   case PROCESSOR_POWER8:
+-  case PROCESSOR_POWER9:
+     type = get_attr_type (insn);
+ 
+     switch (type)
+@@ -30338,7 +31621,7 @@
+ 
+       /* Do we have a special group ending nop? */
+       if (rs6000_cpu_attr == CPU_POWER6 || rs6000_cpu_attr == CPU_POWER7
+-	  || rs6000_cpu_attr == CPU_POWER8 || rs6000_cpu_attr == CPU_POWER9)
++	  || rs6000_cpu_attr == CPU_POWER8)
+ 	{
+ 	  nop = gen_group_ending_nop ();
+ 	  emit_insn_before (nop, next_insn);
+@@ -30592,8 +31875,10 @@
+ 		     int sched_verbose ATTRIBUTE_UNUSED,
+ 		     int max_ready ATTRIBUTE_UNUSED)
+ {
+-  last_scheduled_insn = NULL_RTX;
++  last_scheduled_insn = NULL;
+   load_store_pendulum = 0;
++  divide_cnt = 0;
++  vec_load_pendulum = 0;
+ }
+ 
+ /* The following function is called at the end of scheduling BB.
+@@ -30634,14 +31919,16 @@
+     }
+ }
+ 
+-struct _rs6000_sched_context
++struct rs6000_sched_context
+ {
+   short cached_can_issue_more;
+-  rtx last_scheduled_insn;
++  rtx_insn *last_scheduled_insn;
+   int load_store_pendulum;
++  int divide_cnt;
++  int vec_load_pendulum;
+ };
+ 
+-typedef struct _rs6000_sched_context rs6000_sched_context_def;
++typedef struct rs6000_sched_context rs6000_sched_context_def;
+ typedef rs6000_sched_context_def *rs6000_sched_context_t;
+ 
+ /* Allocate store for new scheduling context.  */
+@@ -30661,8 +31948,10 @@
+   if (clean_p)
+     {
+       sc->cached_can_issue_more = 0;
+-      sc->last_scheduled_insn = NULL_RTX;
++      sc->last_scheduled_insn = NULL;
+       sc->load_store_pendulum = 0;
++      sc->divide_cnt = 0;
++      sc->vec_load_pendulum = 0;
+     }
+   else
+     {
+@@ -30669,6 +31958,8 @@
+       sc->cached_can_issue_more = cached_can_issue_more;
+       sc->last_scheduled_insn = last_scheduled_insn;
+       sc->load_store_pendulum = load_store_pendulum;
++      sc->divide_cnt = divide_cnt;
++      sc->vec_load_pendulum = vec_load_pendulum;
+     }
+ }
+ 
+@@ -30683,6 +31974,8 @@
+   cached_can_issue_more = sc->cached_can_issue_more;
+   last_scheduled_insn = sc->last_scheduled_insn;
+   load_store_pendulum = sc->load_store_pendulum;
++  divide_cnt = sc->divide_cnt;
++  vec_load_pendulum = sc->vec_load_pendulum;
+ }
+ 
+ /* Free _SC.  */
+@@ -33448,17 +34741,25 @@
    if (!REG_P (target))
      tmp = gen_reg_rtx (mode);
  
@@ -813456,7 +827490,7 @@ Index: gcc/config/rs6000/rs6000.c
  
    /* Copy into target, possibly by way of a register.  */
    if (!REG_P (target))
-@@ -33869,8 +34845,14 @@
+@@ -33869,8 +35170,14 @@
    machine_mode inner = GET_MODE_INNER (mode);
    unsigned int inner_bytes = GET_MODE_UNIT_SIZE (mode);
  
@@ -813472,7 +827506,17 @@ Index: gcc/config/rs6000/rs6000.c
    else
      {
        regno = GP_ARG_RETURN;
-@@ -34056,7 +35038,7 @@
+@@ -33992,7 +35299,8 @@
+   if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
+     /* _Decimal128 must use an even/odd register pair.  */
+     regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
+-  else if (SCALAR_FLOAT_MODE_NOT_VECTOR_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS
++  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
++	   && !FLOAT128_VECTOR_P (mode)
+ 	   && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
+     regno = FP_ARG_RETURN;
+   else if (TREE_CODE (valtype) == COMPLEX_TYPE
+@@ -34056,7 +35364,7 @@
  static bool
  rs6000_lra_p (void)
  {
@@ -813481,7 +827525,7 @@ Index: gcc/config/rs6000/rs6000.c
  }
  
  /* Given FROM and TO register numbers, say whether this elimination is allowed.
-@@ -34417,7 +35399,8 @@
+@@ -34417,9 +35725,11 @@
    { "power8-fusion",		OPTION_MASK_P8_FUSION,		false, true  },
    { "power8-fusion-sign",	OPTION_MASK_P8_FUSION_SIGN,	false, true  },
    { "power8-vector",		OPTION_MASK_P8_VECTOR,		false, true  },
@@ -813490,12 +827534,16 @@ Index: gcc/config/rs6000/rs6000.c
 +  { "power9-dform-vector",	OPTION_MASK_P9_DFORM_VECTOR,	false, true  },
    { "power9-fusion",		OPTION_MASK_P9_FUSION,		false, true  },
    { "power9-minmax",		OPTION_MASK_P9_MINMAX,		false, true  },
++  { "power9-misc",		OPTION_MASK_P9_MISC,		false, true  },
    { "power9-vector",		OPTION_MASK_P9_VECTOR,		false, true  },
-@@ -34474,11 +35457,13 @@
+   { "powerpc-gfxopt",		OPTION_MASK_PPC_GFXOPT,		false, true  },
+   { "powerpc-gpopt",		OPTION_MASK_PPC_GPOPT,		false, true  },
+@@ -34474,11 +35784,14 @@
    { "popcntd",		 RS6000_BTM_POPCNTD,	false, false },
    { "cell",		 RS6000_BTM_CELL,	false, false },
    { "power8-vector",	 RS6000_BTM_P8_VECTOR,	false, false },
 +  { "power9-vector",	 RS6000_BTM_P9_VECTOR,	false, false },
++  { "power9-misc",	 RS6000_BTM_P9_MISC,	false, false },
    { "crypto",		 RS6000_BTM_CRYPTO,	false, false },
    { "htm",		 RS6000_BTM_HTM,	false, false },
    { "hard-dfp",		 RS6000_BTM_DFP,	false, false },
@@ -813505,7 +827553,7 @@ Index: gcc/config/rs6000/rs6000.c
  };
  
  /* Option variables that we want to support inside attribute((target)) and
-@@ -35049,7 +36034,9 @@
+@@ -35049,7 +36362,9 @@
    size_t i;
    size_t start_column = 0;
    size_t cur_column;
@@ -813516,7 +827564,7 @@ Index: gcc/config/rs6000/rs6000.c
    const char *comma = "";
  
    if (indent)
-@@ -35067,27 +36054,45 @@
+@@ -35067,27 +36382,45 @@
    cur_column = start_column;
    for (i = 0; i < num_elements; i++)
      {
@@ -813577,6 +827625,19 @@ Index: gcc/config/rs6000/rs6000.c
      }
  
    fputs ("\n", file);
+Index: gcc/config/rs6000/titan.md
+===================================================================
+--- a/src/gcc/config/rs6000/titan.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/titan.md	(.../branches/gcc-6-branch)
+@@ -156,7 +156,7 @@
+ ;; Make sure the "titan_fp" rule stays last, as it's a catch all for
+ ;; double-precision and unclassified (e.g. fsel) FP-instructions
+ (define_insn_reservation "titan_fp" 10
+-  (and (eq_attr "type" "fpcompare,fp,dmul")
++  (and (eq_attr "type" "fpcompare,fp,fpsimple,dmul")
+        (eq_attr "cpu" "titan"))
+   "titan_issue,titan_fp0*2,nothing*8,titan_fpwb")
+ 
 Index: gcc/config/rs6000/vsx.md
 ===================================================================
 --- a/src/gcc/config/rs6000/vsx.md	(.../tags/gcc_6_1_0_release)
@@ -813652,6 +827713,15 @@ Index: gcc/config/rs6000/vsx.md
  ;; VSX moves
  
  ;; The patterns for LE permuted loads and stores come before the general
+@@ -709,7 +685,7 @@
+     }
+ }
+   [(set_attr "length" "0,4")
+-   (set_attr "type" "vecsimple")])
++   (set_attr "type" "veclogical")])
+ 
+ (define_insn_and_split "*vsx_le_perm_load_<mode>"
+   [(set (match_operand:VSX_LE_128 0 "vsx_register_operand" "=<VSa>")
 @@ -787,93 +763,142 @@
  			   (const_int 64)))]
    "")
@@ -814004,6 +828074,24 @@ Index: gcc/config/rs6000/vsx.md
  

  ;; VSX vector floating point arithmetic instructions.  The VSX scalar
  ;; instructions are now combined with the insn for the traditional floating
+@@ -1333,7 +1492,7 @@
+ 	 (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,<VSa>")))]
+   "VECTOR_MEM_VSX_P (<MODE>mode)"
+   "xxsel %x0,%x3,%x2,%x1"
+-  [(set_attr "type" "vecperm")])
++  [(set_attr "type" "vecmove")])
+ 
+ (define_insn "*vsx_xxsel<mode>_uns"
+   [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?<VSa>")
+@@ -1344,7 +1503,7 @@
+ 	 (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,<VSa>")))]
+   "VECTOR_MEM_VSX_P (<MODE>mode)"
+   "xxsel %x0,%x3,%x2,%x1"
+-  [(set_attr "type" "vecperm")])
++  [(set_attr "type" "vecmove")])
+ 
+ ;; Copy sign
+ (define_insn "vsx_copysign<mode>3"
 @@ -1583,10 +1742,15 @@
  {
    rtx op0 = operands[0];
@@ -814044,7 +828132,25 @@ Index: gcc/config/rs6000/vsx.md
    emit_insn (gen_vsx_xvcvdpuxds (op0, tmp));
    DONE;
  })
-@@ -2215,20 +2384,62 @@
+@@ -1960,7 +2129,7 @@
+ 
+   return "xxlor %x0,%x1,%x1";
+ }
+-  [(set_attr "type" "fp,vecsimple,mftgpr,mftgpr")
++  [(set_attr "type" "fpsimple,veclogical,mftgpr,mftgpr")
+    (set_attr "length" "4")])
+ 
+ (define_insn "*vsx_extract_<mode>_internal2"
+@@ -1995,7 +2164,7 @@
+   operands[3] = GEN_INT (fldDM);
+   return "xxpermdi %x0,%x1,%x1,%3";
+ }
+-  [(set_attr "type" "fp,vecsimple,vecperm")
++  [(set_attr "type" "fpsimple,veclogical,vecperm")
+    (set_attr "length" "4")])
+ 
+ ;; Optimize extracting a single scalar element from memory if the scalar is in
+@@ -2215,20 +2384,61 @@
  
  ;; V2DF/V2DI splat
  (define_insn "vsx_splat_<mode>"
@@ -814104,9 +828210,8 @@ Index: gcc/config/rs6000/vsx.md
 +  [(set (match_dup 0)
 +	(unspec:V4SF [(match_dup 1)] UNSPEC_VSX_CVDPSPN))
 +   (set (match_dup 0)
-+	(vec_duplicate:V4SF
-+	 (vec_select:SF (match_dup 0)
-+			(parallel [(const_int 0)]))))]
++	(unspec:V4SF [(match_dup 0)
++		      (const_int 0)] UNSPEC_VSX_XXSPLTW))]
 +  ""
 +  [(set_attr "type" "vecload,vecperm,mftgpr")
 +   (set_attr "length" "4,8,4")])
@@ -814115,7 +828220,7 @@ Index: gcc/config/rs6000/vsx.md
  (define_insn "vsx_xxspltw_<mode>"
    [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?<VSa>")
  	(vec_duplicate:VSX_W
-@@ -2471,11 +2682,11 @@
+@@ -2471,11 +2681,11 @@
  (define_peephole
    [(set (match_operand:P 0 "base_reg_operand" "")
  	(match_operand:P 1 "short_cint_operand" ""))
@@ -814131,7 +828236,7 @@ Index: gcc/config/rs6000/vsx.md
    [(set_attr "length" "8")
     (set_attr "type" "vecload")])
  
-@@ -2482,10 +2693,39 @@
+@@ -2482,10 +2692,39 @@
  (define_peephole
    [(set (match_operand:P 0 "base_reg_operand" "")
  	(match_operand:P 1 "short_cint_operand" ""))
@@ -814157,7 +828262,7 @@ Index: gcc/config/rs6000/vsx.md
 +	 UNSPEC_VSX_SIGN_EXTEND))]
 +  "TARGET_P9_VECTOR"
 +  "vextsb2<wd> %0,%1"
-+  [(set_attr "type" "vecsimple")])
++  [(set_attr "type" "vecexts")])
 +
 +(define_insn "*vsx_sign_extend_hi_<mode>"
 +  [(set (match_operand:VSINT_84 0 "vsx_register_operand" "=v")
@@ -814166,7 +828271,7 @@ Index: gcc/config/rs6000/vsx.md
 +	 UNSPEC_VSX_SIGN_EXTEND))]
 +  "TARGET_P9_VECTOR"
 +  "vextsh2<wd> %0,%1"
-+  [(set_attr "type" "vecsimple")])
++  [(set_attr "type" "vecexts")])
 +
 +(define_insn "*vsx_sign_extend_si_v2di"
 +  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v")
@@ -814174,12 +828279,12 @@ Index: gcc/config/rs6000/vsx.md
 +		     UNSPEC_VSX_SIGN_EXTEND))]
 +  "TARGET_P9_VECTOR"
 +  "vextsw2d %0,%1"
-+  [(set_attr "type" "vecsimple")])
++  [(set_attr "type" "vecexts")])
 Index: gcc/config/rs6000/rs6000.h
 ===================================================================
 --- a/src/gcc/config/rs6000/rs6000.h	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/config/rs6000/rs6000.h	(.../branches/gcc-6-branch)
-@@ -302,6 +302,26 @@
+@@ -302,6 +302,28 @@
  #define TARGET_P8_VECTOR 0
  #endif
  
@@ -814195,18 +828300,20 @@ Index: gcc/config/rs6000/rs6000.h
 +#undef  TARGET_P9_MINMAX
 +#undef  TARGET_P9_DFORM_SCALAR
 +#undef  TARGET_P9_DFORM_VECTOR
++#undef  TARGET_P9_MISC
 +#define TARGET_FLOAT128_HW 0
 +#define TARGET_MODULO 0
 +#define TARGET_P9_VECTOR 0
 +#define TARGET_P9_MINMAX 0
 +#define TARGET_P9_DFORM_SCALAR 0
 +#define TARGET_P9_DFORM_VECTOR 0
++#define TARGET_P9_MISC 0
 +#endif
 +
  /* Define TARGET_LWSYNC_INSTRUCTION if the assembler knows about lwsync.  If
     not, generate the lwsync code as an integer constant.  */
  #ifdef HAVE_AS_LWSYNC
-@@ -418,12 +438,12 @@
+@@ -418,12 +440,12 @@
     Similarly IFmode is the IBM long double format even if the default is IEEE
     128-bit.  */
  #define FLOAT128_IEEE_P(MODE)						\
@@ -814223,7 +828330,7 @@ Index: gcc/config/rs6000/rs6000.h
  
  /* Helper macros to say whether a 128-bit floating point type can go in a
     single vector register, or whether it needs paired scalar values.  */
-@@ -594,6 +614,15 @@
+@@ -594,6 +616,15 @@
     in the register.  */
  #define TARGET_NO_SDMODE_STACK	(TARGET_LFIWZX && TARGET_STFIWX && TARGET_DFP)
  
@@ -814239,15 +828346,16 @@ Index: gcc/config/rs6000/rs6000.h
  /* In switching from using target_flags to using rs6000_isa_flags, the options
     machinery creates OPTION_MASK_<xxx> instead of MASK_<xxx>.  For now map
     OPTION_MASK_<xxx> back into MASK_<xxx>.  */
-@@ -615,6 +644,7 @@
+@@ -615,6 +646,8 @@
  #define MASK_MULTIPLE			OPTION_MASK_MULTIPLE
  #define MASK_NO_UPDATE			OPTION_MASK_NO_UPDATE
  #define MASK_P8_VECTOR			OPTION_MASK_P8_VECTOR
 +#define MASK_P9_VECTOR			OPTION_MASK_P9_VECTOR
++#define MASK_P9_MISC			OPTION_MASK_P9_MISC
  #define MASK_POPCNTB			OPTION_MASK_POPCNTB
  #define MASK_POPCNTD			OPTION_MASK_POPCNTD
  #define MASK_PPC_GFXOPT			OPTION_MASK_PPC_GFXOPT
-@@ -655,6 +685,11 @@
+@@ -655,6 +688,11 @@
  #define MASK_PROTOTYPE			OPTION_MASK_PROTOTYPE
  #endif
  
@@ -814259,7 +828367,7 @@ Index: gcc/config/rs6000/rs6000.h
  /* For power systems, we want to enable Altivec and VSX builtins even if the
     user did not use -maltivec or -mvsx to allow the builtins to be used inside
     of #pragma GCC target or the target attribute to change the code level for a
-@@ -1774,7 +1809,9 @@
+@@ -1774,7 +1812,9 @@
  #define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2)
  #define FP_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2 ? FP_ARG_RETURN	\
  			   : (FP_ARG_RETURN + AGGR_ARG_NUM_REG - 1))
@@ -814270,7 +828378,7 @@ Index: gcc/config/rs6000/rs6000.h
  			        : (ALTIVEC_ARG_RETURN + AGGR_ARG_NUM_REG - 1))
  
  /* Flags for the call/call_value rtl operations set up by function_arg */
-@@ -2638,7 +2675,9 @@
+@@ -2638,7 +2678,9 @@
  
  #define RS6000_BTC_MISC		0x00000000	/* No special attributes.  */
  #define RS6000_BTC_CONST	0x00000100	/* uses no global state.  */
@@ -814281,15 +828389,16 @@ Index: gcc/config/rs6000/rs6000.h
  #define RS6000_BTC_FP		0x00000400	/* depends on rounding mode.  */
  #define RS6000_BTC_ATTR_MASK	0x00000700	/* Mask of the attributes.  */
  
-@@ -2660,6 +2699,7 @@
+@@ -2660,6 +2702,8 @@
  #define RS6000_BTM_ALTIVEC	MASK_ALTIVEC	/* VMX/altivec vectors.  */
  #define RS6000_BTM_VSX		MASK_VSX	/* VSX (vector/scalar).  */
  #define RS6000_BTM_P8_VECTOR	MASK_P8_VECTOR	/* ISA 2.07 vector.  */
 +#define RS6000_BTM_P9_VECTOR	MASK_P9_VECTOR	/* ISA 3.00 vector.  */
++#define RS6000_BTM_P9_MISC	MASK_P9_MISC	/* ISA 3.0 misc. non-vector.  */
  #define RS6000_BTM_CRYPTO	MASK_CRYPTO	/* crypto funcs.  */
  #define RS6000_BTM_HTM		MASK_HTM	/* hardware TM funcs.  */
  #define RS6000_BTM_SPE		MASK_STRING	/* E500 */
-@@ -2673,10 +2713,13 @@
+@@ -2673,10 +2717,15 @@
  #define RS6000_BTM_DFP		MASK_DFP	/* Decimal floating point.  */
  #define RS6000_BTM_HARD_FLOAT	MASK_SOFT_FLOAT	/* Hardware floating point.  */
  #define RS6000_BTM_LDBL128	MASK_MULTIPLE	/* 128-bit long double.  */
@@ -814300,10 +828409,12 @@ Index: gcc/config/rs6000/rs6000.h
  				 | RS6000_BTM_VSX			\
  				 | RS6000_BTM_P8_VECTOR			\
 +				 | RS6000_BTM_P9_VECTOR			\
++				 | RS6000_BTM_P9_MISC			\
++				 | RS6000_BTM_MODULO                    \
  				 | RS6000_BTM_CRYPTO			\
  				 | RS6000_BTM_FRE			\
  				 | RS6000_BTM_FRES			\
-@@ -2687,10 +2730,12 @@
+@@ -2687,10 +2736,12 @@
  				 | RS6000_BTM_CELL			\
  				 | RS6000_BTM_DFP			\
  				 | RS6000_BTM_HARD_FLOAT		\
@@ -814317,7 +828428,7 @@ Index: gcc/config/rs6000/rs6000.h
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -2703,6 +2748,7 @@
+@@ -2703,6 +2754,7 @@
  #undef RS6000_BUILTIN_S
  #undef RS6000_BUILTIN_X
  
@@ -814325,7 +828436,7 @@ Index: gcc/config/rs6000/rs6000.h
  #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
  #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
  #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
-@@ -2722,6 +2768,7 @@
+@@ -2722,6 +2774,7 @@
    RS6000_BUILTIN_COUNT
  };
  
@@ -814333,7 +828444,7 @@ Index: gcc/config/rs6000/rs6000.h
  #undef RS6000_BUILTIN_1
  #undef RS6000_BUILTIN_2
  #undef RS6000_BUILTIN_3
-@@ -2788,6 +2835,7 @@
+@@ -2788,6 +2841,7 @@
    RS6000_BTI_void,	         /* void_type_node */
    RS6000_BTI_ieee128_float,	 /* ieee 128-bit floating point */
    RS6000_BTI_ibm128_float,	 /* IBM 128-bit floating point */
@@ -814341,7 +828452,7 @@ Index: gcc/config/rs6000/rs6000.h
    RS6000_BTI_MAX
  };
  
-@@ -2844,6 +2892,7 @@
+@@ -2844,6 +2898,7 @@
  #define void_type_internal_node		 (rs6000_builtin_types[RS6000_BTI_void])
  #define ieee128_float_type_node		 (rs6000_builtin_types[RS6000_BTI_ieee128_float])
  #define ibm128_float_type_node		 (rs6000_builtin_types[RS6000_BTI_ibm128_float])
@@ -814405,6 +828516,69 @@ Index: gcc/config/rs6000/altivec.md
  ;; Vector move instructions.
  (define_insn "*altivec_mov<mode>"
    [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,*Y,*r,*r,v,v,*r")
+@@ -225,7 +242,7 @@
+     default: gcc_unreachable ();
+     }
+ }
+-  [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*,*")
++  [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*,*")
+    (set_attr "length" "4,4,4,20,20,20,4,8,32")])
+ 
+ ;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode
+@@ -251,7 +268,7 @@
+     default: gcc_unreachable ();
+     }
+ }
+-  [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
++  [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*")])
+ 
+ ;; Load up a vector with the most significant bit set by loading up -1 and
+ ;; doing a shift left
+@@ -586,7 +603,7 @@
+ 		(match_operand:VI2 2 "altivec_register_operand" "v")))]
+   "<VI_unit>"
+   "vcmpequ<VI_char> %0,%1,%2"
+-  [(set_attr "type" "veccmp")])
++  [(set_attr "type" "veccmpfx")])
+ 
+ (define_insn "*altivec_gt<mode>"
+   [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
+@@ -594,7 +611,7 @@
+ 		(match_operand:VI2 2 "altivec_register_operand" "v")))]
+   "<VI_unit>"
+   "vcmpgts<VI_char> %0,%1,%2"
+-  [(set_attr "type" "veccmp")])
++  [(set_attr "type" "veccmpfx")])
+ 
+ (define_insn "*altivec_gtu<mode>"
+   [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
+@@ -602,7 +619,7 @@
+ 		 (match_operand:VI2 2 "altivec_register_operand" "v")))]
+   "<VI_unit>"
+   "vcmpgtu<VI_char> %0,%1,%2"
+-  [(set_attr "type" "veccmp")])
++  [(set_attr "type" "veccmpfx")])
+ 
+ (define_insn "*altivec_eqv4sf"
+   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
+@@ -637,7 +654,7 @@
+ 	 (match_operand:VM 3 "altivec_register_operand" "v")))]
+   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
+   "vsel %0,%3,%2,%1"
+-  [(set_attr "type" "vecperm")])
++  [(set_attr "type" "vecmove")])
+ 
+ (define_insn "*altivec_vsel<mode>_uns"
+   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
+@@ -648,7 +665,7 @@
+ 	 (match_operand:VM 3 "altivec_register_operand" "v")))]
+   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
+   "vsel %0,%3,%2,%1"
+-  [(set_attr "type" "vecperm")])
++  [(set_attr "type" "vecmove")])
+ 
+ ;; Fused multiply add.
+ 
 @@ -1617,6 +1634,24 @@
    "vslo %0,%1,%2"
    [(set_attr "type" "vecperm")])
@@ -814439,8 +828613,8 @@ Index: gcc/config/rs6000/altivec.md
 -		    (match_operand:VM 2 "register_operand" "v,wo,wo")
 -		    (match_operand:V16QI 3 "register_operand" "v,wo,wo")]
 +  [(set (match_operand:VM 0 "register_operand" "=v,?wo")
-+	(unspec:VM [(match_operand:VM 1 "register_operand" "v,0")
-+		    (match_operand:VM 2 "register_operand" "v,wo")
++	(unspec:VM [(match_operand:VM 1 "register_operand" "v,wo")
++		    (match_operand:VM 2 "register_operand" "v,0")
 +		    (match_operand:V16QI 3 "register_operand" "v,wo")]
  		   UNSPEC_VPERM))]
    "TARGET_ALTIVEC"
@@ -814448,7 +828622,7 @@ Index: gcc/config/rs6000/altivec.md
     vperm %0,%1,%2,%3
 -   xxperm %x0,%x2,%x3
 -   xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3"
-+   xxperm %x0,%x2,%x3"
++   xxperm %x0,%x1,%x3"
    [(set_attr "type" "vecperm")
 -   (set_attr "length" "4,4,8")])
 +   (set_attr "length" "4")])
@@ -814459,8 +828633,8 @@ Index: gcc/config/rs6000/altivec.md
 -   	               (match_operand:V8HI 2 "register_operand" "v,wo,wo")
 -		       (match_operand:V16QI 3 "register_operand" "v,wo,wo")]
 +  [(set (match_operand:V16QI 0 "register_operand" "=v,?wo")
-+	(unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,0")
-+   	               (match_operand:V8HI 2 "register_operand" "v,wo")
++	(unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,wo")
++   	               (match_operand:V8HI 2 "register_operand" "v,0")
 +		       (match_operand:V16QI 3 "register_operand" "v,wo")]
  		   UNSPEC_VPERM))]
    "TARGET_ALTIVEC"
@@ -814468,7 +828642,7 @@ Index: gcc/config/rs6000/altivec.md
     vperm %0,%1,%2,%3
 -   xxperm %x0,%x2,%x3
 -   xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3"
-+   xxperm %x0,%x2,%x3"
++   xxperm %x0,%x1,%x3"
    [(set_attr "type" "vecperm")
 -   (set_attr "length" "4,4,8")])
 +   (set_attr "length" "4")])
@@ -814484,8 +828658,8 @@ Index: gcc/config/rs6000/altivec.md
 -		    (match_operand:VM 2 "register_operand" "v,wo,wo")
 -		    (match_operand:V16QI 3 "register_operand" "v,wo,wo")]
 +  [(set (match_operand:VM 0 "register_operand" "=v,?wo")
-+	(unspec:VM [(match_operand:VM 1 "register_operand" "v,0")
-+		    (match_operand:VM 2 "register_operand" "v,wo")
++	(unspec:VM [(match_operand:VM 1 "register_operand" "v,wo")
++		    (match_operand:VM 2 "register_operand" "v,0")
 +		    (match_operand:V16QI 3 "register_operand" "v,wo")]
  		   UNSPEC_VPERM_UNS))]
    "TARGET_ALTIVEC"
@@ -814493,7 +828667,7 @@ Index: gcc/config/rs6000/altivec.md
     vperm %0,%1,%2,%3
 -   xxperm %x0,%x2,%x3
 -   xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3"
-+   xxperm %x0,%x2,%x3"
++   xxperm %x0,%x1,%x3"
    [(set_attr "type" "vecperm")
 -   (set_attr "length" "4,4,8")])
 +   (set_attr "length" "4")])
@@ -814506,20 +828680,47 @@ Index: gcc/config/rs6000/altivec.md
  
 +(define_insn "*altivec_vpermr_<mode>_internal"
 +  [(set (match_operand:VM 0 "register_operand" "=v,?wo")
-+	(unspec:VM [(match_operand:VM 1 "register_operand" "v,0")
-+		    (match_operand:VM 2 "register_operand" "v,wo")
++	(unspec:VM [(match_operand:VM 1 "register_operand" "v,wo")
++		    (match_operand:VM 2 "register_operand" "v,0")
 +		    (match_operand:V16QI 3 "register_operand" "v,wo")]
 +		   UNSPEC_VPERMR))]
 +  "TARGET_P9_VECTOR"
 +  "@
-+   vpermr %0,%1,%2,%3
-+   xxpermr %x0,%x2,%x3"
++   vpermr %0,%2,%1,%3
++   xxpermr %x0,%x1,%x3"
 +  [(set_attr "type" "vecperm")
 +   (set_attr "length" "4")])
 +
  (define_insn "altivec_vrfip"		; ceil
    [(set (match_operand:V4SF 0 "register_operand" "=v")
          (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
+@@ -2238,7 +2283,7 @@
+ 		(match_dup 2)))]
+   "<VI_unit>"
+   "vcmpequ<VI_char>. %0,%1,%2"
+-  [(set_attr "type" "veccmp")])
++  [(set_attr "type" "veccmpfx")])
+ 
+ (define_insn "*altivec_vcmpgts<VI_char>_p"
+   [(set (reg:CC 74)
+@@ -2250,7 +2295,7 @@
+ 		(match_dup 2)))]
+   "<VI_unit>"
+   "vcmpgts<VI_char>. %0,%1,%2"
+-  [(set_attr "type" "veccmp")])
++  [(set_attr "type" "veccmpfx")])
+ 
+ (define_insn "*altivec_vcmpgtu<VI_char>_p"
+   [(set (reg:CC 74)
+@@ -2262,7 +2307,7 @@
+ 		 (match_dup 2)))]
+   "<VI_unit>"
+   "vcmpgtu<VI_char>. %0,%1,%2"
+-  [(set_attr "type" "veccmp")])
++  [(set_attr "type" "veccmpfx")])
+ 
+ (define_insn "*altivec_vcmpeqfp_p"
+   [(set (reg:CC 74)
 @@ -2690,20 +2735,28 @@
    DONE;
  })
@@ -814569,8 +828770,8 @@ Index: gcc/config/rs6000/altivec.md
 -		      (match_operand:V4SI 2 "register_operand" "v,wo,wo")
 -		      (match_operand:V16QI 3 "register_operand" "v,wo,wo")]
 +  [(set (match_operand:V4SI 0 "register_operand" "=v,?wo")
-+        (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,0")
-+		      (match_operand:V4SI 2 "register_operand" "v,wo")
++        (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,wo")
++		      (match_operand:V4SI 2 "register_operand" "v,0")
 +		      (match_operand:V16QI 3 "register_operand" "v,wo")]
                    UNSPEC_VPERMSI))]
    "TARGET_ALTIVEC"
@@ -814578,7 +828779,7 @@ Index: gcc/config/rs6000/altivec.md
     vperm %0,%1,%2,%3
 -   xxperm %x0,%x2,%x3
 -   xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3"
-+   xxperm %x0,%x2,%x3"
++   xxperm %x0,%x1,%x3"
    [(set_attr "type" "vecperm")
 -   (set_attr "length" "4,4,8")])
 +   (set_attr "length" "4")])
@@ -814589,8 +828790,8 @@ Index: gcc/config/rs6000/altivec.md
 -		      (match_operand:V8HI 2 "register_operand" "v,wo,wo")
 -		      (match_operand:V16QI 3 "register_operand" "v,wo,wo")]
 +  [(set (match_operand:V8HI 0 "register_operand" "=v,?wo")
-+        (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,0")
-+		      (match_operand:V8HI 2 "register_operand" "v,wo")
++        (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,wo")
++		      (match_operand:V8HI 2 "register_operand" "v,0")
 +		      (match_operand:V16QI 3 "register_operand" "v,wo")]
                    UNSPEC_VPERMHI))]
    "TARGET_ALTIVEC"
@@ -814598,7 +828799,7 @@ Index: gcc/config/rs6000/altivec.md
     vperm %0,%1,%2,%3
 -   xxperm %x0,%x2,%x3
 -   xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3"
-+   xxperm %x0,%x2,%x3"
++   xxperm %x0,%x1,%x3"
    [(set_attr "type" "vecperm")
 -   (set_attr "length" "4,4,8")])
 +   (set_attr "length" "4")])
@@ -814671,32 +828872,437 @@ Index: gcc/config/rs6000/altivec.md
 +(define_insn "darn_32"
 +  [(set (match_operand:SI 0 "register_operand" "=r")
 +        (unspec:SI [(const_int 0)] UNSPEC_DARN_32))]
-+  "TARGET_MODULO"
++  "TARGET_P9_MISC"
 +  "darn %0,0"
 +  [(set_attr "type" "integer")])
 +
 +(define_insn "darn_raw"
 +  [(set (match_operand:DI 0 "register_operand" "=r")
 +        (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))]
-+  "TARGET_MODULO && TARGET_64BIT"
++  "TARGET_P9_MISC && TARGET_64BIT"
 +  "darn %0,2"
 +  [(set_attr "type" "integer")])
 +
 +(define_insn "darn"
 +  [(set (match_operand:DI 0 "register_operand" "=r")
 +        (unspec:DI [(const_int 0)] UNSPEC_DARN))]
-+  "TARGET_MODULO && TARGET_64BIT"
++  "TARGET_P9_MISC && TARGET_64BIT"
 +  "darn %0,1"
 +  [(set_attr "type" "integer")])
 +
  (define_expand "bcd<bcd_add_sub>_<code>"
    [(parallel [(set (reg:CCFP 74)
  		   (compare:CCFP
+Index: gcc/config/rs6000/601.md
+===================================================================
+--- a/src/gcc/config/rs6000/601.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/601.md	(.../branches/gcc-6-branch)
+@@ -86,7 +86,7 @@
+   "(fpu_ppc601+iu_ppc601*2),nothing*2,bpu_ppc601")
+ 
+ (define_insn_reservation "ppc601-fp" 4
+-  (and (eq_attr "type" "fp")
++  (and (eq_attr "type" "fp,fpsimple")
+        (eq_attr "cpu" "ppc601"))
+   "fpu_ppc601")
+ 
+Index: gcc/config/rs6000/dfp.md
+===================================================================
+--- a/src/gcc/config/rs6000/dfp.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/dfp.md	(.../branches/gcc-6-branch)
+@@ -58,7 +58,7 @@
+ 	(float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))]
+   "TARGET_DFP"
+   "dctdp %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_expand "extendsdtd2"
+   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
+@@ -76,7 +76,7 @@
+ 	(float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "drsp %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_expand "negdd2"
+   [(set (match_operand:DD 0 "gpc_reg_operand" "")
+@@ -89,7 +89,7 @@
+ 	(neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
+   "TARGET_HARD_FLOAT && TARGET_FPRS"
+   "fneg %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "fpsimple")])
+ 
+ (define_expand "absdd2"
+   [(set (match_operand:DD 0 "gpc_reg_operand" "")
+@@ -102,7 +102,7 @@
+ 	(abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
+   "TARGET_HARD_FLOAT && TARGET_FPRS"
+   "fabs %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "fpsimple")])
+ 
+ (define_insn "*nabsdd2_fpr"
+   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
+@@ -109,7 +109,7 @@
+ 	(neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))]
+   "TARGET_HARD_FLOAT && TARGET_FPRS"
+   "fnabs %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "fpsimple")])
+ 
+ (define_expand "negtd2"
+   [(set (match_operand:TD 0 "gpc_reg_operand" "")
+@@ -124,7 +124,7 @@
+   "@
+    fneg %0,%1
+    fneg %0,%1\;fmr %L0,%L1"
+-  [(set_attr "type" "fp")
++  [(set_attr "type" "fpsimple")
+    (set_attr "length" "4,8")])
+ 
+ (define_expand "abstd2"
+@@ -140,7 +140,7 @@
+   "@
+    fabs %0,%1
+    fabs %0,%1\;fmr %L0,%L1"
+-  [(set_attr "type" "fp")
++  [(set_attr "type" "fpsimple")
+    (set_attr "length" "4,8")])
+ 
+ (define_insn "*nabstd2_fpr"
+@@ -150,7 +150,7 @@
+   "@
+    fnabs %0,%1
+    fnabs %0,%1\;fmr %L0,%L1"
+-  [(set_attr "type" "fp")
++  [(set_attr "type" "fpsimple")
+    (set_attr "length" "4,8")])
+ 
+ ;; Hardware support for decimal floating point operations.
+@@ -160,7 +160,7 @@
+ 	(float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dctqpq %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ ;; The result of drdpq is an even/odd register pair with the converted
+ ;; value in the even register and zero in the odd register.
+@@ -173,7 +173,7 @@
+    (clobber (match_scratch:TD 2 "=d"))]
+   "TARGET_DFP"
+   "drdpq %2,%1\;fmr %0,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "adddd3"
+   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
+@@ -181,7 +181,7 @@
+ 		 (match_operand:DD 2 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dadd %0,%1,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "addtd3"
+   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
+@@ -189,7 +189,7 @@
+ 		 (match_operand:TD 2 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "daddq %0,%1,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "subdd3"
+   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
+@@ -197,7 +197,7 @@
+ 		  (match_operand:DD 2 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dsub %0,%1,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "subtd3"
+   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
+@@ -205,7 +205,7 @@
+ 		  (match_operand:TD 2 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dsubq %0,%1,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "muldd3"
+   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
+@@ -213,7 +213,7 @@
+ 		 (match_operand:DD 2 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dmul %0,%1,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "multd3"
+   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
+@@ -221,7 +221,7 @@
+ 		 (match_operand:TD 2 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dmulq %0,%1,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "divdd3"
+   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
+@@ -229,7 +229,7 @@
+ 		(match_operand:DD 2 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "ddiv %0,%1,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "divtd3"
+   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
+@@ -237,7 +237,7 @@
+ 		(match_operand:TD 2 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "ddivq %0,%1,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "*cmpdd_internal1"
+   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+@@ -245,7 +245,7 @@
+ 		      (match_operand:DD 2 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dcmpu %0,%1,%2"
+-  [(set_attr "type" "fpcompare")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "*cmptd_internal1"
+   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+@@ -253,7 +253,7 @@
+ 		      (match_operand:TD 2 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dcmpuq %0,%1,%2"
+-  [(set_attr "type" "fpcompare")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "floatdidd2"
+   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
+@@ -260,7 +260,7 @@
+ 	(float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))]
+   "TARGET_DFP && TARGET_POPCNTD"
+   "dcffix %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "floatditd2"
+   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
+@@ -267,7 +267,7 @@
+ 	(float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dcffixq %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ ;; Convert a decimal64 to a decimal64 whose value is an integer.
+ ;; This is the first stage of converting it to an integer type.
+@@ -277,7 +277,7 @@
+ 	(fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "drintn. 0,%0,%1,1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ ;; Convert a decimal64 whose value is an integer to an actual integer.
+ ;; This is the second stage of converting decimal float to integer type.
+@@ -287,7 +287,7 @@
+ 	(fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dctfix %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ ;; Convert a decimal128 to a decimal128 whose value is an integer.
+ ;; This is the first stage of converting it to an integer type.
+@@ -297,7 +297,7 @@
+ 	(fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "drintnq. 0,%0,%1,1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ ;; Convert a decimal128 whose value is an integer to an actual integer.
+ ;; This is the second stage of converting decimal float to integer type.
+@@ -307,7 +307,7 @@
+ 	(fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))]
+   "TARGET_DFP"
+   "dctfixq %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ 

+ ;; Decimal builtin support
+@@ -318,8 +318,11 @@
+    UNSPEC_DXEX
+    UNSPEC_DIEX
+    UNSPEC_DSCLI
++   UNSPEC_DTSTSFI
+    UNSPEC_DSCRI])
+ 
++(define_code_iterator DFP_TEST [eq lt gt unordered])
++
+ (define_mode_iterator D64_D128 [DD TD])
+ 
+ (define_mode_attr dfp_suffix [(DD "")
+@@ -332,7 +335,7 @@
+ 			 UNSPEC_DDEDPD))]
+   "TARGET_DFP"
+   "ddedpd<dfp_suffix> %1,%0,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "dfp_denbcd_<mode>"
+   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+@@ -341,7 +344,7 @@
+ 			 UNSPEC_DENBCD))]
+   "TARGET_DFP"
+   "denbcd<dfp_suffix> %1,%0,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "dfp_dxex_<mode>"
+   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+@@ -349,7 +352,7 @@
+ 			 UNSPEC_DXEX))]
+   "TARGET_DFP"
+   "dxex<dfp_suffix> %0,%1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "dfp_diex_<mode>"
+   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+@@ -358,6 +361,42 @@
+ 			 UNSPEC_DXEX))]
+   "TARGET_DFP"
+   "diex<dfp_suffix> %0,%1,%2"
++  [(set_attr "type" "dfp")])
++
++(define_expand "dfptstsfi_<code>_<mode>"
++  [(set (match_dup 3)
++	(compare:CCFP
++         (unspec:D64_D128
++	  [(match_operand:SI 1 "const_int_operand" "n")
++	   (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
++	  UNSPEC_DTSTSFI)
++	 (match_dup 4)))
++   (set (match_operand:SI 0 "register_operand" "")
++   	(DFP_TEST:SI (match_dup 3)
++		     (const_int 0)))
++  ]
++  "TARGET_P9_MISC"
++{
++  operands[3] = gen_reg_rtx (CCFPmode);
++  operands[4] = const0_rtx;
++})
++
++(define_insn "*dfp_sgnfcnc_<mode>"
++  [(set (match_operand:CCFP 0 "" "=y")
++        (compare:CCFP
++	 (unspec:D64_D128 [(match_operand:SI 1 "const_int_operand" "n")
++	 	           (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
++          UNSPEC_DTSTSFI)
++	 (match_operand:SI 3 "zero_constant" "j")))]
++  "TARGET_P9_MISC"
++{
++  /* If immediate operand is greater than 63, it will behave as if
++     the value had been 63.  The code generator does not support
++     immediate operand values greater than 63.  */
++  if (!(IN_RANGE (INTVAL (operands[1]), 0, 63)))
++    operands[1] = GEN_INT (63);
++  return "dtstsfi<dfp_suffix> %0,%1,%2";
++}
+   [(set_attr "type" "fp")])
+ 
+ (define_insn "dfp_dscli_<mode>"
+@@ -367,7 +406,7 @@
+ 			 UNSPEC_DSCLI))]
+   "TARGET_DFP"
+   "dscli<dfp_suffix> %0,%1,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+ 
+ (define_insn "dfp_dscri_<mode>"
+   [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+@@ -376,4 +415,4 @@
+ 			 UNSPEC_DSCRI))]
+   "TARGET_DFP"
+   "dscri<dfp_suffix> %0,%1,%2"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "dfp")])
+Index: gcc/config/rs6000/crypto.md
+===================================================================
+--- a/src/gcc/config/rs6000/crypto.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/crypto.md	(.../branches/gcc-6-branch)
+@@ -107,4 +107,4 @@
+ 			UNSPEC_VSHASIGMA))]
+   "TARGET_CRYPTO"
+   "vshasigma<CR_char> %0,%1,%2,%3"
+-  [(set_attr "type" "crypto")])
++  [(set_attr "type" "vecsimple")])
+Index: gcc/config/rs6000/power5.md
+===================================================================
+--- a/src/gcc/config/rs6000/power5.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/power5.md	(.../branches/gcc-6-branch)
+@@ -322,7 +322,7 @@
+ 
+ ; Basic FP latency is 6 cycles
+ (define_insn_reservation "power5-fp" 6
+-  (and (eq_attr "type" "fp,dmul")
++  (and (eq_attr "type" "fp,fpsimple,dmul")
+        (eq_attr "cpu" "power5"))
+   "fpq_power5")
+ 
 Index: gcc/config/rs6000/rs6000.md
 ===================================================================
 --- a/src/gcc/config/rs6000/rs6000.md	(.../tags/gcc_6_1_0_release)
 +++ b/src/gcc/config/rs6000/rs6000.md	(.../branches/gcc-6-branch)
-@@ -489,6 +489,10 @@
+@@ -147,6 +147,8 @@
+    UNSPEC_ROUND_TO_ODD
+    UNSPEC_IEEE128_MOVE
+    UNSPEC_IEEE128_CONVERT
++   UNSPEC_SIGNBIT
++   UNSPEC_DOLOOP
+   ])
+ 
+ ;;
+@@ -183,12 +185,13 @@
+    brinc,
+    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
+    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
+-   htm"
++   veclogical,veccmpfx,vecexts,vecmove,
++   htm,htmsimple,dfp"
+   (const_string "integer"))
+ 
+ ;; What data size does this instruction work on?
+-;; This is used for insert, mul.
+-(define_attr "size" "8,16,32,64" (const_string "32"))
++;; This is used for insert, mul and others as necessary.
++(define_attr "size" "8,16,32,64,128" (const_string "32"))
+ 
+ ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
+ ;; This is used for add, logical, shift, exts, mul.
+@@ -298,6 +301,7 @@
+ (include "power6.md")
+ (include "power7.md")
+ (include "power8.md")
++(include "power9.md")
+ (include "cell.md")
+ (include "xfpu.md")
+ (include "a2.md")
+@@ -489,6 +493,10 @@
  ; Iterator for just SF/DF
  (define_mode_iterator SFDF [SF DF])
  
@@ -814707,7 +829313,21 @@ Index: gcc/config/rs6000/rs6000.md
  ; Iterator for 128-bit floating point that uses the IBM double-double format
  (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
  			      (TF "FLOAT128_IBM_P (TFmode)")])
-@@ -577,7 +581,9 @@
+@@ -502,6 +510,13 @@
+ 				(IF "TARGET_FLOAT128")
+ 				(TF "TARGET_LONG_DOUBLE_128")])
+ 
++; Iterator for signbit on 64-bit machines with direct move
++(define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
++			       (TF "FLOAT128_VECTOR_P (TFmode)")])
++
++(define_mode_attr Fsignbit	[(KF "wa")
++				 (TF "wa")])
++
+ ; SF/DF suffix for traditional floating instructions
+ (define_mode_attr Ftrad		[(SF "s") (DF "")])
+ 
+@@ -577,7 +592,9 @@
  		      (V16QI "b")
  		      (V8HI  "h")
  		      (V4SI  "w")
@@ -814718,7 +829338,7 @@ Index: gcc/config/rs6000/rs6000.md
  
  ;; How many bits in this mode?
  (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
-@@ -698,6 +704,15 @@
+@@ -698,6 +715,15 @@
  (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
  			      SF SD SI DF DD DI TI PTI KF IF TF])
  
@@ -814734,7 +829354,7 @@ Index: gcc/config/rs6000/rs6000.md
  

  ;; Start with fixed-point load and store insns.  Here we put only the more
  ;; complex forms.  Basic data transfer is done later.
-@@ -4044,7 +4059,7 @@
+@@ -4044,7 +4070,7 @@
  
    if (REGNO (cr) == CR0_REGNO)
      {
@@ -814743,7 +829363,121 @@ Index: gcc/config/rs6000/rs6000.md
        DONE;
      }
  
-@@ -4599,74 +4614,45 @@
+@@ -4305,7 +4331,7 @@
+   "@
+    fabs %0,%1
+    xsabsdp %x0,%x1"
+-  [(set_attr "type" "fp")
++  [(set_attr "type" "fpsimple")
+    (set_attr "fp_type" "fp_addsub_<Fs>")])
+ 
+ (define_insn "*nabs<mode>2_fpr"
+@@ -4317,7 +4343,7 @@
+   "@
+    fnabs %0,%1
+    xsnabsdp %x0,%x1"
+-  [(set_attr "type" "fp")
++  [(set_attr "type" "fpsimple")
+    (set_attr "fp_type" "fp_addsub_<Fs>")])
+ 
+ (define_expand "neg<mode>2"
+@@ -4333,7 +4359,7 @@
+   "@
+    fneg %0,%1
+    xsnegdp %x0,%x1"
+-  [(set_attr "type" "fp")
++  [(set_attr "type" "fpsimple")
+    (set_attr "fp_type" "fp_addsub_<Fs>")])
+ 
+ (define_expand "add<mode>3"
+@@ -4494,7 +4520,7 @@
+   emit_note (NOTE_INSN_DELETED);
+   DONE;
+ }
+-  [(set_attr "type" "fp,fp,fpload,fp,fp,fpload,fpload")])
++  [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
+ 
+ (define_expand "truncdfsf2"
+   [(set (match_operand:SF 0 "gpc_reg_operand" "")
+@@ -4516,7 +4542,7 @@
+ ;; when little-endian.
+ (define_expand "signbit<mode>2"
+   [(set (match_dup 2)
+-	(float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "")))
++	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
+    (set (match_dup 3)
+    	(subreg:DI (match_dup 2) 0))
+    (set (match_dup 4)
+@@ -4524,8 +4550,20 @@
+    (set (match_operand:SI 0 "gpc_reg_operand" "")
+   	(match_dup 6))]
+   "TARGET_HARD_FLOAT
+-   && (TARGET_FPRS || TARGET_E500_DOUBLE)"
++   && (TARGET_FPRS || TARGET_E500_DOUBLE)
++   && (!FLOAT128_IEEE_P (<MODE>mode)
++       || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
+ {
++  if (FLOAT128_IEEE_P (<MODE>mode))
++    {
++      if (<MODE>mode == KFmode)
++	emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
++      else if (<MODE>mode == TFmode)
++	emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
++      else
++	gcc_unreachable ();
++      DONE;
++    }
+   operands[2] = gen_reg_rtx (DFmode);
+   operands[3] = gen_reg_rtx (DImode);
+   if (TARGET_POWERPC64)
+@@ -4573,6 +4611,37 @@
+    operands[5] = CONST0_RTX (<MODE>mode);
+   })
+ 
++;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
++;; and load.
++(define_insn_and_split "signbit<mode>2_dm"
++  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
++	(unspec:SI
++	 [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,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,12")
++  (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 "signbit<mode>2_dm2"
++  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
++	(unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
++		    (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 "copysign<mode>3_fcpsgn"
+@@ -4584,7 +4653,7 @@
+   "@
+    fcpsgn %0,%2,%1
+    xscpsgndp %x0,%x2,%x1"
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "fpsimple")])
+ 
+ ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
+ ;; fsel instruction and some auxiliary computations.  Then we just have a
+@@ -4599,74 +4668,45 @@
  ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
  ;; to allow either DF/SF to use only traditional registers.
  
@@ -814843,7 +829577,7 @@ Index: gcc/config/rs6000/rs6000.md
  (define_expand "mov<mode>cc"
     [(set (match_operand:GPR 0 "gpc_reg_operand" "")
  	 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
-@@ -4749,12 +4735,13 @@
+@@ -4749,12 +4789,13 @@
    [(set_attr "type" "isel")
     (set_attr "length" "4")])
  
@@ -814863,7 +829597,7 @@ Index: gcc/config/rs6000/rs6000.md
    "
  {
    if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
-@@ -4763,76 +4750,70 @@
+@@ -4763,76 +4804,70 @@
      FAIL;
  }")
  
@@ -814973,7 +829707,7 @@ Index: gcc/config/rs6000/rs6000.md
 +			   (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
 +  "TARGET_P9_MINMAX"
 +  "xxsel %x0,%x1,%x3,%x4"
-+  [(set_attr "type" "vecperm")])
++  [(set_attr "type" "vecmove")])
  
 -(define_insn "*fseldfdf4"
 -  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
@@ -814997,7 +829731,254 @@ Index: gcc/config/rs6000/rs6000.md
  

  ;; Conversions to and from floating-point.
  
-@@ -12563,8 +12544,10 @@
+@@ -5942,7 +5977,7 @@
+   [(set (attr "type")
+       (if_then_else
+ 	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
+-	(const_string "vecsimple")
++	(const_string "veclogical")
+ 	(const_string "integer")))
+    (set (attr "length")
+       (if_then_else
+@@ -5978,7 +6013,7 @@
+   [(set (attr "type")
+       (if_then_else
+ 	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
+-	(const_string "vecsimple")
++	(const_string "veclogical")
+ 	(const_string "integer")))
+    (set (attr "length")
+       (if_then_else
+@@ -6016,7 +6051,7 @@
+   [(set (attr "type")
+       (if_then_else
+ 	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
+-	(const_string "vecsimple")
++	(const_string "veclogical")
+ 	(const_string "integer")))
+    (set (attr "length")
+       (if_then_else
+@@ -6076,7 +6111,7 @@
+   [(set (attr "type")
+       (if_then_else
+ 	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
+-	(const_string "vecsimple")
++	(const_string "veclogical")
+ 	(const_string "integer")))
+    (set (attr "length")
+       (if_then_else
+@@ -6134,7 +6169,7 @@
+   [(set (attr "type")
+       (if_then_else
+ 	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
+-	(const_string "vecsimple")
++	(const_string "veclogical")
+ 	(const_string "integer")))
+    (set (attr "length")
+       (if_then_else
+@@ -6190,7 +6225,7 @@
+   [(set (attr "type")
+       (if_then_else
+ 	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
+-	(const_string "vecsimple")
++	(const_string "veclogical")
+ 	(const_string "integer")))
+    (set (attr "length")
+       (if_then_else
+@@ -6505,7 +6540,7 @@
+    mt%0 %1
+    mf%1 %0
+    nop"
+-  [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mffgpr,mftgpr,mtjmpr,mfjmpr,*")
++  [(set_attr "type" "*,load,store,fpsimple,fpsimple,veclogical,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mffgpr,mftgpr,mtjmpr,mfjmpr,*")
+    (set_attr "length" "4")])
+ 
+ (define_insn "*mov<mode>_softfloat"
+@@ -6640,7 +6675,8 @@
+    #
+    #
+    #"
+-  [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,two,store,load,two")
++  [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
++   (set_attr "size" "64")
+    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
+ 
+ (define_insn "*mov<mode>_softfloat32"
+@@ -6685,7 +6721,8 @@
+    mffgpr %0,%1
+    mfvsrd %0,%x1
+    mtvsrd %x0,%1"
+-  [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
++  [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
++   (set_attr "size" "64")
+    (set_attr "length" "4")])
+ 
+ (define_insn "*mov<mode>_softfloat64"
+@@ -6896,7 +6933,7 @@
+   emit_note (NOTE_INSN_DELETED);
+   DONE;
+ }
+-  [(set_attr "type" "fp")])
++  [(set_attr "type" "fpsimple")])
+ 
+ (define_insn "trunc<mode>df2_internal2"
+   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+@@ -7129,7 +7166,7 @@
+   else
+     return \"fneg %0,%1\;fneg %L0,%L1\";
+ }"
+-  [(set_attr "type" "fp")
++  [(set_attr "type" "fpsimple")
+    (set_attr "length" "8")])
+ 
+ (define_expand "abs<mode>2"
+@@ -7264,7 +7301,7 @@
+    (use (match_operand:V16QI 2 "register_operand" "v"))]
+   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
+   "xxlxor %x0,%x1,%x2"
+-  [(set_attr "type" "vecsimple")])
++  [(set_attr "type" "veclogical")])
+ 
+ ;; IEEE 128-bit absolute value
+ (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
+@@ -7293,7 +7330,7 @@
+    (use (match_operand:V16QI 2 "register_operand" "v"))]
+   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
+   "xxlandc %x0,%x1,%x2"
+-  [(set_attr "type" "vecsimple")])
++  [(set_attr "type" "veclogical")])
+ 
+ ;; IEEE 128-bit negative absolute value
+ (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
+@@ -7326,7 +7363,7 @@
+    (use (match_operand:V16QI 2 "register_operand" "v"))]
+   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
+   "xxlor %x0,%x1,%x2"
+-  [(set_attr "type" "vecsimple")])
++  [(set_attr "type" "veclogical")])
+ 
+ ;; Float128 conversion functions.  These expand to library function calls.
+ ;; We use expand to convert from IBM double double to IEEE 128-bit
+@@ -7482,7 +7519,7 @@
+ 			 UNSPEC_P8V_FMRGOW))]
+   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+   "fmrgow %0,%1,%2"
+-  [(set_attr "type" "vecperm")])
++  [(set_attr "type" "fpsimple")])
+ 
+ (define_insn "p8_mtvsrwz"
+   [(set (match_operand:DF 0 "register_operand" "=d")
+@@ -7705,7 +7742,8 @@
+    lfd%U1%X1 %0,%1
+    fmr %0,%1
+    #"
+-  [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
++  [(set_attr "type" "store,load,*,fpstore,fpload,fpsimple,*")
++   (set_attr "size" "64")])
+ 
+ (define_split
+   [(set (match_operand:DI 0 "gpc_reg_operand" "")
+@@ -7759,7 +7797,8 @@
+    mfvsrd %0,%x1
+    mtvsrd %x0,%1
+    xxlxor %x0,%x0,%x0"
+-  [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
++  [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fpsimple,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,veclogical")
++   (set_attr "size" "64")
+    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
+ 
+ ; Some DImode loads are best done as a load of -1 followed by a mask
+@@ -8767,7 +8806,8 @@
+    lfdu %3,%2(%0)"
+   [(set_attr "type" "fpload")
+    (set_attr "update" "yes")
+-   (set_attr "indexed" "yes,no")])
++   (set_attr "indexed" "yes,no")
++   (set_attr "size" "64")])
+ 
+ (define_insn "*movdf_update2"
+   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
+@@ -11902,6 +11942,7 @@
+ 	      (set (match_dup 0)
+ 		   (plus:P (match_dup 0)
+ 			    (const_int -1)))
++	      (unspec [(const_int 0)] UNSPEC_DOLOOP)
+ 	      (clobber (match_scratch:CC 2 ""))
+ 	      (clobber (match_scratch:P 3 ""))])]
+   ""
+@@ -11912,6 +11953,7 @@
+ ;; JUMP_INSNs.
+ ;; For the length attribute to be calculated correctly, the
+ ;; label MUST be operand 0.
++;; The UNSPEC is present to prevent combine creating this pattern.
+ 
+ (define_insn "*ctr<mode>_internal1"
+   [(set (pc)
+@@ -11919,9 +11961,10 @@
+ 			  (const_int 1))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))
+-   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
++   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
+ 	(plus:P (match_dup 1)
+ 		 (const_int -1)))
++   (unspec [(const_int 0)] UNSPEC_DOLOOP)
+    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
+   ""
+@@ -11943,9 +11986,10 @@
+ 			  (const_int 1))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))
+-   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
++   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
+ 	(plus:P (match_dup 1)
+ 		 (const_int -1)))
++   (unspec [(const_int 0)] UNSPEC_DOLOOP)
+    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
+   ""
+@@ -11969,9 +12013,10 @@
+ 			  (const_int 1))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))
+-   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
++   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
+ 	(plus:P (match_dup 1)
+ 		 (const_int -1)))
++   (unspec [(const_int 0)] UNSPEC_DOLOOP)
+    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
+   ""
+@@ -11993,9 +12038,10 @@
+ 			  (const_int 1))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))
+-   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l")
++   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
+ 	(plus:P (match_dup 1)
+ 		 (const_int -1)))
++   (unspec [(const_int 0)] UNSPEC_DOLOOP)
+    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
+   ""
+@@ -12022,6 +12068,7 @@
+ 		      (match_operand 6 "" "")))
+    (set (match_operand:P 0 "int_reg_operand" "")
+ 	(plus:P (match_dup 1) (const_int -1)))
++   (unspec [(const_int 0)] UNSPEC_DOLOOP)
+    (clobber (match_scratch:CC 3 ""))
+    (clobber (match_scratch:P 4 ""))]
+   "reload_completed"
+@@ -12047,6 +12094,7 @@
+ 		      (match_operand 6 "" "")))
+    (set (match_operand:P 0 "nonimmediate_operand" "")
+ 	(plus:P (match_dup 1) (const_int -1)))
++   (unspec [(const_int 0)] UNSPEC_DOLOOP)
+    (clobber (match_scratch:CC 3 ""))
+    (clobber (match_scratch:P 4 ""))]
+   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
+@@ -12563,8 +12611,10 @@
     (set_attr "indexed" "no")])
  
  ;; A return instruction which the middle-end doesn't see.
@@ -815009,9 +829990,62 @@ Index: gcc/config/rs6000/rs6000.md
    ""
    "blr"
    [(set_attr "type" "jmpreg")])
-@@ -13242,7 +13225,25 @@
+@@ -13166,7 +13216,7 @@
+   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
+   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
+ }
+-  [(set_attr "type" "fp,fp")
++  [(set_attr "type" "fpsimple,fp")
+    (set_attr "length" "4,8")])
+ 
+ (define_insn "unpack<mode>"
+@@ -13205,7 +13255,8 @@
+ 	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xsaddqp %0,%1,%2"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ (define_insn "sub<mode>3"
+   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+@@ -13214,7 +13265,8 @@
+ 	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xssubqp %0,%1,%2"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ (define_insn "mul<mode>3"
+   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+@@ -13223,7 +13275,8 @@
+ 	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xsmulqp %0,%1,%2"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ (define_insn "div<mode>3"
+   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+@@ -13232,7 +13285,8 @@
+ 	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xsdivqp %0,%1,%2"
+-  [(set_attr "type" "vecdiv")])
++  [(set_attr "type" "vecdiv")
++   (set_attr "size" "128")])
+ 
+ (define_insn "sqrt<mode>2"
+   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+@@ -13240,9 +13294,28 @@
+ 	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
     "xssqrtqp %0,%1"
-   [(set_attr "type" "vecdiv")])
+-  [(set_attr "type" "vecdiv")])
++  [(set_attr "type" "vecdiv")
++   (set_attr "size" "128")])
  
 -(define_insn "copysign<mode>3"
 +(define_expand "copysign<mode>3"
@@ -815036,9 +830070,13 @@ Index: gcc/config/rs6000/rs6000.md
    [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
  	(unspec:IEEE128
  	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
-@@ -13252,6 +13253,18 @@
+@@ -13250,8 +13323,21 @@
+ 	 UNSPEC_COPYSIGN))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
     "xscpsgnqp %0,%2,%1"
-   [(set_attr "type" "vecsimple")])
+-  [(set_attr "type" "vecsimple")])
++  [(set_attr "type" "vecmove")
++   (set_attr "size" "128")])
  
 +(define_insn "copysign<mode>3_soft"
 +  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
@@ -815055,6 +830093,213 @@ Index: gcc/config/rs6000/rs6000.md
  (define_insn "neg<mode>2_hw"
    [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
  	(neg:IEEE128
+@@ -13258,7 +13344,8 @@
+ 	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xsnegqp %0,%1"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecmove")
++   (set_attr "size" "128")])
+ 
+ 
+ (define_insn "abs<mode>2_hw"
+@@ -13267,7 +13354,8 @@
+ 	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xsabsqp %0,%1"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecmove")
++   (set_attr "size" "128")])
+ 
+ 
+ (define_insn "*nabs<mode>2_hw"
+@@ -13277,7 +13365,8 @@
+ 	  (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xsnabsqp %0,%1"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecmove")
++   (set_attr "size" "128")])
+ 
+ ;; Initially don't worry about doing fusion
+ (define_insn "*fma<mode>4_hw"
+@@ -13288,7 +13377,8 @@
+ 	 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xsmaddqp %0,%1,%2"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ (define_insn "*fms<mode>4_hw"
+   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+@@ -13299,7 +13389,8 @@
+ 	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xsmsubqp %0,%1,%2"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ (define_insn "*nfma<mode>4_hw"
+   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+@@ -13310,7 +13401,8 @@
+ 	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xsnmaddqp %0,%1,%2"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ (define_insn "*nfms<mode>4_hw"
+   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+@@ -13322,7 +13414,8 @@
+ 	   (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xsnmsubqp %0,%1,%2"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
+   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+@@ -13330,7 +13423,8 @@
+ 	 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
+   "xscvdpqp %0,%1"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
+ ;; point is a simple copy.
+@@ -13347,7 +13441,7 @@
+   emit_note (NOTE_INSN_DELETED);
+   DONE;
+ }
+-  [(set_attr "type" "*,vecsimple")
++  [(set_attr "type" "*,veclogical")
+    (set_attr "length" "0,4")])
+ 
+ (define_insn_and_split "trunctfkf2"
+@@ -13363,7 +13457,7 @@
+   emit_note (NOTE_INSN_DELETED);
+   DONE;
+ }
+-  [(set_attr "type" "*,vecsimple")
++  [(set_attr "type" "*,veclogical")
+    (set_attr "length" "0,4")])
+ 
+ (define_insn "trunc<mode>df2_hw"
+@@ -13372,7 +13466,8 @@
+ 	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xscvqpdp %0,%1"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
+ ;; the KFmode -> DFmode conversion using round to odd rather than the normal
+@@ -13469,7 +13564,8 @@
+ 	 UNSPEC_IEEE128_CONVERT))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xscvqp<su>wz %0,%1"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ (define_insn "*xscvqp<su>dz_<mode>"
+   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+@@ -13479,7 +13575,8 @@
+ 	 UNSPEC_IEEE128_CONVERT))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xscvqp<su>dz %0,%1"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ (define_insn "*xscv<su>dqp_<mode>"
+   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+@@ -13488,7 +13585,8 @@
+ 		    UNSPEC_IEEE128_CONVERT)))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xscv<su>dqp %0,%1"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ (define_insn "*ieee128_mfvsrd_64bit"
+   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
+@@ -13499,7 +13597,7 @@
+    mfvsrd %0,%x1
+    stxsdx %x1,%y0
+    xxlor %x0,%x1,%x1"
+-  [(set_attr "type" "mftgpr,fpstore,vecsimple")])
++  [(set_attr "type" "mftgpr,fpstore,veclogical")])
+ 
+ 
+ (define_insn "*ieee128_mfvsrd_32bit"
+@@ -13510,7 +13608,7 @@
+   "@
+    stxsdx %x1,%y0
+    xxlor %x0,%x1,%x1"
+-  [(set_attr "type" "fpstore,vecsimple")])
++  [(set_attr "type" "fpstore,veclogical")])
+ 
+ (define_insn "*ieee128_mfvsrwz"
+   [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
+@@ -13546,7 +13644,7 @@
+    mtvsrd %x0,%1
+    lxsdx %x0,%y1
+    xxlor %x0,%x1,%x1"
+-  [(set_attr "type" "mffgpr,fpload,vecsimple")])
++  [(set_attr "type" "mffgpr,fpload,veclogical")])
+ 
+ (define_insn "*ieee128_mtvsrd_32bit"
+   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
+@@ -13556,7 +13654,7 @@
+   "@
+    lxsdx %x0,%y1
+    xxlor %x0,%x1,%x1"
+-  [(set_attr "type" "fpload,vecsimple")])
++  [(set_attr "type" "fpload,veclogical")])
+ 
+ ;; IEEE 128-bit instructions with round to odd semantics
+ (define_insn "*trunc<mode>df2_odd"
+@@ -13565,7 +13663,8 @@
+ 		   UNSPEC_ROUND_TO_ODD))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+   "xscvqpdpo %0,%1"
+-  [(set_attr "type" "vecfloat")])
++  [(set_attr "type" "vecfloat")
++   (set_attr "size" "128")])
+ 
+ ;; IEEE 128-bit comparisons
+ (define_insn "*cmp<mode>_hw"
+@@ -13574,7 +13673,8 @@
+ 		      (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
+   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+    "xscmpuqp %0,%1,%2"
+-  [(set_attr "type" "fpcompare")])
++  [(set_attr "type" "veccmp")
++   (set_attr "size" "128")])
+ 
+ 

+ 
+Index: gcc/config/rs6000/a2.md
+===================================================================
+--- a/src/gcc/config/rs6000/a2.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/rs6000/a2.md	(.../branches/gcc-6-branch)
+@@ -81,7 +81,7 @@
+ 
+ ;; D.8.1
+ (define_insn_reservation "ppca2-fp" 6
+-  (and (eq_attr "type" "fp")     	   ;; Ignore fpsimple insn types (SPE only).
++  (and (eq_attr "type" "fp,fpsimple")
+        (eq_attr "cpu" "ppca2"))
+   "axu")
+ 
 Index: gcc/config/rs6000/altivec.h
 ===================================================================
 --- a/src/gcc/config/rs6000/altivec.h	(.../tags/gcc_6_1_0_release)
@@ -815296,6 +830541,318 @@ Index: gcc/config/arm/freebsd.h
  
  #undef MAX_SYNC_LIBFUNC_SIZE
  #define MAX_SYNC_LIBFUNC_SIZE 4 /* UNITS_PER_WORD not defined yet.  */
+Index: gcc/config/pa/pa.md
+===================================================================
+--- a/src/gcc/config/pa/pa.md	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/pa/pa.md	(.../branches/gcc-6-branch)
+@@ -8216,6 +8216,170 @@
+ 	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
+ 	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
+ 
++/* Expand special pc-relative call to _mcount.  */
++
++(define_expand "call_mcount"
++  [(parallel [(call (match_operand:SI 0 "" "")
++		    (match_operand 1 "" ""))
++	      (set (reg:SI 25)
++		   (plus:SI (reg:SI 2)
++			    (minus:SI (match_operand 2 "" "")
++				      (plus:SI (pc) (const_int 4)))))
++	      (clobber (reg:SI 2))])]
++  "!TARGET_PORTABLE_RUNTIME"
++  "
++{
++  rtx op = XEXP (operands[0], 0);
++  rtx nb = operands[1];
++  rtx lab = operands[2];
++
++  if (TARGET_64BIT)
++    {
++      rtx r4 = gen_rtx_REG (word_mode, 4);
++      emit_move_insn (arg_pointer_rtx,
++		      gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
++				    GEN_INT (64)));
++      emit_call_insn (gen_call_mcount_64bit (op, nb, lab, r4));
++    }
++  else
++    {
++      if (flag_pic)
++	{
++	  rtx r4 = gen_rtx_REG (word_mode, 4);
++	  emit_call_insn (gen_call_mcount_pic (op, nb, lab, r4));
++	}
++      else
++	emit_call_insn (gen_call_mcount_nonpic (op, nb, lab));
++    }
++
++  DONE;
++}")
++
++(define_insn "call_mcount_nonpic"
++  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
++	 (match_operand 1 "" "i"))
++   (set (reg:SI 25)
++	(plus:SI (reg:SI 2)
++		 (minus:SI (match_operand 2 "" "")
++			   (plus:SI (pc) (const_int 4)))))
++   (clobber (reg:SI 2))]
++  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
++  "*
++{
++  pa_output_arg_descriptor (insn);
++  return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
++}"
++  [(set_attr "type" "multi")
++   (set_attr "length" "8")])
++
++(define_insn "call_mcount_pic"
++  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
++	 (match_operand 1 "" "i"))
++   (set (reg:SI 25)
++	(plus:SI (reg:SI 2)
++		 (minus:SI (match_operand 2 "" "")
++			   (plus:SI (pc) (const_int 4)))))
++   (clobber (reg:SI 2))
++   (clobber (match_operand 3))
++   (use (reg:SI 19))]
++  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
++  "#")
++
++(define_split
++  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
++		    (match_operand 1 "" ""))
++	      (set (reg:SI 25)
++		   (plus:SI (reg:SI 2)
++			    (minus:SI (match_operand 2 "" "")
++				      (plus:SI (pc) (const_int 4)))))
++	      (clobber (reg:SI 2))
++	      (clobber (match_operand 3))
++	      (use (reg:SI 19))])]
++  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
++  [(set (match_dup 3) (reg:SI 19))
++   (parallel [(call (mem:SI (match_dup 0))
++		    (match_dup 1))
++	      (set (reg:SI 25)
++		   (plus:SI (reg:SI 2)
++			    (minus:SI (match_dup 2)
++				      (plus:SI (pc) (const_int 4)))))
++	      (clobber (reg:SI 2))
++	      (use (reg:SI 19))])
++   (set (reg:SI 19) (match_dup 3))]
++  "")
++
++(define_insn "*call_mcount_pic_post_reload"
++  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
++	 (match_operand 1 "" "i"))
++   (set (reg:SI 25)
++	(plus:SI (reg:SI 2)
++		 (minus:SI (match_operand 2 "" "")
++			   (plus:SI (pc) (const_int 4)))))
++   (clobber (reg:SI 2))
++   (use (reg:SI 19))]
++  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
++  "*
++{
++  pa_output_arg_descriptor (insn);
++  return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
++}"
++  [(set_attr "type" "multi")
++   (set_attr "length" "8")])
++
++(define_insn "call_mcount_64bit"
++  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
++	 (match_operand 1 "" "i"))
++   (set (reg:SI 25)
++	(plus:SI (reg:SI 2)
++		 (minus:SI (match_operand 2 "" "")
++			   (plus:SI (pc) (const_int 4)))))
++   (clobber (reg:DI 2))
++   (clobber (match_operand 3))
++   (use (reg:DI 27))
++   (use (reg:DI 29))]
++  "TARGET_64BIT"
++  "#")
++
++(define_split
++  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
++		    (match_operand 1 "" ""))
++	      (set (reg:SI 25)
++		   (plus:SI (reg:SI 2)
++			    (minus:SI (match_operand 2 "" "")
++				      (plus:SI (pc) (const_int 4)))))
++	      (clobber (reg:DI 2))
++	      (clobber (match_operand 3))
++	      (use (reg:DI 27))
++	      (use (reg:DI 29))])]
++  "TARGET_64BIT && reload_completed"
++  [(set (match_dup 3) (reg:DI 27))
++   (parallel [(call (mem:SI (match_dup 0))
++		    (match_dup 1))
++	      (set (reg:SI 25)
++		   (plus:SI (reg:SI 2)
++			    (minus:SI (match_dup 2)
++				      (plus:SI (pc) (const_int 4)))))
++	      (clobber (reg:DI 2))
++	      (use (reg:DI 27))
++	      (use (reg:DI 29))])
++   (set (reg:DI 27) (match_dup 3))]
++  "")
++
++(define_insn "*call_mcount_64bit_post_reload"
++  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
++	 (match_operand 1 "" "i"))
++   (set (reg:SI 25)
++	(plus:SI (reg:SI 2)
++		 (minus:SI (match_operand 2 "" "")
++			   (plus:SI (pc) (const_int 4)))))
++   (clobber (reg:DI 2))
++   (use (reg:DI 27))
++   (use (reg:DI 29))]
++  "TARGET_64BIT"
++  "{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25"
++  [(set_attr "type" "multi")
++   (set_attr "length" "8")])
++
+ ;; Call subroutine returning any type.
+ 
+ (define_expand "untyped_call"
+Index: gcc/config/pa/pa.c
+===================================================================
+--- a/src/gcc/config/pa/pa.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/config/pa/pa.c	(.../branches/gcc-6-branch)
+@@ -4541,64 +4541,79 @@
+      lcla2 and load_offset_label_address insn patterns.  */
+   rtx reg = gen_reg_rtx (SImode);
+   rtx_code_label *label_rtx = gen_label_rtx ();
+-  rtx begin_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_insn *call_insn;
+   char begin_label_name[16];
++  bool use_mcount_pcrel_call;
+ 
++  /* 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.  */
++  if (!TARGET_PORTABLE_RUNTIME
++      && !TARGET_LONG_CALLS
++      && (TARGET_SOM || flag_function_sections))
++    use_mcount_pcrel_call = TRUE;
++  else
++    use_mcount_pcrel_call = FALSE;
++
+   ASM_GENERATE_INTERNAL_LABEL (begin_label_name, FUNC_BEGIN_PROLOG_LABEL,
+ 			       label_no);
+   begin_label_rtx = gen_rtx_SYMBOL_REF (SImode, ggc_strdup (begin_label_name));
+ 
+-  if (TARGET_64BIT)
+-    emit_move_insn (arg_pointer_rtx,
+-		    gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
+-				  GEN_INT (64)));
+-
+   emit_move_insn (gen_rtx_REG (word_mode, 26), gen_rtx_REG (word_mode, 2));
+ 
+-  /* The address of the function is loaded into %r25 with an instruction-
+-     relative sequence that avoids the use of relocations.  The sequence
+-     is split so that the load_offset_label_address instruction can
+-     occupy the delay slot of the call to _mcount.  */
+-  if (TARGET_PA_20)
+-    emit_insn (gen_lcla2 (reg, label_rtx));
+-  else
+-    emit_insn (gen_lcla1 (reg, label_rtx));
++  if (!use_mcount_pcrel_call)
++    {
++      /* The address of the function is loaded into %r25 with an instruction-
++	 relative sequence that avoids the use of relocations.  The sequence
++	 is split so that the load_offset_label_address instruction can
++	 occupy the delay slot of the call to _mcount.  */
++      if (TARGET_PA_20)
++	emit_insn (gen_lcla2 (reg, label_rtx));
++      else
++	emit_insn (gen_lcla1 (reg, label_rtx));
+ 
+-  emit_insn (gen_load_offset_label_address (gen_rtx_REG (SImode, 25), 
+-					    reg, begin_label_rtx, label_rtx));
++      emit_insn (gen_load_offset_label_address (gen_rtx_REG (SImode, 25), 
++						reg,
++						begin_label_rtx,
++						label_rtx));
++    }
+ 
+-#if !NO_DEFERRED_PROFILE_COUNTERS
+-  {
+-    rtx count_label_rtx, addr, r24;
+-    char count_label_name[16];
++  if (!NO_DEFERRED_PROFILE_COUNTERS)
++    {
++      rtx count_label_rtx, addr, r24;
++      char count_label_name[16];
+ 
+-    funcdef_nos.safe_push (label_no);
+-    ASM_GENERATE_INTERNAL_LABEL (count_label_name, "LP", label_no);
+-    count_label_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (count_label_name));
++      funcdef_nos.safe_push (label_no);
++      ASM_GENERATE_INTERNAL_LABEL (count_label_name, "LP", label_no);
++      count_label_rtx = gen_rtx_SYMBOL_REF (Pmode,
++					    ggc_strdup (count_label_name));
+ 
+-    addr = force_reg (Pmode, count_label_rtx);
+-    r24 = gen_rtx_REG (Pmode, 24);
+-    emit_move_insn (r24, addr);
++      addr = force_reg (Pmode, count_label_rtx);
++      r24 = gen_rtx_REG (Pmode, 24);
++      emit_move_insn (r24, addr);
+ 
+-    call_insn =
+-      emit_call_insn (gen_call (gen_rtx_MEM (Pmode, 
+-					     gen_rtx_SYMBOL_REF (Pmode, 
+-								 "_mcount")),
+-				GEN_INT (TARGET_64BIT ? 24 : 12)));
++      arg_bytes = GEN_INT (TARGET_64BIT ? 24 : 12);
++      if (use_mcount_pcrel_call)
++	call_insn = emit_call_insn (gen_call_mcount (mcount, arg_bytes,
++						     begin_label_rtx));
++      else
++	call_insn = emit_call_insn (gen_call (mcount, arg_bytes));
+ 
+-    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), r24);
+-  }
+-#else
++      use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), r24);
++    }
++  else
++    {
++      arg_bytes = GEN_INT (TARGET_64BIT ? 16 : 8);
++      if (use_mcount_pcrel_call)
++	call_insn = emit_call_insn (gen_call_mcount (mcount, arg_bytes,
++						     begin_label_rtx));
++      else
++	call_insn = emit_call_insn (gen_call (mcount, arg_bytes));
++    }
+ 
+-  call_insn =
+-    emit_call_insn (gen_call (gen_rtx_MEM (Pmode, 
+-					   gen_rtx_SYMBOL_REF (Pmode, 
+-							       "_mcount")),
+-			      GEN_INT (TARGET_64BIT ? 16 : 8)));
+-
+-#endif
+-
+   use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), gen_rtx_REG (SImode, 25));
+   use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), gen_rtx_REG (SImode, 26));
+ 
+@@ -4605,6 +4620,10 @@
+   /* Indicate the _mcount call cannot throw, nor will it execute a
+      non-local goto.  */
+   make_reg_eh_region_note_nothrow_nononlocal (call_insn);
++
++  /* Allocate space for fixed arguments.  */
++  if (reg_parm_stack_space > crtl->outgoing_args_size)
++    crtl->outgoing_args_size = reg_parm_stack_space;
+ }
+ 
+ /* Fetch the return address for the frame COUNT steps up from
 Index: gcc/config/visium/visium-protos.h
 ===================================================================
 --- a/src/gcc/config/visium/visium-protos.h	(.../tags/gcc_6_1_0_release)
@@ -815684,6 +831241,23 @@ Index: gcc/tree-vect-slp.c
  		    }
  		  else
  		    {
+Index: gcc/cfgrtl.c
+===================================================================
+--- a/src/gcc/cfgrtl.c	(.../tags/gcc_6_1_0_release)
++++ b/src/gcc/cfgrtl.c	(.../branches/gcc-6-branch)
+@@ -572,8 +572,10 @@
+ {
+   rtx_insn *insn;
+ 
+-  if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
+-      || !single_succ_p (bb))
++  if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
++      || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
++      || !single_succ_p (bb)
++      || (single_succ_edge (bb)->flags & EDGE_FAKE) != 0)
+     return false;
+ 
+   for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
 Index: gcc/ipa-icf.c
 ===================================================================
 --- a/src/gcc/ipa-icf.c	(.../tags/gcc_6_1_0_release)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/gcc-6.git



More information about the Reproducible-commits mailing list