[c++20] Implement P1185R2 (as modified by P2002R0).

For each defaulted operator<=> in a class that doesn't explicitly
declare any operator==, also inject a matching implicit defaulted
operator==.
diff --git a/clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp b/clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
index e3c1535..e6be640 100644
--- a/clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
+++ b/clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
@@ -1,6 +1,41 @@
-// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=ITANIUM
-// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple x86_64-pc-win32 2>&1 | FileCheck %s --check-prefix=MSABI
-// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple -DBUILTIN 2>&1 | FileCheck %s --check-prefix=BUILTIN
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s --check-prefixes=CHECK,ITANIUM
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple x86_64-pc-win32 2>&1 | FileCheck %s --check-prefixes=CHECK,MSABI
+
+namespace std {
+  struct strong_ordering {
+    int n;
+    constexpr operator int() const { return n; }
+    static const strong_ordering less, equal, greater;
+  };
+  constexpr strong_ordering strong_ordering::less = {-1};
+  constexpr strong_ordering strong_ordering::equal = {0};
+  constexpr strong_ordering strong_ordering::greater = {1};
+}
+
+struct Primary {
+  virtual void f();
+  std::strong_ordering operator<=>(const Primary&) const = default;
+};
+struct X {
+  virtual struct Y &operator=(Y&&);
+  virtual struct Y &operator=(const Y&);
+  std::strong_ordering operator<=>(const X&) const = default;
+};
+// The vtable for Y should contain the following entries in order:
+//  - Primary::f
+//  - Y::operator<=>
+//  - Y::operator=(const Y&) (implicit)
+//  - Y::operator=(Y&&) (implicit)
+//  - Y::operator==(const Y&) const (implicit)
+// See:
+//   https://github.com/itanium-cxx-abi/cxx-abi/issues/83 for assignment operator
+//   https://github.com/itanium-cxx-abi/cxx-abi/issues/88 for equality comparison
+// FIXME: What rule does MSVC use?
+struct Y : Primary, X {
+  virtual std::strong_ordering operator<=>(const Y&) const = default;
+};
+Y y;
+// ITANIUM: @_ZTV1Y = {{.*}}constant {{.*}} null, {{.*}} @_ZTI1Y {{.*}} @_ZN7Primary1fEv {{.*}} @_ZNK1YssERKS_ {{.*}} @_ZN1YaSERKS_ {{.*}} @_ZN1YaSEOS_ {{.*}} @_ZNK1YeqERKS_ {{.*}} -{{4|8}} {{.*}} @_ZTI1Y {{.*}} @_ZThn8_N1YaSERKS_
 
 struct A {
   void operator<=>(int);
@@ -26,8 +61,11 @@
   return a <=> a;
 }
 
-#ifdef BUILTIN
-void builtin(int a) {
-  a <=> a; // BUILTIN: cannot compile this scalar expression yet
+// CHECK-LABEL: define {{.*}}builtin_cmp
+void builtin_cmp(int a) {
+  // CHECK: icmp slt
+  // CHECK: select
+  // CHECK: icmp eq
+  // CHECK: select
+  a <=> a;
 }
-#endif