diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 1c19f67cb0fc2d9b10b76fc7695a4a6641d8057a..2920ede3b5eea3de477e0ab2e6a8e2fa993edfac 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -5123,18 +5123,22 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
   if (CTAK == CTAK_Deduced &&
       !Context.hasSameType(ParamType.getNonLValueExprType(Context),
                            Arg->getType())) {
-    // C++ [temp.deduct.type]p17: (DR1770)
-    //   If P has a form that contains <i>, and if the type of i differs from
-    //   the type of the corresponding template parameter of the template named
-    //   by the enclosing simple-template-id, deduction fails.
-    //
-    // Note that CTAK will be CTAK_DeducedFromArrayBound if the form was [i]
-    // rather than <i>.
-    //
-    // FIXME: We interpret the 'i' here as referring to the expression
-    // denoting the non-type template parameter rather than the parameter
-    // itself, and so strip off references before comparing types. It's
-    // not clear how this is supposed to work for references.
+    // FIXME: If either type is dependent, we skip the check. This isn't
+    // correct, since during deduction we're supposed to have replaced each
+    // template parameter with some unique (non-dependent) placeholder.
+    // FIXME: If the argument type contains 'auto', we carry on and fail the
+    // type check in order to force specific types to be more specialized than
+    // 'auto'. It's not clear how partial ordering with 'auto' is supposed to
+    // work.
+    if ((ParamType->isDependentType() || Arg->isTypeDependent()) &&
+        !Arg->getType()->getContainedAutoType()) {
+      Converted = TemplateArgument(Arg);
+      return Arg;
+    }
+    // FIXME: This attempts to implement C++ [temp.deduct.type]p17. Per DR1770,
+    // we should actually be checking the type of the template argument in P,
+    // not the type of the template argument deduced from A, against the
+    // template parameter type.
     Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch)
       << Arg->getType()
       << ParamType.getUnqualifiedType();
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
index 518ec78e6f7d03a4cb935fa0911a04f8611e614a..00e03ef61eb07fe3a3ef526ba2fdd0e8d31f7249 100644
--- a/test/SemaTemplate/class-template-spec.cpp
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -207,19 +207,19 @@ namespace NTTPTypeVsPartialOrder {
   struct X { typedef int value_type; };
   template<typename T> struct Y { typedef T value_type; };
 
-  template<typename T, typename T::value_type N> struct A; // expected-note {{template}}
+  template<typename T, typename T::value_type N> struct A;
   template<int N> struct A<X, N> {};
-  template<typename T, T N> struct A<Y<T>, N> {}; // expected-error {{not more specialized}} expected-note {{'T' vs 'typename Y<type-parameter-0-0>::value_type'}}
+  template<typename T, T N> struct A<Y<T>, N> {};
   A<X, 0> ax;
   A<Y<int>, 0> ay;
 
 
-  template<int, typename T, typename T::value_type> struct B; // expected-note {{template}}
-  template<typename T, typename T::value_type N> struct B<0, T, N>; // expected-note {{matches}}
+  template<int, typename T, typename T::value_type> struct B;
+  template<typename T, typename T::value_type N> struct B<0, T, N>;
   template<int N> struct B<0, X, N> {};
-  template<typename T, T N> struct B<0, Y<T>, N> {}; // expected-error {{not more specialized}} expected-note {{'T' vs 'typename Y<type-parameter-0-0>::value_type'}} expected-note {{matches}}
+  template<typename T, T N> struct B<0, Y<T>, N> {};
   B<0, X, 0> bx;
-  B<0, Y<int>, 0> by; // expected-error {{ambiguous}}
+  B<0, Y<int>, 0> by;
 }
 
 namespace DefaultArgVsPartialSpec {
diff --git a/test/SemaTemplate/partial-order.cpp b/test/SemaTemplate/partial-order.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0a151de3902361ca9c7de168fe43d7cf839cc0e4
--- /dev/null
+++ b/test/SemaTemplate/partial-order.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+
+// expected-no-diagnostics
+
+namespace hana_enable_if_idiom {
+  template<bool> struct A {};
+  template<typename, typename = A<true>> struct B;
+  template<typename T, bool N> struct B<T, A<N>> {};
+  template<typename T> struct B<T, A<T::value>> {};
+  struct C {
+    static const bool value = true;
+  };
+  B<C> b;
+}
diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp
index 27a0a03f84f462c9083c972de38d90401ba30bdf..5b72b8c6549a4ac1e4f5f811d1d985ee81f3d96f 100644
--- a/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/test/SemaTemplate/temp_arg_nontype.cpp
@@ -370,13 +370,13 @@ namespace PR17696 {
 }
 
 namespace partial_order_different_types {
-  // These are unordered because the type of the final argument doesn't match.
-  template<int, int, typename T, typename, T> struct A; // expected-note {{here}}
-  template<int N, typename T, typename U, T V> struct A<0, N, T, U, V> {}; // expected-note {{matches}}
-  template<typename T, typename U, U V> struct A<0, 0, T, U, V> {}; // expected-note {{matches}}
-  // expected-error@-1 {{not more specialized than the primary}}
-  // expected-note@-2 {{deduced non-type template argument does not have the same type as the corresponding template parameter ('U' vs 'type-parameter-0-0')}}
-  A<0, 0, int, int, 0> a; // expected-error {{ambiguous partial specializations}}
+  template<int, int, typename T, typename, T> struct A;
+  template<int N, typename T, typename U, T V> struct A<0, N, T, U, V>; // expected-note {{matches}}
+  // FIXME: It appears that this partial specialization should be ill-formed as
+  // it is not more specialized than the primary template. V is not deducible
+  // because it does not have the same type as the corresponding parameter.
+  template<int N, typename T, typename U, U V> struct A<0, N, T, U, V> {}; // expected-note {{matches}}
+  A<0, 0, int, int, 0> a; // expected-error {{ambiguous}}
 }
 
 namespace partial_order_references {
@@ -434,7 +434,7 @@ namespace dependent_nested_partial_specialization {
 
   template<typename T> struct E {
     template<typename U, U V> struct F; // expected-note {{template}}
-    template<typename W, T V> struct F<W, V> {}; // expected-error {{not more specialized than the primary}} expected-note {{does not have the same type}}
+    template<typename W, T V> struct F<W, V> {}; // expected-error {{not more specialized than the primary}}
   };
   E<int>::F<int, 0> e1; // expected-note {{instantiation of}}
 }
diff --git a/test/SemaTemplate/temp_arg_template_cxx1z.cpp b/test/SemaTemplate/temp_arg_template_cxx1z.cpp
index aa517c32859937e2bec2e267ce06f562f7b6314c..703935dcd5c19bfa76e6634a02fa379b11c19462 100644
--- a/test/SemaTemplate/temp_arg_template_cxx1z.cpp
+++ b/test/SemaTemplate/temp_arg_template_cxx1z.cpp
@@ -79,13 +79,13 @@ namespace Auto {
 
   TInt<Auto> ia;
   TInt<AutoPtr> iap; // expected-error {{different template parameters}}
-  TInt<DecltypeAuto> ida; // FIXME expected-error {{different template parameters}}
+  TInt<DecltypeAuto> ida;
   TInt<Int> ii;
   TInt<IntPtr> iip; // expected-error {{different template parameters}}
 
   TIntPtr<Auto> ipa;
   TIntPtr<AutoPtr> ipap;
-  TIntPtr<DecltypeAuto> ipda; // FIXME expected-error {{different template parameters}}
+  TIntPtr<DecltypeAuto> ipda;
   TIntPtr<Int> ipi; // expected-error {{different template parameters}}
   TIntPtr<IntPtr> ipip;
 
@@ -114,6 +114,6 @@ namespace Auto {
 
   int n;
   template<auto A, decltype(A) B = &n> struct SubstFailure;
-  TInt<SubstFailure> isf; // expected-error {{different template parameters}}
-  TIntPtr<SubstFailure> ipsf; // expected-error {{different template parameters}}
+  TInt<SubstFailure> isf; // FIXME: this should be ill-formed
+  TIntPtr<SubstFailure> ipsf;
 }